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

Generated on Fri Sep 16 2011 17:17:38 for FFmpeg by  doxygen 1.7.1