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 }