• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

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 FFmpeg.
00005  *
00006  * FFmpeg 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  * FFmpeg 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 FFmpeg; 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, ret;
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     FF_ALLOCZ_OR_GOTO(avctx, s->spatial_idwt_buffer, width * height * sizeof(IDWTELEM), fail);
00442     FF_ALLOCZ_OR_GOTO(avctx, s->spatial_dwt_buffer,  width * height * sizeof(DWTELEM),  fail); //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     if ((ret = s->avctx->get_buffer(s->avctx, &s->mconly_picture)) < 0) {
00449         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00450         return ret;
00451     }
00452     FF_ALLOC_OR_GOTO(avctx, s->scratchbuf, s->mconly_picture.linesize[0]*7*MB_SIZE, fail);
00453 
00454     return 0;
00455 fail:
00456     return AVERROR(ENOMEM);
00457 }
00458 
00459 int ff_snow_common_init_after_header(AVCodecContext *avctx) {
00460     SnowContext *s = avctx->priv_data;
00461     int plane_index, level, orientation;
00462 
00463     for(plane_index=0; plane_index<3; plane_index++){
00464         int w= s->avctx->width;
00465         int h= s->avctx->height;
00466 
00467         if(plane_index){
00468             w>>= s->chroma_h_shift;
00469             h>>= s->chroma_v_shift;
00470         }
00471         s->plane[plane_index].width = w;
00472         s->plane[plane_index].height= h;
00473 
00474         for(level=s->spatial_decomposition_count-1; level>=0; level--){
00475             for(orientation=level ? 1 : 0; orientation<4; orientation++){
00476                 SubBand *b= &s->plane[plane_index].band[level][orientation];
00477 
00478                 b->buf= s->spatial_dwt_buffer;
00479                 b->level= level;
00480                 b->stride= s->plane[plane_index].width << (s->spatial_decomposition_count - level);
00481                 b->width = (w + !(orientation&1))>>1;
00482                 b->height= (h + !(orientation>1))>>1;
00483 
00484                 b->stride_line = 1 << (s->spatial_decomposition_count - level);
00485                 b->buf_x_offset = 0;
00486                 b->buf_y_offset = 0;
00487 
00488                 if(orientation&1){
00489                     b->buf += (w+1)>>1;
00490                     b->buf_x_offset = (w+1)>>1;
00491                 }
00492                 if(orientation>1){
00493                     b->buf += b->stride>>1;
00494                     b->buf_y_offset = b->stride_line >> 1;
00495                 }
00496                 b->ibuf= s->spatial_idwt_buffer + (b->buf - s->spatial_dwt_buffer);
00497 
00498                 if(level)
00499                     b->parent= &s->plane[plane_index].band[level-1][orientation];
00500                 //FIXME avoid this realloc
00501                 av_freep(&b->x_coeff);
00502                 b->x_coeff=av_mallocz(((b->width+1) * b->height+1)*sizeof(x_and_coeff));
00503             }
00504             w= (w+1)>>1;
00505             h= (h+1)>>1;
00506         }
00507     }
00508 
00509     return 0;
00510 }
00511 
00512 #define USE_HALFPEL_PLANE 0
00513 
00514 static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *frame){
00515     int p,x,y;
00516 
00517     for(p=0; p<3; p++){
00518         int is_chroma= !!p;
00519         int w= s->avctx->width  >>is_chroma;
00520         int h= s->avctx->height >>is_chroma;
00521         int ls= frame->linesize[p];
00522         uint8_t *src= frame->data[p];
00523 
00524         halfpel[1][p] = (uint8_t*) av_malloc(ls * (h + 2 * EDGE_WIDTH)) + EDGE_WIDTH * (1 + ls);
00525         halfpel[2][p] = (uint8_t*) av_malloc(ls * (h + 2 * EDGE_WIDTH)) + EDGE_WIDTH * (1 + ls);
00526         halfpel[3][p] = (uint8_t*) av_malloc(ls * (h + 2 * EDGE_WIDTH)) + EDGE_WIDTH * (1 + ls);
00527 
00528         halfpel[0][p]= src;
00529         for(y=0; y<h; y++){
00530             for(x=0; x<w; x++){
00531                 int i= y*ls + x;
00532 
00533                 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;
00534             }
00535         }
00536         for(y=0; y<h; y++){
00537             for(x=0; x<w; x++){
00538                 int i= y*ls + x;
00539 
00540                 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;
00541             }
00542         }
00543         src= halfpel[1][p];
00544         for(y=0; y<h; y++){
00545             for(x=0; x<w; x++){
00546                 int i= y*ls + x;
00547 
00548                 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;
00549             }
00550         }
00551 
00552 //FIXME border!
00553     }
00554 }
00555 
00556 void ff_snow_release_buffer(AVCodecContext *avctx)
00557 {
00558     SnowContext *s = avctx->priv_data;
00559     int i;
00560 
00561     if(s->last_picture[s->max_ref_frames-1].data[0]){
00562         avctx->release_buffer(avctx, &s->last_picture[s->max_ref_frames-1]);
00563         for(i=0; i<9; i++)
00564             if(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3])
00565                 av_free(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] - EDGE_WIDTH*(1+s->current_picture.linesize[i%3]));
00566     }
00567 }
00568 
00569 int ff_snow_frame_start(SnowContext *s){
00570    AVFrame tmp;
00571    int w= s->avctx->width; //FIXME round up to x16 ?
00572    int h= s->avctx->height;
00573 
00574     if (s->current_picture.data[0] && !(s->avctx->flags&CODEC_FLAG_EMU_EDGE)) {
00575         s->dsp.draw_edges(s->current_picture.data[0],
00576                           s->current_picture.linesize[0], w   , h   ,
00577                           EDGE_WIDTH  , EDGE_WIDTH  , EDGE_TOP | EDGE_BOTTOM);
00578         s->dsp.draw_edges(s->current_picture.data[1],
00579                           s->current_picture.linesize[1], w>>1, h>>1,
00580                           EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM);
00581         s->dsp.draw_edges(s->current_picture.data[2],
00582                           s->current_picture.linesize[2], w>>1, h>>1,
00583                           EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM);
00584     }
00585 
00586     ff_snow_release_buffer(s->avctx);
00587 
00588     tmp= s->last_picture[s->max_ref_frames-1];
00589     memmove(s->last_picture+1, s->last_picture, (s->max_ref_frames-1)*sizeof(AVFrame));
00590     memmove(s->halfpel_plane+1, s->halfpel_plane, (s->max_ref_frames-1)*sizeof(void*)*4*4);
00591     if(USE_HALFPEL_PLANE && s->current_picture.data[0])
00592         halfpel_interpol(s, s->halfpel_plane[0], &s->current_picture);
00593     s->last_picture[0]= s->current_picture;
00594     s->current_picture= tmp;
00595 
00596     if(s->keyframe){
00597         s->ref_frames= 0;
00598     }else{
00599         int i;
00600         for(i=0; i<s->max_ref_frames && s->last_picture[i].data[0]; i++)
00601             if(i && s->last_picture[i-1].key_frame)
00602                 break;
00603         s->ref_frames= i;
00604         if(s->ref_frames==0){
00605             av_log(s->avctx,AV_LOG_ERROR, "No reference frames\n");
00606             return -1;
00607         }
00608     }
00609 
00610     s->current_picture.reference= 3;
00611     if(s->avctx->get_buffer(s->avctx, &s->current_picture) < 0){
00612         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00613         return -1;
00614     }
00615 
00616     s->current_picture.key_frame= s->keyframe;
00617 
00618     return 0;
00619 }
00620 
00621 av_cold void ff_snow_common_end(SnowContext *s)
00622 {
00623     int plane_index, level, orientation, i;
00624 
00625     av_freep(&s->spatial_dwt_buffer);
00626     av_freep(&s->spatial_idwt_buffer);
00627 
00628     s->m.me.temp= NULL;
00629     av_freep(&s->m.me.scratchpad);
00630     av_freep(&s->m.me.map);
00631     av_freep(&s->m.me.score_map);
00632     av_freep(&s->m.obmc_scratchpad);
00633 
00634     av_freep(&s->block);
00635     av_freep(&s->scratchbuf);
00636 
00637     for(i=0; i<MAX_REF_FRAMES; i++){
00638         av_freep(&s->ref_mvs[i]);
00639         av_freep(&s->ref_scores[i]);
00640         if(s->last_picture[i].data[0])
00641             s->avctx->release_buffer(s->avctx, &s->last_picture[i]);
00642     }
00643 
00644     for(plane_index=0; plane_index<3; plane_index++){
00645         for(level=s->spatial_decomposition_count-1; level>=0; level--){
00646             for(orientation=level ? 1 : 0; orientation<4; orientation++){
00647                 SubBand *b= &s->plane[plane_index].band[level][orientation];
00648 
00649                 av_freep(&b->x_coeff);
00650             }
00651         }
00652     }
00653     if (s->mconly_picture.data[0])
00654         s->avctx->release_buffer(s->avctx, &s->mconly_picture);
00655     if (s->current_picture.data[0])
00656         s->avctx->release_buffer(s->avctx, &s->current_picture);
00657 }
00658 
Generated on Fri Feb 1 2013 14:34:43 for FFmpeg by doxygen 1.7.1