00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00024 #include "libavutil/avassert.h"
00025 #include "avcodec.h"
00026 #include "get_bits.h"
00027 #include "mpegvideo.h"
00028 #include "msmpeg4data.h"
00029 #include "intrax8huf.h"
00030 #include "intrax8.h"
00031 #include "intrax8dsp.h"
00032 
00033 #define MAX_TABLE_DEPTH(table_bits, max_bits) ((max_bits+table_bits-1)/table_bits)
00034 
00035 #define DC_VLC_BITS 9
00036 #define AC_VLC_BITS 9
00037 #define OR_VLC_BITS 7
00038 
00039 #define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS)
00040 #define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
00041 #define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS)
00042 
00043 static VLC j_ac_vlc[2][2][8];  
00044 static VLC j_dc_vlc[2][8];     
00045 static VLC j_orient_vlc[2][4]; 
00046 
00047 static av_cold void x8_vlc_init(void){
00048     int i;
00049     int offset = 0;
00050     int sizeidx = 0;
00051     static const uint16_t sizes[8*4 + 8*2 + 2 + 4] = {
00052         576, 548, 582, 618, 546, 616, 560, 642,
00053         584, 582, 704, 664, 512, 544, 656, 640,
00054         512, 648, 582, 566, 532, 614, 596, 648,
00055         586, 552, 584, 590, 544, 578, 584, 624,
00056 
00057         528, 528, 526, 528, 536, 528, 526, 544,
00058         544, 512, 512, 528, 528, 544, 512, 544,
00059 
00060         128, 128, 128, 128, 128, 128};
00061 
00062     static VLC_TYPE table[28150][2];
00063 
00064 #define  init_ac_vlc(dst,src) \
00065     dst.table = &table[offset]; \
00066     dst.table_allocated = sizes[sizeidx]; \
00067     offset += sizes[sizeidx++]; \
00068        init_vlc(&dst, \
00069               AC_VLC_BITS,77, \
00070               &src[1],4,2, \
00071               &src[0],4,2, \
00072               INIT_VLC_USE_NEW_STATIC)
00073 
00074     for(i=0;i<8;i++){
00075         init_ac_vlc( j_ac_vlc[0][0][i], x8_ac0_highquant_table[i][0] );
00076         init_ac_vlc( j_ac_vlc[0][1][i], x8_ac1_highquant_table[i][0] );
00077         init_ac_vlc( j_ac_vlc[1][0][i], x8_ac0_lowquant_table [i][0] );
00078         init_ac_vlc( j_ac_vlc[1][1][i], x8_ac1_lowquant_table [i][0] );
00079     }
00080 #undef init_ac_vlc
00081 
00082 
00083 #define init_dc_vlc(dst,src) \
00084     dst.table = &table[offset]; \
00085     dst.table_allocated = sizes[sizeidx]; \
00086     offset += sizes[sizeidx++]; \
00087         init_vlc(&dst, \
00088         DC_VLC_BITS,34, \
00089         &src[1],4,2, \
00090         &src[0],4,2, \
00091         INIT_VLC_USE_NEW_STATIC);
00092     for(i=0;i<8;i++){
00093         init_dc_vlc( j_dc_vlc[0][i], x8_dc_highquant_table[i][0]);
00094         init_dc_vlc( j_dc_vlc[1][i], x8_dc_lowquant_table [i][0]);
00095     }
00096 #undef init_dc_vlc
00097 
00098 
00099 #define init_or_vlc(dst,src) \
00100     dst.table = &table[offset]; \
00101     dst.table_allocated = sizes[sizeidx]; \
00102     offset += sizes[sizeidx++]; \
00103     init_vlc(&dst, \
00104     OR_VLC_BITS,12, \
00105     &src[1],4,2, \
00106     &src[0],4,2, \
00107     INIT_VLC_USE_NEW_STATIC);
00108     for(i=0;i<2;i++){
00109         init_or_vlc( j_orient_vlc[0][i], x8_orient_highquant_table[i][0]);
00110     }
00111     for(i=0;i<4;i++){
00112         init_or_vlc( j_orient_vlc[1][i], x8_orient_lowquant_table [i][0])
00113     }
00114     if (offset != sizeof(table)/sizeof(VLC_TYPE)/2)
00115         av_log(NULL, AV_LOG_ERROR, "table size %i does not match needed %i\n", (int)(sizeof(table)/sizeof(VLC_TYPE)/2), offset);
00116 }
00117 #undef init_or_vlc
00118 
00119 static void x8_reset_vlc_tables(IntraX8Context * w){
00120     memset(w->j_dc_vlc,0,sizeof(w->j_dc_vlc));
00121     memset(w->j_ac_vlc,0,sizeof(w->j_ac_vlc));
00122     w->j_orient_vlc=NULL;
00123 }
00124 
00125 static inline void x8_select_ac_table(IntraX8Context * const w , int mode){
00126     MpegEncContext * const s= w->s;
00127     int table_index;
00128 
00129     av_assert2(mode<4);
00130 
00131     if( w->j_ac_vlc[mode] ) return;
00132 
00133     table_index = get_bits(&s->gb, 3);
00134     w->j_ac_vlc[mode] = &j_ac_vlc[w->quant<13][mode>>1][table_index];
00135     av_assert2(w->j_ac_vlc[mode]);
00136 }
00137 
00138 static inline int x8_get_orient_vlc(IntraX8Context * w){
00139     MpegEncContext * const s= w->s;
00140     int table_index;
00141 
00142     if(!w->j_orient_vlc ){
00143         table_index = get_bits(&s->gb, 1+(w->quant<13) );
00144         w->j_orient_vlc = &j_orient_vlc[w->quant<13][table_index];
00145     }
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      extra_bits(3) |  extra_run  | run_offset(16) | level_offset( 0),
00157      extra_bits(3) |  extra_run  | run_offset(24) | level_offset( 0),
00158      extra_bits(2) |  extra_run  | run_offset( 4) | level_offset( 1),
00159      extra_bits(3) |  extra_run  | run_offset( 8) | level_offset( 1),
00160 
00161      extra_bits(5) |  extra_run  | run_offset(32) | level_offset( 0),
00162      extra_bits(4) |  extra_run  | run_offset(16) | level_offset( 1),
00163 
00164      extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4),
00165      extra_bits(2) | extra_level | run_offset( 0) | level_offset( 8),
00166      extra_bits(2) | extra_level | run_offset( 0) | level_offset(12),
00167      extra_bits(3) | extra_level | run_offset( 0) | level_offset(16),
00168      extra_bits(3) | extra_level | run_offset( 0) | level_offset(24),
00169 
00170      extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3),
00171      extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7),
00172 
00173      extra_bits(2) |  extra_run  | run_offset(16) | level_offset( 0),
00174      extra_bits(2) |  extra_run  | run_offset(20) | level_offset( 0),
00175      extra_bits(2) |  extra_run  | run_offset(24) | level_offset( 0),
00176      extra_bits(2) |  extra_run  | run_offset(28) | level_offset( 0),
00177      extra_bits(4) |  extra_run  | run_offset(32) | level_offset( 0),
00178      extra_bits(4) |  extra_run  | run_offset(48) | level_offset( 0),
00179 
00180      extra_bits(2) |  extra_run  | run_offset( 4) | level_offset( 1),
00181      extra_bits(3) |  extra_run  | run_offset( 8) | level_offset( 1),
00182      extra_bits(4) |  extra_run  | run_offset(16) | level_offset( 1),
00183 
00184      extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4),
00185      extra_bits(3) | extra_level | run_offset( 0) | level_offset( 8),
00186      extra_bits(4) | extra_level | run_offset( 0) | level_offset(16),
00187 
00188      extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3),
00189      extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7),
00190 };
00191 
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 
00204     i = get_vlc2(&s->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD);
00205 
00206     if(i<46){ 
00207         int t,l;
00208         if(i<0){
00209             (*level)=(*final)=
00210             (*run)=64;
00211             return;
00212         }
00213 
00214         (*final) = t = (i>22);
00215         i-=23*t;
00216 
00217 
00218 
00219 
00220 
00221 
00222 
00223         l=(0xE50000>>(i&(0x1E)))&3;
00224         t=(0x01030F>>(l<<3));
00225 
00226         (*run)   = i&t;
00227         (*level) = l;
00228     }else if(i<73){
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;
00236         mask=sm&0xff;sm>>=8;             
00237 
00238         (*run)  =(sm&0xff) + (e&( mask));
00239         (*level)=(sm>>8)   + (e&(~mask));
00240         (*final)=i>(58-46);
00241     }else if(i<75){
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);
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 
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     av_assert2(mode<3);
00268     if( !w->j_dc_vlc[mode] ) {
00269         int table_index;
00270         table_index = get_bits(&s->gb, 3);
00271         
00272         w->j_dc_vlc[mode]= &j_dc_vlc[w->quant<13][table_index];
00273     }
00274 
00275     i=get_vlc2(&s->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD);
00276 
00277     
00278     c= i>16;
00279     (*final)=c;
00280     i-=17*c;
00281 
00282     if(i<=0){
00283         (*level)=0;
00284         return -i;
00285     }
00286     c=(i+1)>>1;
00287     c-=c>1;
00288 
00289     e=get_bits(&s->gb,c);
00290     i=dc_index_offset[i]+(e>>1);
00291 
00292     e= -(e & 1);
00293     (*level)= (i ^ e) - e;
00294     return 0;
00295 }
00296 
00297 
00298 static int x8_setup_spatial_predictor(IntraX8Context * const w, const int chroma){
00299     MpegEncContext * const s= w->s;
00300     int range;
00301     int sum;
00302     int quant;
00303 
00304     w->dsp.setup_spatial_compensation(s->dest[chroma], s->edge_emu_buffer,
00305                                       s->current_picture.f.linesize[chroma>0],
00306                                       &range, &sum, w->edges);
00307     if(chroma){
00308         w->orient=w->chroma_orient;
00309         quant=w->quant_dc_chroma;
00310     }else{
00311         quant=w->quant;
00312     }
00313 
00314     w->flat_dc=0;
00315     if(range < quant || range < 3){
00316         w->orient=0;
00317         if(range < 3){
00318             w->flat_dc=1;
00319             sum+=9;
00320             w->predicted_dc = (sum*6899)>>17;
00321         }
00322     }
00323     if(chroma)
00324         return 0;
00325 
00326     av_assert2(w->orient < 3);
00327     if(range < 2*w->quant){
00328         if( (w->edges&3) == 0){
00329             if(w->orient==1) w->orient=11;
00330             if(w->orient==2) w->orient=10;
00331         }else{
00332             w->orient=0;
00333         }
00334         w->raw_orient=0;
00335     }else{
00336         static const uint8_t prediction_table[3][12]={
00337             {0,8,4, 10,11, 2,6,9,1,3,5,7},
00338             {4,0,8, 11,10, 3,5,2,6,9,1,7},
00339             {8,0,4, 10,11, 1,7,2,6,9,3,5}
00340         };
00341         w->raw_orient=x8_get_orient_vlc(w);
00342         if(w->raw_orient<0) return -1;
00343         av_assert2(w->raw_orient < 12 );
00344         av_assert2(w->orient<3);
00345         w->orient=prediction_table[w->orient][w->raw_orient];
00346     }
00347     return 0;
00348 }
00349 
00350 static void x8_update_predictions(IntraX8Context * const w, const int orient, const int est_run ){
00351     MpegEncContext * const s= w->s;
00352 
00353     w->prediction_table[s->mb_x*2+(s->mb_y&1)] = (est_run<<2) + 1*(orient==4) + 2*(orient==8);
00354 
00355 
00356 
00357 
00358 }
00359 static void x8_get_prediction_chroma(IntraX8Context * const w){
00360     MpegEncContext * const s= w->s;
00361 
00362     w->edges = 1*( !(s->mb_x>>1) );
00363     w->edges|= 2*( !(s->mb_y>>1) );
00364     w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );
00365 
00366     w->raw_orient=0;
00367     if(w->edges&3){
00368         w->chroma_orient=4<<((0xCC>>w->edges)&1);
00369         return;
00370     }
00371     w->chroma_orient = (w->prediction_table[2*s->mb_x-2] & 0x03)<<2;
00372 }
00373 
00374 static void x8_get_prediction(IntraX8Context * const w){
00375     MpegEncContext * const s= w->s;
00376     int a,b,c,i;
00377 
00378     w->edges = 1*( !s->mb_x );
00379     w->edges|= 2*( !s->mb_y );
00380     w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );
00381 
00382     switch(w->edges&3){
00383         case 0:
00384             break;
00385         case 1:
00386             
00387             w->est_run = w->prediction_table[!(s->mb_y&1)]>>2;
00388             w->orient  = 1;
00389             return;
00390         case 2:
00391             
00392             w->est_run = w->prediction_table[2*s->mb_x-2]>>2;
00393             w->orient  = 2;
00394             return;
00395         case 3:
00396             w->est_run = 16;
00397             w->orient  = 0;
00398             return;
00399     }
00400     
00401     b= w->prediction_table[2*s->mb_x   + !(s->mb_y&1) ];
00402     a= w->prediction_table[2*s->mb_x-2 +  (s->mb_y&1) ];
00403     c= w->prediction_table[2*s->mb_x-2 + !(s->mb_y&1) ];
00404 
00405     w->est_run = FFMIN(b,a);
00406     
00407 
00408 
00409     if( (s->mb_x & s->mb_y) != 0 ) w->est_run=FFMIN(c,w->est_run);
00410     w->est_run>>=2;
00411 
00412     a&=3;
00413     b&=3;
00414     c&=3;
00415 
00416     i=( 0xFFEAF4C4>>(2*b+8*a) )&3;
00417     if(i!=3) w->orient=i;
00418     else     w->orient=( 0xFFEAD8>>(2*c+8*(w->quant>12)) )&3;
00419 
00420 
00421 
00422 
00423 
00424 
00425 
00426 
00427 
00428 
00429 
00430 
00431 
00432 
00433 }
00434 
00435 
00436 static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){
00437     MpegEncContext * const s= w->s;
00438     int t;
00439 #define B(x,y)  s->block[0][s->dsp.idct_permutation[(x)+(y)*8]]
00440 #define T(x)  ((x) * dc_level + 0x8000) >> 16;
00441     switch(direction){
00442     case 0:
00443         t = T(3811);
00444         B(1,0) -= t;
00445         B(0,1) -= t;
00446 
00447         t = T(487);
00448         B(2,0) -= t;
00449         B(0,2) -= t;
00450 
00451         t = T(506);
00452         B(3,0) -= t;
00453         B(0,3) -= t;
00454 
00455         t = T(135);
00456         B(4,0) -= t;
00457         B(0,4) -= t;
00458         B(2,1) += t;
00459         B(1,2) += t;
00460         B(3,1) += t;
00461         B(1,3) += t;
00462 
00463         t = T(173);
00464         B(5,0) -= t;
00465         B(0,5) -= t;
00466 
00467         t = T(61);
00468         B(6,0) -= t;
00469         B(0,6) -= t;
00470         B(5,1) += t;
00471         B(1,5) += t;
00472 
00473         t = T(42); 
00474         B(7,0) -= t;
00475         B(0,7) -= t;
00476         B(4,1) += t;
00477         B(1,4) += t;
00478         B(4,4) += t;
00479 
00480         t = T(1084);
00481         B(1,1) += t;
00482 
00483         s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
00484         break;
00485     case 1:
00486         B(0,1) -= T(6269);
00487         B(0,3) -= T( 708);
00488         B(0,5) -= T( 172);
00489         B(0,7) -= T(  73);
00490 
00491         s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
00492         break;
00493     case 2:
00494         B(1,0) -= T(6269);
00495         B(3,0) -= T( 708);
00496         B(5,0) -= T( 172);
00497         B(7,0) -= T(  73);
00498 
00499         s->block_last_index[0] = FFMAX(s->block_last_index[0], 7);
00500         break;
00501     }
00502 #undef B
00503 #undef T
00504 }
00505 
00506 static void dsp_x8_put_solidcolor(uint8_t const pix, uint8_t * dst, int const linesize){
00507     int k;
00508     for(k=0;k<8;k++){
00509         memset(dst,pix,8);
00510         dst+=linesize;
00511     }
00512 }
00513 
00514 static const int16_t quant_table[64] = {
00515     256, 256, 256, 256,  256, 256, 259, 262,
00516     265, 269, 272, 275,  278, 282, 285, 288,
00517     292, 295, 299, 303,  306, 310, 314, 317,
00518     321, 325, 329, 333,  337, 341, 345, 349,
00519     353, 358, 362, 366,  371, 375, 379, 384,
00520     389, 393, 398, 403,  408, 413, 417, 422,
00521     428, 433, 438, 443,  448, 454, 459, 465,
00522     470, 476, 482, 488,  493, 499, 505, 511
00523 };
00524 
00525 static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){
00526     MpegEncContext * const s= w->s;
00527 
00528     uint8_t * scantable;
00529     int final,run,level;
00530     int ac_mode,dc_mode,est_run,dc_level;
00531     int pos,n;
00532     int zeros_only;
00533     int use_quant_matrix;
00534     int sign;
00535 
00536     av_assert2(w->orient<12);
00537     s->dsp.clear_block(s->block[0]);
00538 
00539     if(chroma){
00540         dc_mode=2;
00541     }else{
00542         dc_mode=!!w->est_run;
00543     }
00544 
00545     if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1;
00546     n=0;
00547     zeros_only=0;
00548     if(!final){
00549         use_quant_matrix=w->use_quant_matrix;
00550         if(chroma){
00551             ac_mode = 1;
00552             est_run = 64;
00553         }else{
00554             if (w->raw_orient < 3){
00555                 use_quant_matrix = 0;
00556             }
00557             if(w->raw_orient > 4){
00558                 ac_mode = 0;
00559                 est_run = 64;
00560             }else{
00561                 if(w->est_run > 1){
00562                     ac_mode = 2;
00563                     est_run=w->est_run;
00564                 }else{
00565                     ac_mode = 3;
00566                     est_run = 64;
00567                 }
00568             }
00569         }
00570         x8_select_ac_table(w,ac_mode);
00571         
00572 
00573         scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated;
00574         pos=0;
00575         do {
00576             n++;
00577             if( n >= est_run ){
00578                 ac_mode=3;
00579                 x8_select_ac_table(w,3);
00580             }
00581 
00582             x8_get_ac_rlf(w,ac_mode,&run,&level,&final);
00583 
00584             pos+=run+1;
00585             if(pos>63){
00586                 
00587                 return -1;
00588             }
00589             level= (level+1) * w->dquant;
00590             level+= w->qsum;
00591 
00592             sign = - get_bits1(&s->gb);
00593             level = (level ^ sign) - sign;
00594 
00595             if(use_quant_matrix){
00596                 level = (level*quant_table[pos])>>8;
00597             }
00598             s->block[0][ scantable[pos] ]=level;
00599         }while(!final);
00600 
00601         s->block_last_index[0]=pos;
00602     }else{
00603         s->block_last_index[0]=0;
00604         if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){
00605             int32_t divide_quant= !chroma ? w->divide_quant_dc_luma:
00606                                             w->divide_quant_dc_chroma;
00607             int32_t dc_quant    = !chroma ? w->quant:
00608                                             w->quant_dc_chroma;
00609 
00610             
00611             dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13;
00612 
00613             dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3),
00614                                    s->dest[chroma], s->current_picture.f.linesize[!!chroma]);
00615 
00616             goto block_placed;
00617         }
00618         zeros_only = (dc_level == 0);
00619     }
00620     if(!chroma){
00621         s->block[0][0] = dc_level*w->quant;
00622     }else{
00623         s->block[0][0] = dc_level*w->quant_dc_chroma;
00624     }
00625 
00626     
00627     if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){
00628         int direction;
00629         
00630 
00631         direction= (0x6A017C>>(w->orient*2))&3;
00632         if (direction != 3){
00633             x8_ac_compensation(w, direction, s->block[0][0]);
00634         }
00635     }
00636 
00637     if(w->flat_dc){
00638         dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.f.linesize[!!chroma]);
00639     }else{
00640         w->dsp.spatial_compensation[w->orient]( s->edge_emu_buffer,
00641                                             s->dest[chroma],
00642                                             s->current_picture.f.linesize[!!chroma] );
00643     }
00644     if(!zeros_only)
00645         s->dsp.idct_add ( s->dest[chroma],
00646                           s->current_picture.f.linesize[!!chroma],
00647                           s->block[0] );
00648 
00649 block_placed:
00650 
00651     if(!chroma){
00652         x8_update_predictions(w,w->orient,n);
00653     }
00654 
00655     if(s->loop_filter){
00656         uint8_t* ptr = s->dest[chroma];
00657         int linesize = s->current_picture.f.linesize[!!chroma];
00658 
00659         if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){
00660             w->dsp.h_loop_filter(ptr, linesize, w->quant);
00661         }
00662         if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){
00663             w->dsp.v_loop_filter(ptr, linesize, w->quant);
00664         }
00665     }
00666     return 0;
00667 }
00668 
00669 static void x8_init_block_index(MpegEncContext *s){ 
00670 
00671 
00672     const int linesize   = s->current_picture.f.linesize[0];
00673     const int uvlinesize = s->current_picture.f.linesize[1];
00674 
00675     s->dest[0] = s->current_picture.f.data[0];
00676     s->dest[1] = s->current_picture.f.data[1];
00677     s->dest[2] = s->current_picture.f.data[2];
00678 
00679     s->dest[0] +=   s->mb_y        *   linesize << 3;
00680     s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;
00681     s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2;
00682 }
00683 
00690 av_cold void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s){
00691 
00692     w->s=s;
00693     x8_vlc_init();
00694     av_assert0(s->mb_width>0);
00695     w->prediction_table=av_mallocz(s->mb_width*2*2);
00696 
00697     ff_init_scantable(s->dsp.idct_permutation, &w->scantable[0], ff_wmv1_scantable[0]);
00698     ff_init_scantable(s->dsp.idct_permutation, &w->scantable[1], ff_wmv1_scantable[2]);
00699     ff_init_scantable(s->dsp.idct_permutation, &w->scantable[2], ff_wmv1_scantable[3]);
00700 
00701     ff_intrax8dsp_init(&w->dsp);
00702 }
00703 
00708 av_cold void ff_intrax8_common_end(IntraX8Context * w)
00709 {
00710     av_freep(&w->prediction_table);
00711 }
00712 
00724 
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     w->use_quant_matrix = get_bits1(&s->gb);
00729 
00730     w->dquant = dquant;
00731     w->quant  = dquant >> 1;
00732     w->qsum   = quant_offset;
00733 
00734     w->divide_quant_dc_luma = ((1<<16) + (w->quant>>1)) / w->quant;
00735     if(w->quant < 5){
00736         w->quant_dc_chroma =  w->quant;
00737         w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
00738     }else{
00739         w->quant_dc_chroma =  w->quant+((w->quant+3)>>3);
00740         w->divide_quant_dc_chroma = ((1<<16) + (w->quant_dc_chroma>>1)) / w->quant_dc_chroma;
00741     }
00742     x8_reset_vlc_tables(w);
00743 
00744     s->resync_mb_x=0;
00745     s->resync_mb_y=0;
00746 
00747     for(s->mb_y=0; s->mb_y < s->mb_height*2; s->mb_y++){
00748         x8_init_block_index(s);
00749         mb_xy=(s->mb_y>>1)*s->mb_stride;
00750 
00751         for(s->mb_x=0; s->mb_x < s->mb_width*2; s->mb_x++){
00752             x8_get_prediction(w);
00753             if(x8_setup_spatial_predictor(w,0)) goto error;
00754             if(x8_decode_intra_mb(w,0)) goto error;
00755 
00756             if( s->mb_x & s->mb_y & 1 ){
00757                 x8_get_prediction_chroma(w);
00758 
00759                 
00760 
00761                 x8_setup_spatial_predictor(w,1);
00762                 if(x8_decode_intra_mb(w,1)) goto error;
00763 
00764                 x8_setup_spatial_predictor(w,2);
00765                 if(x8_decode_intra_mb(w,2)) goto error;
00766 
00767                 s->dest[1]+= 8;
00768                 s->dest[2]+= 8;
00769 
00770                 
00771                 s->mbskip_table [mb_xy]=0;
00772                 s->mbintra_table[mb_xy]=1;
00773                 s->current_picture.f.qscale_table[mb_xy] = w->quant;
00774                 mb_xy++;
00775             }
00776             s->dest[0]+= 8;
00777         }
00778         if(s->mb_y&1){
00779             ff_draw_horiz_band(s, (s->mb_y-1)*8, 16);
00780         }
00781     }
00782 
00783 error:
00784     ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
00785                         (s->mb_x>>1)-1, (s->mb_y>>1)-1,
00786                         ER_MB_END );
00787     return 0;
00788 }