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

libavcodec/intrax8.c

Go to the documentation of this file.
00001 /*
00002  * This file is part of FFmpeg.
00003  *
00004  * FFmpeg is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * FFmpeg is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with FFmpeg; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00017  */
00018 
00024 #include "avcodec.h"
00025 #include "bitstream.h"
00026 #include "mpegvideo.h"
00027 #include "msmpeg4data.h"
00028 #include "intrax8huf.h"
00029 #include "intrax8.h"
00030 
00031 #define MAX_TABLE_DEPTH(table_bits, max_bits) ((max_bits+table_bits-1)/table_bits)
00032 
00033 #define DC_VLC_BITS 9
00034 #define AC_VLC_BITS 9
00035 #define OR_VLC_BITS 7
00036 
00037 #define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS)
00038 #define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
00039 #define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS)
00040 
00041 static VLC j_ac_vlc[2][2][8];  //[quant<13],[intra/inter],[select]
00042 static VLC j_dc_vlc[2][8];     //[quant], [select]
00043 static VLC j_orient_vlc[2][4]; //[quant], [select]
00044 
00045 static av_cold void x8_vlc_init(void){
00046     int i;
00047 
00048 #define  init_ac_vlc(dst,src) \
00049        init_vlc(&dst, \
00050               AC_VLC_BITS,77, \
00051               &src[1],4,2, \
00052               &src[0],4,2, \
00053               1)
00054 //set ac tables
00055     for(i=0;i<8;i++){
00056         init_ac_vlc( j_ac_vlc[0][0][i], x8_ac0_highquant_table[i][0] );
00057         init_ac_vlc( j_ac_vlc[0][1][i], x8_ac1_highquant_table[i][0] );
00058         init_ac_vlc( j_ac_vlc[1][0][i], x8_ac0_lowquant_table [i][0] );
00059         init_ac_vlc( j_ac_vlc[1][1][i], x8_ac1_lowquant_table [i][0] );
00060     }
00061 #undef init_ac_vlc
00062 
00063 //set dc tables
00064 #define init_dc_vlc(dst,src) \
00065         init_vlc(&dst, \
00066         DC_VLC_BITS,34, \
00067         &src[1],4,2, \
00068         &src[0],4,2, \
00069         1);
00070     for(i=0;i<8;i++){
00071         init_dc_vlc( j_dc_vlc[0][i], x8_dc_highquant_table[i][0]);
00072         init_dc_vlc( j_dc_vlc[1][i], x8_dc_lowquant_table [i][0]);
00073     }
00074 #undef init_dc_vlc
00075 
00076 //set orient tables
00077 #define init_or_vlc(dst,src) \
00078     init_vlc(&dst, \
00079     OR_VLC_BITS,12, \
00080     &src[1],4,2, \
00081     &src[0],4,2, \
00082     1);
00083     for(i=0;i<2;i++){
00084         init_or_vlc( j_orient_vlc[0][i], x8_orient_highquant_table[i][0]);
00085     }
00086     for(i=0;i<4;i++){
00087         init_or_vlc( j_orient_vlc[1][i], x8_orient_lowquant_table [i][0])
00088     }
00089 }
00090 #undef init_or_vlc
00091 
00092 static void x8_reset_vlc_tables(IntraX8Context * w){
00093     memset(w->j_dc_vlc,0,sizeof(w->j_dc_vlc));
00094     memset(w->j_ac_vlc,0,sizeof(w->j_ac_vlc));
00095     w->j_orient_vlc=NULL;
00096 }
00097 
00098 static inline void x8_select_ac_table(IntraX8Context * const w , int mode){
00099     MpegEncContext * const s= w->s;
00100     int table_index;
00101 
00102     assert(mode<4);
00103 
00104     if( w->j_ac_vlc[mode] ) return;
00105 
00106     table_index = get_bits(&s->gb, 3);
00107     w->j_ac_vlc[mode] = &j_ac_vlc[w->quant<13][mode>>1][table_index];//2 modes use same tables
00108     assert(w->j_ac_vlc[mode]);
00109 }
00110 
00111 static inline int x8_get_orient_vlc(IntraX8Context * w){
00112     MpegEncContext * const s= w->s;
00113     int table_index;
00114 
00115     if(!w->j_orient_vlc ){
00116         table_index = get_bits(&s->gb, 1+(w->quant<13) );
00117         w->j_orient_vlc = &j_orient_vlc[w->quant<13][table_index];
00118     }
00119     assert(w->j_orient_vlc);
00120     assert(w->j_orient_vlc->table);
00121 
00122     return get_vlc2(&s->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD);
00123 }
00124 
00125 #define extra_bits(eb) (eb)
00126 #define extra_run   (0xFF<<8)
00127 #define extra_level (0x00<<8)
00128 #define   run_offset(r)    ((r)<<16)
00129 #define level_offset(l)    ((l)<<24)
00130 static const uint32_t ac_decode_table[]={
00131     /*46*/ extra_bits(3) |  extra_run  | run_offset(16) | level_offset( 0),
00132     /*47*/ extra_bits(3) |  extra_run  | run_offset(24) | level_offset( 0),
00133     /*48*/ extra_bits(2) |  extra_run  | run_offset( 4) | level_offset( 1),
00134     /*49*/ extra_bits(3) |  extra_run  | run_offset( 8) | level_offset( 1),
00135 
00136     /*50*/ extra_bits(5) |  extra_run  | run_offset(32) | level_offset( 0),
00137     /*51*/ extra_bits(4) |  extra_run  | run_offset(16) | level_offset( 1),
00138 
00139     /*52*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4),
00140     /*53*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 8),
00141     /*54*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset(12),
00142     /*55*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(16),
00143     /*56*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(24),
00144 
00145     /*57*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3),
00146     /*58*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7),
00147 
00148     /*59*/ extra_bits(2) |  extra_run  | run_offset(16) | level_offset( 0),
00149     /*60*/ extra_bits(2) |  extra_run  | run_offset(20) | level_offset( 0),
00150     /*61*/ extra_bits(2) |  extra_run  | run_offset(24) | level_offset( 0),
00151     /*62*/ extra_bits(2) |  extra_run  | run_offset(28) | level_offset( 0),
00152     /*63*/ extra_bits(4) |  extra_run  | run_offset(32) | level_offset( 0),
00153     /*64*/ extra_bits(4) |  extra_run  | run_offset(48) | level_offset( 0),
00154 
00155     /*65*/ extra_bits(2) |  extra_run  | run_offset( 4) | level_offset( 1),
00156     /*66*/ extra_bits(3) |  extra_run  | run_offset( 8) | level_offset( 1),
00157     /*67*/ extra_bits(4) |  extra_run  | run_offset(16) | level_offset( 1),
00158 
00159     /*68*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4),
00160     /*69*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset( 8),
00161     /*70*/ extra_bits(4) | extra_level | run_offset( 0) | level_offset(16),
00162 
00163     /*71*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3),
00164     /*72*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7),
00165 };
00166 //extra_bits = 3bits; extra_run/level = 1 bit; run_offset = 6bits; level_offset = 5 bits;
00167 #undef extra_bits
00168 #undef extra_run
00169 #undef extra_level
00170 #undef run_offset
00171 #undef level_offset
00172 
00173 static void x8_get_ac_rlf(IntraX8Context * const w, const int mode,
00174                      int * const run, int * const level, int * const final){
00175     MpegEncContext *  const s= w->s;
00176     int i,e;
00177 
00178 //    x8_select_ac_table(w,mode);
00179     i = get_vlc2(&s->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD);
00180 
00181     if(i<46){ //[0-45]
00182         int t,l;
00183         if(i<0){
00184             (*level)=(*final)=//prevent 'may be used unilitialized'
00185             (*run)=64;//this would cause error exit in the ac loop
00186             return;
00187         }
00188 
00189         (*final) = t = (i>22);
00190         i-=23*t;
00191 /*
00192   i== 0-15 r=0-15 l=0 ;r=i& %01111
00193   i==16-19 r=0-3  l=1 ;r=i& %00011
00194   i==20-21 r=0-1  l=2 ;r=i& %00001
00195   i==22    r=0    l=3 ;r=i& %00000
00196 l=lut_l[i/2]={0,0,0,0,0,0,0,0,1,1,2,3}[i>>1];// 11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000
00197 t=lut_mask[l]={0x0f,0x03,0x01,0x00}[l]; as i<256 the higher bits do not matter */
00198         l=(0xE50000>>(i&(0x1E)))&3;/*0x1E or (~1) or ((i>>1)<<1)*/
00199         t=(0x01030F>>(l<<3));
00200 
00201         (*run)   = i&t;
00202         (*level) = l;
00203     }else if(i<73){//[46-72]
00204         uint32_t sm;
00205         uint32_t mask;
00206 
00207         i-=46;
00208         sm=ac_decode_table[i];
00209 
00210         e=get_bits(&s->gb,sm&0xF);sm>>=8;//3bits
00211         mask=sm&0xff;sm>>=8;             //1bit
00212 
00213         (*run)  =(sm&0xff) + (e&( mask));//6bits
00214         (*level)=(sm>>8)   + (e&(~mask));//5bits
00215         (*final)=i>(58-46);
00216     }else if(i<75){//[73-74]
00217         static const uint8_t crazy_mix_runlevel[32]={
00218         0x22,0x32,0x33,0x53,0x23,0x42,0x43,0x63,
00219         0x24,0x52,0x34,0x73,0x25,0x62,0x44,0x83,
00220         0x26,0x72,0x35,0x54,0x27,0x82,0x45,0x64,
00221         0x28,0x92,0x36,0x74,0x29,0xa2,0x46,0x84};
00222 
00223         (*final)=!(i&1);
00224         e=get_bits(&s->gb,5);//get the extra bits
00225         (*run)  =crazy_mix_runlevel[e]>>4;
00226         (*level)=crazy_mix_runlevel[e]&0x0F;
00227     }else{
00228         (*level)=get_bits( &s->gb, 7-3*(i&1));
00229         (*run)  =get_bits( &s->gb, 6);
00230         (*final)=get_bits1(&s->gb);
00231     }
00232     return;
00233 }
00234 
00235 //static const uint8_t dc_extra_sbits[]   ={0, 1,1, 1,1, 2,2, 3,3,   4,4,   5,5,   6,6,    7,7    };
00236 static const uint8_t dc_index_offset[]  ={ 0, 1,2, 3,4, 5,7, 9,13, 17,25, 33,49, 65,97, 129,193};
00237 
00238 static int x8_get_dc_rlf(IntraX8Context * const w,int const mode, int * const level, int * const final){
00239     MpegEncContext * const s= w->s;
00240     int i,e,c;
00241 
00242     assert(mode<3);
00243     if( !w->j_dc_vlc[mode] ) {
00244         int table_index;
00245         table_index = get_bits(&s->gb, 3);
00246         //4 modes, same table
00247         w->j_dc_vlc[mode]= &j_dc_vlc[w->quant<13][table_index];
00248     }
00249     assert(w->j_dc_vlc);
00250     assert(w->j_dc_vlc[mode]->table);
00251 
00252     i=get_vlc2(&s->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD);
00253 
00254     /*(i>=17) {i-=17;final=1;}*/
00255     c= i>16;
00256     (*final)=c;
00257     i-=17*c;
00258 
00259     if(i<=0){
00260         (*level)=0;
00261         return -i;
00262     }
00263     c=(i+1)>>1;//hackish way to calculate dc_extra_sbits[]
00264     c-=c>1;
00265 
00266     e=get_bits(&s->gb,c);//get the extra bits
00267     i=dc_index_offset[i]+(e>>1);
00268 
00269     e= -(e & 1);//0,0xffffff
00270     (*level)= (i ^ e) - e;// (i^0)-0 , (i^0xff)-(-1)
00271     return 0;
00272 }
00273 //end of huffman
00274 
00275 static int x8_setup_spatial_predictor(IntraX8Context * const w, const int chroma){
00276     MpegEncContext * const s= w->s;
00277     int range;
00278     int sum;
00279     int quant;
00280 
00281     s->dsp.x8_setup_spatial_compensation(s->dest[chroma], s->edge_emu_buffer,
00282                                           s->current_picture.linesize[chroma>0],
00283                                           &range, &sum, w->edges);
00284     if(chroma){
00285         w->orient=w->chroma_orient;
00286         quant=w->quant_dc_chroma;
00287     }else{
00288         quant=w->quant;
00289     }
00290 
00291     w->flat_dc=0;
00292     if(range < quant || range < 3){
00293         w->orient=0;
00294         if(range < 3){//yep you read right, a +-1 idct error may break decoding!
00295             w->flat_dc=1;
00296             sum+=9;
00297             w->predicted_dc = (sum*6899)>>17;//((1<<17)+9)/(8+8+1+2)=6899
00298         }
00299     }
00300     if(chroma)
00301         return 0;
00302 
00303     assert(w->orient < 3);
00304     if(range < 2*w->quant){
00305         if( (w->edges&3) == 0){
00306             if(w->orient==1) w->orient=11;
00307             if(w->orient==2) w->orient=10;
00308         }else{
00309             w->orient=0;
00310         }
00311         w->raw_orient=0;
00312     }else{
00313         static const uint8_t prediction_table[3][12]={
00314             {0,8,4, 10,11, 2,6,9,1,3,5,7},
00315             {4,0,8, 11,10, 3,5,2,6,9,1,7},
00316             {8,0,4, 10,11, 1,7,2,6,9,3,5}
00317         };
00318         w->raw_orient=x8_get_orient_vlc(w);
00319         if(w->raw_orient<0) return -1;
00320         assert(w->raw_orient < 12 );
00321         assert(w->orient<3);
00322         w->orient=prediction_table[w->orient][w->raw_orient];
00323     }
00324     return 0;
00325 }
00326 
00327 static void x8_update_predictions(IntraX8Context * const w, const int orient, const int est_run ){
00328     MpegEncContext * const s= w->s;
00329 
00330     w->prediction_table[s->mb_x*2+(s->mb_y&1)] = (est_run<<2) + 1*(orient==4) + 2*(orient==8);
00331 /*
00332   y=2n+0 ->//0 2 4
00333   y=2n+1 ->//1 3 5
00334 */
00335 }
00336 static void x8_get_prediction_chroma(IntraX8Context * const w){
00337     MpegEncContext * const s= w->s;
00338 
00339     w->edges = 1*( !(s->mb_x>>1) );
00340     w->edges|= 2*( !(s->mb_y>>1) );
00341     w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );//mb_x for chroma would always be odd
00342 
00343     w->raw_orient=0;
00344     if(w->edges&3){//lut_co[8]={inv,4,8,8, inv,4,8,8}<- =>{1,1,0,0;1,1,0,0} => 0xCC
00345         w->chroma_orient=4<<((0xCC>>w->edges)&1);
00346         return;
00347     }
00348     w->chroma_orient = (w->prediction_table[2*s->mb_x-2] & 0x03)<<2;//block[x-1][y|1-1)]
00349 }
00350 
00351 static void x8_get_prediction(IntraX8Context * const w){
00352     MpegEncContext * const s= w->s;
00353     int a,b,c,i;
00354 
00355     w->edges = 1*( !s->mb_x );
00356     w->edges|= 2*( !s->mb_y );
00357     w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );
00358 
00359     switch(w->edges&3){
00360         case 0:
00361             break;
00362         case 1:
00363             //take the one from the above block[0][y-1]
00364             w->est_run = w->prediction_table[!(s->mb_y&1)]>>2;
00365             w->orient  = 1;
00366             return;
00367         case 2:
00368             //take the one from the previous block[x-1][0]
00369             w->est_run = w->prediction_table[2*s->mb_x-2]>>2;
00370             w->orient  = 2;
00371             return;
00372         case 3:
00373             w->est_run = 16;
00374             w->orient  = 0;
00375             return;
00376     }
00377     //no edge cases
00378     b= w->prediction_table[2*s->mb_x   + !(s->mb_y&1) ];//block[x  ][y-1]
00379     a= w->prediction_table[2*s->mb_x-2 +  (s->mb_y&1) ];//block[x-1][y  ]
00380     c= w->prediction_table[2*s->mb_x-2 + !(s->mb_y&1) ];//block[x-1][y-1]
00381 
00382     w->est_run = FFMIN(b,a);
00383     /* This condition has nothing to do with w->edges, even if it looks
00384        similar it would trigger if e.g. x=3;y=2;
00385        I guess somebody wrote something wrong and it became standard. */
00386     if( (s->mb_x & s->mb_y) != 0 ) w->est_run=FFMIN(c,w->est_run);
00387     w->est_run>>=2;
00388 
00389     a&=3;
00390     b&=3;
00391     c&=3;
00392 
00393     i=( 0xFFEAF4C4>>(2*b+8*a) )&3;
00394     if(i!=3) w->orient=i;
00395     else     w->orient=( 0xFFEAD8>>(2*c+8*(w->quant>12)) )&3;
00396 /*
00397 lut1[b][a]={
00398 ->{0, 1, 0, pad},
00399   {0, 1, X, pad},
00400   {2, 2, 2, pad}}
00401    pad 2   2  2; pad X  1  0; pad 0  1  0 <-
00402 -> 11 10 '10 10 '11 11'01 00 '11 00'01 00=>0xEAF4C4
00403 
00404 lut2[q>12][c]={
00405   ->{0,2,1,pad},
00406     {2,2,2,pad}}
00407    pad 2  2  2; pad 1  2  0 <-
00408 -> 11 10'10 10 '11 01'10 00=>0xEAD8
00409 */
00410 }
00411 
00412 
00413 static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){
00414     MpegEncContext * const s= w->s;
00415     int t;
00416 #define B(x,y)  s->block[0][s->dsp.idct_permutation[(x)+(y)*8]]
00417 #define T(x)  ((x) * dc_level + 0x8000) >> 16;
00418     switch(direction){
00419     case 0:
00420         t = T(3811);//h
00421         B(1,0) -= t;
00422         B(0,1) -= t;
00423 
00424         t = T(487);//e
00425         B(2,0) -= t;
00426         B(0,2) -= t;
00427 
00428         t = T(506);//f
00429         B(3,0) -= t;
00430         B(0,3) -= t;
00431 
00432         t = T(135);//c
00433         B(4,0) -= t;
00434         B(0,4) -= t;
00435         B(2,1) += t;
00436         B(1,2) += t;
00437         B(3,1) += t;
00438         B(1,3) += t;
00439 
00440         t = T(173);//d
00441         B(5,0) -= t;
00442         B(0,5) -= t;
00443 
00444         t = T(61);//b
00445         B(6,0) -= t;
00446         B(0,6) -= t;
00447         B(5,1) += t;
00448         B(1,5) += t;
00449 
00450         t = T(42); //a
00451         B(7,0) -= t;
00452         B(0,7) -= t;
00453         B(4,1) += t;
00454         B(1,4) += t;
00455         B(4,4) += t;
00456 
00457         t = T(1084);//g
00458         B(1,1) += t;
00459 
00460         s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
00461         break;
00462     case 1:
00463         B(0,1) -= T(6269);
00464         B(0,3) -= T( 708);
00465         B(0,5) -= T( 172);
00466         B(0,7) -= T(  73);
00467 
00468         s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
00469         break;
00470     case 2:
00471         B(1,0) -= T(6269);
00472         B(3,0) -= T( 708);
00473         B(5,0) -= T( 172);
00474         B(7,0) -= T(  73);
00475 
00476         s->block_last_index[0] = FFMAX(s->block_last_index[0], 7);
00477         break;
00478     }
00479 #undef B
00480 #undef T
00481 }
00482 
00483 static void dsp_x8_put_solidcolor(uint8_t const pix, uint8_t * dst, int const linesize){
00484     int k;
00485     for(k=0;k<8;k++){
00486         memset(dst,pix,8);
00487         dst+=linesize;
00488     }
00489 }
00490 
00491 static const int16_t quant_table[64] = {
00492     256, 256, 256, 256,  256, 256, 259, 262,
00493     265, 269, 272, 275,  278, 282, 285, 288,
00494     292, 295, 299, 303,  306, 310, 314, 317,
00495     321, 325, 329, 333,  337, 341, 345, 349,
00496     353, 358, 362, 366,  371, 375, 379, 384,
00497     389, 393, 398, 403,  408, 413, 417, 422,
00498     428, 433, 438, 443,  448, 454, 459, 465,
00499     470, 476, 482, 488,  493, 499, 505, 511
00500 };
00501 
00502 static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){
00503     MpegEncContext * const s= w->s;
00504 
00505     uint8_t * scantable;
00506     int final,run,level;
00507     int ac_mode,dc_mode,est_run,dc_level;
00508     int pos,n;
00509     int zeros_only;
00510     int use_quant_matrix;
00511     int sign;
00512 
00513     assert(w->orient<12);
00514     s->dsp.clear_block(s->block[0]);
00515 
00516     if(chroma){
00517         dc_mode=2;
00518     }else{
00519         dc_mode=!!w->est_run;//0,1
00520     }
00521 
00522     if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1;
00523     n=0;
00524     zeros_only=0;
00525     if(!final){//decode ac
00526         use_quant_matrix=w->use_quant_matrix;
00527         if(chroma){
00528             ac_mode = 1;
00529             est_run = 64;//not used
00530         }else{
00531             if (w->raw_orient < 3){
00532                 use_quant_matrix = 0;
00533             }
00534             if(w->raw_orient > 4){
00535                 ac_mode = 0;
00536                 est_run = 64;
00537             }else{
00538                 if(w->est_run > 1){
00539                     ac_mode = 2;
00540                     est_run=w->est_run;
00541                 }else{
00542                     ac_mode = 3;
00543                     est_run = 64;
00544                 }
00545             }
00546         }
00547         x8_select_ac_table(w,ac_mode);
00548         /*scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};<-
00549         -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>0x928548 */
00550         scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated;
00551         pos=0;
00552         do {
00553             n++;
00554             if( n >= est_run ){
00555                 ac_mode=3;
00556                 x8_select_ac_table(w,3);
00557             }
00558 
00559             x8_get_ac_rlf(w,ac_mode,&run,&level,&final);
00560 
00561             pos+=run+1;
00562             if(pos>63){
00563                 //this also handles vlc error in x8_get_ac_rlf
00564                 return -1;
00565             }
00566             level= (level+1) * w->dquant;
00567             level+= w->qsum;
00568 
00569             sign = - get_bits1(&s->gb);
00570             level = (level ^ sign) - sign;
00571 
00572             if(use_quant_matrix){
00573                 level = (level*quant_table[pos])>>8;
00574             }
00575             s->block[0][ scantable[pos] ]=level;
00576         }while(!final);
00577 
00578         s->block_last_index[0]=pos;
00579     }else{//DC only
00580         s->block_last_index[0]=0;
00581         if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){//[-1;1]
00582             int32_t divide_quant= !chroma ? w->divide_quant_dc_luma:
00583                                             w->divide_quant_dc_chroma;
00584             int32_t dc_quant    = !chroma ? w->quant:
00585                                             w->quant_dc_chroma;
00586 
00587             //original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding
00588             dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13;
00589 
00590             dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3),
00591                                    s->dest[chroma], s->current_picture.linesize[!!chroma]);
00592 
00593             goto block_placed;
00594         }
00595         zeros_only = (dc_level == 0);
00596     }
00597     if(!chroma){
00598         s->block[0][0] = dc_level*w->quant;
00599     }else{
00600         s->block[0][0] = dc_level*w->quant_dc_chroma;
00601     }
00602 
00603     //there is !zero_only check in the original, but dc_level check is enough
00604     if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){
00605         int direction;
00606         /*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<-
00607         -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */
00608         direction= (0x6A017C>>(w->orient*2))&3;
00609         if (direction != 3){
00610             x8_ac_compensation(w, direction, s->block[0][0]);//modify block_last[]
00611         }
00612     }
00613 
00614     if(w->flat_dc){
00615         dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.linesize[!!chroma]);
00616     }else{
00617         s->dsp.x8_spatial_compensation[w->orient]( s->edge_emu_buffer,
00618                                             s->dest[chroma],
00619                                             s->current_picture.linesize[!!chroma] );
00620     }
00621     if(!zeros_only)
00622         s->dsp.idct_add ( s->dest[chroma],
00623                           s->current_picture.linesize[!!chroma],
00624                           s->block[0] );
00625 
00626 block_placed:
00627 
00628     if(!chroma){
00629         x8_update_predictions(w,w->orient,n);
00630     }
00631 
00632     if(s->loop_filter){
00633         uint8_t* ptr = s->dest[chroma];
00634         int linesize = s->current_picture.linesize[!!chroma];
00635 
00636         if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){
00637             s->dsp.x8_h_loop_filter(ptr, linesize, w->quant);
00638         }
00639         if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){
00640             s->dsp.x8_v_loop_filter(ptr, linesize, w->quant);
00641         }
00642     }
00643     return 0;
00644 }
00645 
00646 static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_*
00647 //not s->linesize as this would be wrong for field pics
00648 //not that IntraX8 has interlacing support ;)
00649     const int linesize  = s->current_picture.linesize[0];
00650     const int uvlinesize= s->current_picture.linesize[1];
00651 
00652     s->dest[0] = s->current_picture.data[0];
00653     s->dest[1] = s->current_picture.data[1];
00654     s->dest[2] = s->current_picture.data[2];
00655 
00656     s->dest[0] +=   s->mb_y        *   linesize << 3;
00657     s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows
00658     s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2;
00659 }
00660 
00667 av_cold void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s){
00668 
00669     w->s=s;
00670     x8_vlc_init();
00671     assert(s->mb_width>0);
00672     w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb
00673 
00674     ff_init_scantable(s->dsp.idct_permutation, &w->scantable[0], wmv1_scantable[0]);
00675     ff_init_scantable(s->dsp.idct_permutation, &w->scantable[1], wmv1_scantable[2]);
00676     ff_init_scantable(s->dsp.idct_permutation, &w->scantable[2], wmv1_scantable[3]);
00677 }
00678 
00683 av_cold void ff_intrax8_common_end(IntraX8Context * w)
00684 {
00685     av_freep(&w->prediction_table);
00686 }
00687 
00699 //FIXME extern uint8_t wmv3_dc_scale_table[32];
00700 int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){
00701     MpegEncContext * const s= w->s;
00702     int mb_xy;
00703     assert(s);
00704     w->use_quant_matrix = get_bits1(&s->gb);
00705 
00706     w->dquant = dquant;
00707     w->quant  = dquant >> 1;
00708     w->qsum   = quant_offset;
00709 
00710     w->divide_quant_dc_luma = ((1<<16) + (w->quant>>1)) / w->quant;
00711     if(w->quant < 5){
00712         w->quant_dc_chroma =  w->quant;
00713         w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
00714     }else{
00715         w->quant_dc_chroma =  w->quant+((w->quant+3)>>3);
00716         w->divide_quant_dc_chroma = ((1<<16) + (w->quant_dc_chroma>>1)) / w->quant_dc_chroma;
00717     }
00718     x8_reset_vlc_tables(w);
00719 
00720     s->resync_mb_x=0;
00721     s->resync_mb_y=0;
00722 
00723     for(s->mb_y=0; s->mb_y < s->mb_height*2; s->mb_y++){
00724         x8_init_block_index(s);
00725         mb_xy=(s->mb_y>>1)*s->mb_stride;
00726 
00727         for(s->mb_x=0; s->mb_x < s->mb_width*2; s->mb_x++){
00728             x8_get_prediction(w);
00729             if(x8_setup_spatial_predictor(w,0)) goto error;
00730             if(x8_decode_intra_mb(w,0)) goto error;
00731 
00732             if( s->mb_x & s->mb_y & 1 ){
00733                 x8_get_prediction_chroma(w);
00734 
00735                 /*when setting up chroma, no vlc is read,
00736                 so no error condition can be reached*/
00737                 x8_setup_spatial_predictor(w,1);
00738                 if(x8_decode_intra_mb(w,1)) goto error;
00739 
00740                 x8_setup_spatial_predictor(w,2);
00741                 if(x8_decode_intra_mb(w,2)) goto error;
00742 
00743                 s->dest[1]+= 8;
00744                 s->dest[2]+= 8;
00745 
00746                 /*emulate MB info in the relevant tables*/
00747                 s->mbskip_table [mb_xy]=0;
00748                 s->mbintra_table[mb_xy]=1;
00749                 s->current_picture.qscale_table[mb_xy]=w->quant;
00750                 mb_xy++;
00751             }
00752             s->dest[0]+= 8;
00753         }
00754         if(s->mb_y&1){
00755             ff_draw_horiz_band(s, (s->mb_y-1)*8, 16);
00756         }
00757     }
00758 
00759 error:
00760     ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
00761                         (s->mb_x>>1)-1, (s->mb_y>>1)-1,
00762                         (AC_END|DC_END|MV_END) );
00763     return 0;
00764 }

Generated on Sat Feb 16 2013 09:23:12 for ffmpeg by  doxygen 1.7.1