libavcodec/snow.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
00003  *
00004  * This file is part of Libav.
00005  *
00006  * Libav is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * Libav is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with Libav; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 
00021 #include "libavutil/intmath.h"
00022 #include "libavutil/log.h"
00023 #include "libavutil/opt.h"
00024 #include "avcodec.h"
00025 #include "dsputil.h"
00026 #include "dwt.h"
00027 #include "snow.h"
00028 #include "snowdata.h"
00029 
00030 #include "rangecoder.h"
00031 #include "mathops.h"
00032 #include "h263.h"
00033 
00034 #undef NDEBUG
00035 #include <assert.h>
00036 
00037 
00038 void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h,
00039                               int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8){
00040     int y, x;
00041     IDWTELEM * dst;
00042     for(y=0; y<b_h; y++){
00043         //FIXME ugly misuse of obmc_stride
00044         const uint8_t *obmc1= obmc + y*obmc_stride;
00045         const uint8_t *obmc2= obmc1+ (obmc_stride>>1);
00046         const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1);
00047         const uint8_t *obmc4= obmc3+ (obmc_stride>>1);
00048         dst = slice_buffer_get_line(sb, src_y + y);
00049         for(x=0; x<b_w; x++){
00050             int v=   obmc1[x] * block[3][x + y*src_stride]
00051                     +obmc2[x] * block[2][x + y*src_stride]
00052                     +obmc3[x] * block[1][x + y*src_stride]
00053                     +obmc4[x] * block[0][x + y*src_stride];
00054 
00055             v <<= 8 - LOG2_OBMC_MAX;
00056             if(FRAC_BITS != 8){
00057                 v >>= 8 - FRAC_BITS;
00058             }
00059             if(add){
00060                 v += dst[x + src_x];
00061                 v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS;
00062                 if(v&(~255)) v= ~(v>>31);
00063                 dst8[x + y*src_stride] = v;
00064             }else{
00065                 dst[x + src_x] -= v;
00066             }
00067         }
00068     }
00069 }
00070 
00071 void ff_snow_reset_contexts(SnowContext *s){ //FIXME better initial contexts
00072     int plane_index, level, orientation;
00073 
00074     for(plane_index=0; plane_index<3; plane_index++){
00075         for(level=0; level<MAX_DECOMPOSITIONS; level++){
00076             for(orientation=level ? 1:0; orientation<4; orientation++){
00077                 memset(s->plane[plane_index].band[level][orientation].state, MID_STATE, sizeof(s->plane[plane_index].band[level][orientation].state));
00078             }
00079         }
00080     }
00081     memset(s->header_state, MID_STATE, sizeof(s->header_state));
00082     memset(s->block_state, MID_STATE, sizeof(s->block_state));
00083 }
00084 
00085 int ff_snow_alloc_blocks(SnowContext *s){
00086     int w= -((-s->avctx->width )>>LOG2_MB_SIZE);
00087     int h= -((-s->avctx->height)>>LOG2_MB_SIZE);
00088 
00089     s->b_width = w;
00090     s->b_height= h;
00091 
00092     av_free(s->block);
00093     s->block= av_mallocz(w * h * sizeof(BlockNode) << (s->block_max_depth*2));
00094     return 0;
00095 }
00096 
00097 static void init_qexp(void){
00098     int i;
00099     double v=128;
00100 
00101     for(i=0; i<QROOT; i++){
00102         qexp[i]= lrintf(v);
00103         v *= pow(2, 1.0 / QROOT);
00104     }
00105 }
00106 static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int b_w, int b_h, int dx, int dy){
00107     static const uint8_t weight[64]={
00108     8,7,6,5,4,3,2,1,
00109     7,7,0,0,0,0,0,1,
00110     6,0,6,0,0,0,2,0,
00111     5,0,0,5,0,3,0,0,
00112     4,0,0,0,4,0,0,0,
00113     3,0,0,5,0,3,0,0,
00114     2,0,6,0,0,0,2,0,
00115     1,7,0,0,0,0,0,1,
00116     };
00117 
00118     static const uint8_t brane[256]={
00119     0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x11,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
00120     0x04,0x05,0xcc,0xcc,0xcc,0xcc,0xcc,0x41,0x15,0x16,0xcc,0xcc,0xcc,0xcc,0xcc,0x52,
00121     0x04,0xcc,0x05,0xcc,0xcc,0xcc,0x41,0xcc,0x15,0xcc,0x16,0xcc,0xcc,0xcc,0x52,0xcc,
00122     0x04,0xcc,0xcc,0x05,0xcc,0x41,0xcc,0xcc,0x15,0xcc,0xcc,0x16,0xcc,0x52,0xcc,0xcc,
00123     0x04,0xcc,0xcc,0xcc,0x41,0xcc,0xcc,0xcc,0x15,0xcc,0xcc,0xcc,0x16,0xcc,0xcc,0xcc,
00124     0x04,0xcc,0xcc,0x41,0xcc,0x05,0xcc,0xcc,0x15,0xcc,0xcc,0x52,0xcc,0x16,0xcc,0xcc,
00125     0x04,0xcc,0x41,0xcc,0xcc,0xcc,0x05,0xcc,0x15,0xcc,0x52,0xcc,0xcc,0xcc,0x16,0xcc,
00126     0x04,0x41,0xcc,0xcc,0xcc,0xcc,0xcc,0x05,0x15,0x52,0xcc,0xcc,0xcc,0xcc,0xcc,0x16,
00127     0x44,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x55,0x56,0x56,0x56,0x56,0x56,0x56,0x56,
00128     0x48,0x49,0xcc,0xcc,0xcc,0xcc,0xcc,0x85,0x59,0x5A,0xcc,0xcc,0xcc,0xcc,0xcc,0x96,
00129     0x48,0xcc,0x49,0xcc,0xcc,0xcc,0x85,0xcc,0x59,0xcc,0x5A,0xcc,0xcc,0xcc,0x96,0xcc,
00130     0x48,0xcc,0xcc,0x49,0xcc,0x85,0xcc,0xcc,0x59,0xcc,0xcc,0x5A,0xcc,0x96,0xcc,0xcc,
00131     0x48,0xcc,0xcc,0xcc,0x49,0xcc,0xcc,0xcc,0x59,0xcc,0xcc,0xcc,0x96,0xcc,0xcc,0xcc,
00132     0x48,0xcc,0xcc,0x85,0xcc,0x49,0xcc,0xcc,0x59,0xcc,0xcc,0x96,0xcc,0x5A,0xcc,0xcc,
00133     0x48,0xcc,0x85,0xcc,0xcc,0xcc,0x49,0xcc,0x59,0xcc,0x96,0xcc,0xcc,0xcc,0x5A,0xcc,
00134     0x48,0x85,0xcc,0xcc,0xcc,0xcc,0xcc,0x49,0x59,0x96,0xcc,0xcc,0xcc,0xcc,0xcc,0x5A,
00135     };
00136 
00137     static const uint8_t needs[16]={
00138     0,1,0,0,
00139     2,4,2,0,
00140     0,1,0,0,
00141     15
00142     };
00143 
00144     int x, y, b, r, l;
00145     int16_t tmpIt   [64*(32+HTAPS_MAX)];
00146     uint8_t tmp2t[3][stride*(32+HTAPS_MAX)];
00147     int16_t *tmpI= tmpIt;
00148     uint8_t *tmp2= tmp2t[0];
00149     const uint8_t *hpel[11];
00150     assert(dx<16 && dy<16);
00151     r= brane[dx + 16*dy]&15;
00152     l= brane[dx + 16*dy]>>4;
00153 
00154     b= needs[l] | needs[r];
00155     if(p && !p->diag_mc)
00156         b= 15;
00157 
00158     if(b&5){
00159         for(y=0; y < b_h+HTAPS_MAX-1; y++){
00160             for(x=0; x < b_w; x++){
00161                 int a_1=src[x + HTAPS_MAX/2-4];
00162                 int a0= src[x + HTAPS_MAX/2-3];
00163                 int a1= src[x + HTAPS_MAX/2-2];
00164                 int a2= src[x + HTAPS_MAX/2-1];
00165                 int a3= src[x + HTAPS_MAX/2+0];
00166                 int a4= src[x + HTAPS_MAX/2+1];
00167                 int a5= src[x + HTAPS_MAX/2+2];
00168                 int a6= src[x + HTAPS_MAX/2+3];
00169                 int am=0;
00170                 if(!p || p->fast_mc){
00171                     am= 20*(a2+a3) - 5*(a1+a4) + (a0+a5);
00172                     tmpI[x]= am;
00173                     am= (am+16)>>5;
00174                 }else{
00175                     am= p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6);
00176                     tmpI[x]= am;
00177                     am= (am+32)>>6;
00178                 }
00179 
00180                 if(am&(~255)) am= ~(am>>31);
00181                 tmp2[x]= am;
00182             }
00183             tmpI+= 64;
00184             tmp2+= stride;
00185             src += stride;
00186         }
00187         src -= stride*y;
00188     }
00189     src += HTAPS_MAX/2 - 1;
00190     tmp2= tmp2t[1];
00191 
00192     if(b&2){
00193         for(y=0; y < b_h; y++){
00194             for(x=0; x < b_w+1; x++){
00195                 int a_1=src[x + (HTAPS_MAX/2-4)*stride];
00196                 int a0= src[x + (HTAPS_MAX/2-3)*stride];
00197                 int a1= src[x + (HTAPS_MAX/2-2)*stride];
00198                 int a2= src[x + (HTAPS_MAX/2-1)*stride];
00199                 int a3= src[x + (HTAPS_MAX/2+0)*stride];
00200                 int a4= src[x + (HTAPS_MAX/2+1)*stride];
00201                 int a5= src[x + (HTAPS_MAX/2+2)*stride];
00202                 int a6= src[x + (HTAPS_MAX/2+3)*stride];
00203                 int am=0;
00204                 if(!p || p->fast_mc)
00205                     am= (20*(a2+a3) - 5*(a1+a4) + (a0+a5) + 16)>>5;
00206                 else
00207                     am= (p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6) + 32)>>6;
00208 
00209                 if(am&(~255)) am= ~(am>>31);
00210                 tmp2[x]= am;
00211             }
00212             src += stride;
00213             tmp2+= stride;
00214         }
00215         src -= stride*y;
00216     }
00217     src += stride*(HTAPS_MAX/2 - 1);
00218     tmp2= tmp2t[2];
00219     tmpI= tmpIt;
00220     if(b&4){
00221         for(y=0; y < b_h; y++){
00222             for(x=0; x < b_w; x++){
00223                 int a_1=tmpI[x + (HTAPS_MAX/2-4)*64];
00224                 int a0= tmpI[x + (HTAPS_MAX/2-3)*64];
00225                 int a1= tmpI[x + (HTAPS_MAX/2-2)*64];
00226                 int a2= tmpI[x + (HTAPS_MAX/2-1)*64];
00227                 int a3= tmpI[x + (HTAPS_MAX/2+0)*64];
00228                 int a4= tmpI[x + (HTAPS_MAX/2+1)*64];
00229                 int a5= tmpI[x + (HTAPS_MAX/2+2)*64];
00230                 int a6= tmpI[x + (HTAPS_MAX/2+3)*64];
00231                 int am=0;
00232                 if(!p || p->fast_mc)
00233                     am= (20*(a2+a3) - 5*(a1+a4) + (a0+a5) + 512)>>10;
00234                 else
00235                     am= (p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6) + 2048)>>12;
00236                 if(am&(~255)) am= ~(am>>31);
00237                 tmp2[x]= am;
00238             }
00239             tmpI+= 64;
00240             tmp2+= stride;
00241         }
00242     }
00243 
00244     hpel[ 0]= src;
00245     hpel[ 1]= tmp2t[0] + stride*(HTAPS_MAX/2-1);
00246     hpel[ 2]= src + 1;
00247 
00248     hpel[ 4]= tmp2t[1];
00249     hpel[ 5]= tmp2t[2];
00250     hpel[ 6]= tmp2t[1] + 1;
00251 
00252     hpel[ 8]= src + stride;
00253     hpel[ 9]= hpel[1] + stride;
00254     hpel[10]= hpel[8] + 1;
00255 
00256     if(b==15){
00257         const uint8_t *src1= hpel[dx/8 + dy/8*4  ];
00258         const uint8_t *src2= hpel[dx/8 + dy/8*4+1];
00259         const uint8_t *src3= hpel[dx/8 + dy/8*4+4];
00260         const uint8_t *src4= hpel[dx/8 + dy/8*4+5];
00261         dx&=7;
00262         dy&=7;
00263         for(y=0; y < b_h; y++){
00264             for(x=0; x < b_w; x++){
00265                 dst[x]= ((8-dx)*(8-dy)*src1[x] + dx*(8-dy)*src2[x]+
00266                          (8-dx)*   dy *src3[x] + dx*   dy *src4[x]+32)>>6;
00267             }
00268             src1+=stride;
00269             src2+=stride;
00270             src3+=stride;
00271             src4+=stride;
00272             dst +=stride;
00273         }
00274     }else{
00275         const uint8_t *src1= hpel[l];
00276         const uint8_t *src2= hpel[r];
00277         int a= weight[((dx&7) + (8*(dy&7)))];
00278         int b= 8-a;
00279         for(y=0; y < b_h; y++){
00280             for(x=0; x < b_w; x++){
00281                 dst[x]= (a*src1[x] + b*src2[x] + 4)>>3;
00282             }
00283             src1+=stride;
00284             src2+=stride;
00285             dst +=stride;
00286         }
00287     }
00288 }
00289 
00290 void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h){
00291     if(block->type & BLOCK_INTRA){
00292         int x, y;
00293         const unsigned color  = block->color[plane_index];
00294         const unsigned color4 = color*0x01010101;
00295         if(b_w==32){
00296             for(y=0; y < b_h; y++){
00297                 *(uint32_t*)&dst[0 + y*stride]= color4;
00298                 *(uint32_t*)&dst[4 + y*stride]= color4;
00299                 *(uint32_t*)&dst[8 + y*stride]= color4;
00300                 *(uint32_t*)&dst[12+ y*stride]= color4;
00301                 *(uint32_t*)&dst[16+ y*stride]= color4;
00302                 *(uint32_t*)&dst[20+ y*stride]= color4;
00303                 *(uint32_t*)&dst[24+ y*stride]= color4;
00304                 *(uint32_t*)&dst[28+ y*stride]= color4;
00305             }
00306         }else if(b_w==16){
00307             for(y=0; y < b_h; y++){
00308                 *(uint32_t*)&dst[0 + y*stride]= color4;
00309                 *(uint32_t*)&dst[4 + y*stride]= color4;
00310                 *(uint32_t*)&dst[8 + y*stride]= color4;
00311                 *(uint32_t*)&dst[12+ y*stride]= color4;
00312             }
00313         }else if(b_w==8){
00314             for(y=0; y < b_h; y++){
00315                 *(uint32_t*)&dst[0 + y*stride]= color4;
00316                 *(uint32_t*)&dst[4 + y*stride]= color4;
00317             }
00318         }else if(b_w==4){
00319             for(y=0; y < b_h; y++){
00320                 *(uint32_t*)&dst[0 + y*stride]= color4;
00321             }
00322         }else{
00323             for(y=0; y < b_h; y++){
00324                 for(x=0; x < b_w; x++){
00325                     dst[x + y*stride]= color;
00326                 }
00327             }
00328         }
00329     }else{
00330         uint8_t *src= s->last_picture[block->ref].data[plane_index];
00331         const int scale= plane_index ?  s->mv_scale : 2*s->mv_scale;
00332         int mx= block->mx*scale;
00333         int my= block->my*scale;
00334         const int dx= mx&15;
00335         const int dy= my&15;
00336         const int tab_index= 3 - (b_w>>2) + (b_w>>4);
00337         sx += (mx>>4) - (HTAPS_MAX/2-1);
00338         sy += (my>>4) - (HTAPS_MAX/2-1);
00339         src += sx + sy*stride;
00340         if(   (unsigned)sx >= w - b_w - (HTAPS_MAX-2)
00341            || (unsigned)sy >= h - b_h - (HTAPS_MAX-2)){
00342             s->dsp.emulated_edge_mc(tmp + MB_SIZE, src, stride, b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, sx, sy, w, h);
00343             src= tmp + MB_SIZE;
00344         }
00345 //        assert(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h);
00346 //        assert(!(b_w&(b_w-1)));
00347         assert(b_w>1 && b_h>1);
00348         assert((tab_index>=0 && tab_index<4) || b_w==32);
00349         if((dx&3) || (dy&3) || !(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h) || (b_w&(b_w-1)) || !s->plane[plane_index].fast_mc )
00350             mc_block(&s->plane[plane_index], dst, src, stride, b_w, b_h, dx, dy);
00351         else if(b_w==32){
00352             int y;
00353             for(y=0; y<b_h; y+=16){
00354                 s->dsp.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + y*stride, src + 3 + (y+3)*stride,stride);
00355                 s->dsp.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + 16 + y*stride, src + 19 + (y+3)*stride,stride);
00356             }
00357         }else if(b_w==b_h)
00358             s->dsp.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst,src + 3 + 3*stride,stride);
00359         else if(b_w==2*b_h){
00360             s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst    ,src + 3       + 3*stride,stride);
00361             s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst+b_h,src + 3 + b_h + 3*stride,stride);
00362         }else{
00363             assert(2*b_w==b_h);
00364             s->dsp.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst           ,src + 3 + 3*stride           ,stride);
00365             s->dsp.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst+b_w*stride,src + 3 + 3*stride+b_w*stride,stride);
00366         }
00367     }
00368 }
00369 
00370 #define mca(dx,dy,b_w)\
00371 static void mc_block_hpel ## dx ## dy ## b_w(uint8_t *dst, const uint8_t *src, int stride, int h){\
00372     assert(h==b_w);\
00373     mc_block(NULL, dst, src-(HTAPS_MAX/2-1)-(HTAPS_MAX/2-1)*stride, stride, b_w, b_w, dx, dy);\
00374 }
00375 
00376 mca( 0, 0,16)
00377 mca( 8, 0,16)
00378 mca( 0, 8,16)
00379 mca( 8, 8,16)
00380 mca( 0, 0,8)
00381 mca( 8, 0,8)
00382 mca( 0, 8,8)
00383 mca( 8, 8,8)
00384 
00385 av_cold int ff_snow_common_init(AVCodecContext *avctx){
00386     SnowContext *s = avctx->priv_data;
00387     int width, height;
00388     int i, j;
00389 
00390     s->avctx= avctx;
00391     s->max_ref_frames=1; //just make sure its not an invalid value in case of no initial keyframe
00392 
00393     dsputil_init(&s->dsp, avctx);
00394     ff_dwt_init(&s->dwt);
00395 
00396 #define mcf(dx,dy)\
00397     s->dsp.put_qpel_pixels_tab       [0][dy+dx/4]=\
00398     s->dsp.put_no_rnd_qpel_pixels_tab[0][dy+dx/4]=\
00399         s->dsp.put_h264_qpel_pixels_tab[0][dy+dx/4];\
00400     s->dsp.put_qpel_pixels_tab       [1][dy+dx/4]=\
00401     s->dsp.put_no_rnd_qpel_pixels_tab[1][dy+dx/4]=\
00402         s->dsp.put_h264_qpel_pixels_tab[1][dy+dx/4];
00403 
00404     mcf( 0, 0)
00405     mcf( 4, 0)
00406     mcf( 8, 0)
00407     mcf(12, 0)
00408     mcf( 0, 4)
00409     mcf( 4, 4)
00410     mcf( 8, 4)
00411     mcf(12, 4)
00412     mcf( 0, 8)
00413     mcf( 4, 8)
00414     mcf( 8, 8)
00415     mcf(12, 8)
00416     mcf( 0,12)
00417     mcf( 4,12)
00418     mcf( 8,12)
00419     mcf(12,12)
00420 
00421 #define mcfh(dx,dy)\
00422     s->dsp.put_pixels_tab       [0][dy/4+dx/8]=\
00423     s->dsp.put_no_rnd_pixels_tab[0][dy/4+dx/8]=\
00424         mc_block_hpel ## dx ## dy ## 16;\
00425     s->dsp.put_pixels_tab       [1][dy/4+dx/8]=\
00426     s->dsp.put_no_rnd_pixels_tab[1][dy/4+dx/8]=\
00427         mc_block_hpel ## dx ## dy ## 8;
00428 
00429     mcfh(0, 0)
00430     mcfh(8, 0)
00431     mcfh(0, 8)
00432     mcfh(8, 8)
00433 
00434     init_qexp();
00435 
00436 //    dec += FFMAX(s->chroma_h_shift, s->chroma_v_shift);
00437 
00438     width= s->avctx->width;
00439     height= s->avctx->height;
00440 
00441     s->spatial_idwt_buffer= av_mallocz(width*height*sizeof(IDWTELEM));
00442     s->spatial_dwt_buffer= av_mallocz(width*height*sizeof(DWTELEM)); //FIXME this does not belong here
00443 
00444     for(i=0; i<MAX_REF_FRAMES; i++)
00445         for(j=0; j<MAX_REF_FRAMES; j++)
00446             scale_mv_ref[i][j] = 256*(i+1)/(j+1);
00447 
00448     s->avctx->get_buffer(s->avctx, &s->mconly_picture);
00449     s->scratchbuf = av_malloc(s->mconly_picture.linesize[0]*7*MB_SIZE);
00450 
00451     return 0;
00452 }
00453 
00454 int ff_snow_common_init_after_header(AVCodecContext *avctx) {
00455     SnowContext *s = avctx->priv_data;
00456     int plane_index, level, orientation;
00457 
00458     for(plane_index=0; plane_index<3; plane_index++){
00459         int w= s->avctx->width;
00460         int h= s->avctx->height;
00461 
00462         if(plane_index){
00463             w>>= s->chroma_h_shift;
00464             h>>= s->chroma_v_shift;
00465         }
00466         s->plane[plane_index].width = w;
00467         s->plane[plane_index].height= h;
00468 
00469         for(level=s->spatial_decomposition_count-1; level>=0; level--){
00470             for(orientation=level ? 1 : 0; orientation<4; orientation++){
00471                 SubBand *b= &s->plane[plane_index].band[level][orientation];
00472 
00473                 b->buf= s->spatial_dwt_buffer;
00474                 b->level= level;
00475                 b->stride= s->plane[plane_index].width << (s->spatial_decomposition_count - level);
00476                 b->width = (w + !(orientation&1))>>1;
00477                 b->height= (h + !(orientation>1))>>1;
00478 
00479                 b->stride_line = 1 << (s->spatial_decomposition_count - level);
00480                 b->buf_x_offset = 0;
00481                 b->buf_y_offset = 0;
00482 
00483                 if(orientation&1){
00484                     b->buf += (w+1)>>1;
00485                     b->buf_x_offset = (w+1)>>1;
00486                 }
00487                 if(orientation>1){
00488                     b->buf += b->stride>>1;
00489                     b->buf_y_offset = b->stride_line >> 1;
00490                 }
00491                 b->ibuf= s->spatial_idwt_buffer + (b->buf - s->spatial_dwt_buffer);
00492 
00493                 if(level)
00494                     b->parent= &s->plane[plane_index].band[level-1][orientation];
00495                 //FIXME avoid this realloc
00496                 av_freep(&b->x_coeff);
00497                 b->x_coeff=av_mallocz(((b->width+1) * b->height+1)*sizeof(x_and_coeff));
00498             }
00499             w= (w+1)>>1;
00500             h= (h+1)>>1;
00501         }
00502     }
00503 
00504     return 0;
00505 }
00506 
00507 #define USE_HALFPEL_PLANE 0
00508 
00509 static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *frame){
00510     int p,x,y;
00511 
00512     for(p=0; p<3; p++){
00513         int is_chroma= !!p;
00514         int w= s->avctx->width  >>is_chroma;
00515         int h= s->avctx->height >>is_chroma;
00516         int ls= frame->linesize[p];
00517         uint8_t *src= frame->data[p];
00518 
00519         halfpel[1][p] = (uint8_t*) av_malloc(ls * (h + 2 * EDGE_WIDTH)) + EDGE_WIDTH * (1 + ls);
00520         halfpel[2][p] = (uint8_t*) av_malloc(ls * (h + 2 * EDGE_WIDTH)) + EDGE_WIDTH * (1 + ls);
00521         halfpel[3][p] = (uint8_t*) av_malloc(ls * (h + 2 * EDGE_WIDTH)) + EDGE_WIDTH * (1 + ls);
00522 
00523         halfpel[0][p]= src;
00524         for(y=0; y<h; y++){
00525             for(x=0; x<w; x++){
00526                 int i= y*ls + x;
00527 
00528                 halfpel[1][p][i]= (20*(src[i] + src[i+1]) - 5*(src[i-1] + src[i+2]) + (src[i-2] + src[i+3]) + 16 )>>5;
00529             }
00530         }
00531         for(y=0; y<h; y++){
00532             for(x=0; x<w; x++){
00533                 int i= y*ls + x;
00534 
00535                 halfpel[2][p][i]= (20*(src[i] + src[i+ls]) - 5*(src[i-ls] + src[i+2*ls]) + (src[i-2*ls] + src[i+3*ls]) + 16 )>>5;
00536             }
00537         }
00538         src= halfpel[1][p];
00539         for(y=0; y<h; y++){
00540             for(x=0; x<w; x++){
00541                 int i= y*ls + x;
00542 
00543                 halfpel[3][p][i]= (20*(src[i] + src[i+ls]) - 5*(src[i-ls] + src[i+2*ls]) + (src[i-2*ls] + src[i+3*ls]) + 16 )>>5;
00544             }
00545         }
00546 
00547 //FIXME border!
00548     }
00549 }
00550 
00551 void ff_snow_release_buffer(AVCodecContext *avctx)
00552 {
00553     SnowContext *s = avctx->priv_data;
00554     int i;
00555 
00556     if(s->last_picture[s->max_ref_frames-1].data[0]){
00557         avctx->release_buffer(avctx, &s->last_picture[s->max_ref_frames-1]);
00558         for(i=0; i<9; i++)
00559             if(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3])
00560                 av_free(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] - EDGE_WIDTH*(1+s->current_picture.linesize[i%3]));
00561     }
00562 }
00563 
00564 int ff_snow_frame_start(SnowContext *s){
00565    AVFrame tmp;
00566    int w= s->avctx->width; //FIXME round up to x16 ?
00567    int h= s->avctx->height;
00568 
00569     if (s->current_picture.data[0] && !(s->avctx->flags&CODEC_FLAG_EMU_EDGE)) {
00570         s->dsp.draw_edges(s->current_picture.data[0],
00571                           s->current_picture.linesize[0], w   , h   ,
00572                           EDGE_WIDTH  , EDGE_WIDTH  , EDGE_TOP | EDGE_BOTTOM);
00573         s->dsp.draw_edges(s->current_picture.data[1],
00574                           s->current_picture.linesize[1], w>>1, h>>1,
00575                           EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM);
00576         s->dsp.draw_edges(s->current_picture.data[2],
00577                           s->current_picture.linesize[2], w>>1, h>>1,
00578                           EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM);
00579     }
00580 
00581     ff_snow_release_buffer(s->avctx);
00582 
00583     tmp= s->last_picture[s->max_ref_frames-1];
00584     memmove(s->last_picture+1, s->last_picture, (s->max_ref_frames-1)*sizeof(AVFrame));
00585     memmove(s->halfpel_plane+1, s->halfpel_plane, (s->max_ref_frames-1)*sizeof(void*)*4*4);
00586     if(USE_HALFPEL_PLANE && s->current_picture.data[0])
00587         halfpel_interpol(s, s->halfpel_plane[0], &s->current_picture);
00588     s->last_picture[0]= s->current_picture;
00589     s->current_picture= tmp;
00590 
00591     if(s->keyframe){
00592         s->ref_frames= 0;
00593     }else{
00594         int i;
00595         for(i=0; i<s->max_ref_frames && s->last_picture[i].data[0]; i++)
00596             if(i && s->last_picture[i-1].key_frame)
00597                 break;
00598         s->ref_frames= i;
00599         if(s->ref_frames==0){
00600             av_log(s->avctx,AV_LOG_ERROR, "No reference frames\n");
00601             return -1;
00602         }
00603     }
00604 
00605     s->current_picture.reference= 1;
00606     if(s->avctx->get_buffer(s->avctx, &s->current_picture) < 0){
00607         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00608         return -1;
00609     }
00610 
00611     s->current_picture.key_frame= s->keyframe;
00612 
00613     return 0;
00614 }
00615 
00616 av_cold void ff_snow_common_end(SnowContext *s)
00617 {
00618     int plane_index, level, orientation, i;
00619 
00620     av_freep(&s->spatial_dwt_buffer);
00621     av_freep(&s->spatial_idwt_buffer);
00622 
00623     s->m.me.temp= NULL;
00624     av_freep(&s->m.me.scratchpad);
00625     av_freep(&s->m.me.map);
00626     av_freep(&s->m.me.score_map);
00627     av_freep(&s->m.obmc_scratchpad);
00628 
00629     av_freep(&s->block);
00630     av_freep(&s->scratchbuf);
00631 
00632     for(i=0; i<MAX_REF_FRAMES; i++){
00633         av_freep(&s->ref_mvs[i]);
00634         av_freep(&s->ref_scores[i]);
00635         if(s->last_picture[i].data[0])
00636             s->avctx->release_buffer(s->avctx, &s->last_picture[i]);
00637     }
00638 
00639     for(plane_index=0; plane_index<3; plane_index++){
00640         for(level=s->spatial_decomposition_count-1; level>=0; level--){
00641             for(orientation=level ? 1 : 0; orientation<4; orientation++){
00642                 SubBand *b= &s->plane[plane_index].band[level][orientation];
00643 
00644                 av_freep(&b->x_coeff);
00645             }
00646         }
00647     }
00648     if (s->mconly_picture.data[0])
00649         s->avctx->release_buffer(s->avctx, &s->mconly_picture);
00650     if (s->current_picture.data[0])
00651         s->avctx->release_buffer(s->avctx, &s->current_picture);
00652 }
00653