1/* 2 * This file is part of FFmpeg. 3 * 4 * FFmpeg is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * FFmpeg is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with FFmpeg; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19/** 20 * @file 21 * @brief IntraX8 (J-Frame) subdecoder, used by WMV2 and VC-1 22 */ 23 24#include "libavutil/avassert.h" 25#include "avcodec.h" 26#include "error_resilience.h" 27#include "get_bits.h" 28#include "idctdsp.h" 29#include "mpegvideo.h" 30#include "msmpeg4data.h" 31#include "intrax8huf.h" 32#include "intrax8.h" 33#include "intrax8dsp.h" 34 35#define MAX_TABLE_DEPTH(table_bits, max_bits) ((max_bits+table_bits-1)/table_bits) 36 37#define DC_VLC_BITS 9 38#define AC_VLC_BITS 9 39#define OR_VLC_BITS 7 40 41#define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS) 42#define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS) 43#define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS) 44 45static VLC j_ac_vlc[2][2][8]; //[quant<13],[intra/inter],[select] 46static VLC j_dc_vlc[2][8]; //[quant], [select] 47static VLC j_orient_vlc[2][4]; //[quant], [select] 48 49static av_cold void x8_vlc_init(void){ 50 int i; 51 int offset = 0; 52 int sizeidx = 0; 53 static const uint16_t sizes[8*4 + 8*2 + 2 + 4] = { 54 576, 548, 582, 618, 546, 616, 560, 642, 55 584, 582, 704, 664, 512, 544, 656, 640, 56 512, 648, 582, 566, 532, 614, 596, 648, 57 586, 552, 584, 590, 544, 578, 584, 624, 58 59 528, 528, 526, 528, 536, 528, 526, 544, 60 544, 512, 512, 528, 528, 544, 512, 544, 61 62 128, 128, 128, 128, 128, 128}; 63 64 static VLC_TYPE table[28150][2]; 65 66#define init_ac_vlc(dst,src) \ 67 dst.table = &table[offset]; \ 68 dst.table_allocated = sizes[sizeidx]; \ 69 offset += sizes[sizeidx++]; \ 70 init_vlc(&dst, \ 71 AC_VLC_BITS,77, \ 72 &src[1],4,2, \ 73 &src[0],4,2, \ 74 INIT_VLC_USE_NEW_STATIC) 75//set ac tables 76 for(i=0;i<8;i++){ 77 init_ac_vlc( j_ac_vlc[0][0][i], x8_ac0_highquant_table[i][0] ); 78 init_ac_vlc( j_ac_vlc[0][1][i], x8_ac1_highquant_table[i][0] ); 79 init_ac_vlc( j_ac_vlc[1][0][i], x8_ac0_lowquant_table [i][0] ); 80 init_ac_vlc( j_ac_vlc[1][1][i], x8_ac1_lowquant_table [i][0] ); 81 } 82#undef init_ac_vlc 83 84//set dc tables 85#define init_dc_vlc(dst,src) \ 86 dst.table = &table[offset]; \ 87 dst.table_allocated = sizes[sizeidx]; \ 88 offset += sizes[sizeidx++]; \ 89 init_vlc(&dst, \ 90 DC_VLC_BITS,34, \ 91 &src[1],4,2, \ 92 &src[0],4,2, \ 93 INIT_VLC_USE_NEW_STATIC); 94 for(i=0;i<8;i++){ 95 init_dc_vlc( j_dc_vlc[0][i], x8_dc_highquant_table[i][0]); 96 init_dc_vlc( j_dc_vlc[1][i], x8_dc_lowquant_table [i][0]); 97 } 98#undef init_dc_vlc 99 100//set orient tables 101#define init_or_vlc(dst,src) \ 102 dst.table = &table[offset]; \ 103 dst.table_allocated = sizes[sizeidx]; \ 104 offset += sizes[sizeidx++]; \ 105 init_vlc(&dst, \ 106 OR_VLC_BITS,12, \ 107 &src[1],4,2, \ 108 &src[0],4,2, \ 109 INIT_VLC_USE_NEW_STATIC); 110 for(i=0;i<2;i++){ 111 init_or_vlc( j_orient_vlc[0][i], x8_orient_highquant_table[i][0]); 112 } 113 for(i=0;i<4;i++){ 114 init_or_vlc( j_orient_vlc[1][i], x8_orient_lowquant_table [i][0]) 115 } 116 if (offset != sizeof(table)/sizeof(VLC_TYPE)/2) 117 av_log(NULL, AV_LOG_ERROR, "table size %i does not match needed %i\n", (int)(sizeof(table)/sizeof(VLC_TYPE)/2), offset); 118} 119#undef init_or_vlc 120 121static void x8_reset_vlc_tables(IntraX8Context * w){ 122 memset(w->j_dc_vlc,0,sizeof(w->j_dc_vlc)); 123 memset(w->j_ac_vlc,0,sizeof(w->j_ac_vlc)); 124 w->j_orient_vlc=NULL; 125} 126 127static inline void x8_select_ac_table(IntraX8Context * const w , int mode){ 128 MpegEncContext * const s= w->s; 129 int table_index; 130 131 av_assert2(mode<4); 132 133 if( w->j_ac_vlc[mode] ) return; 134 135 table_index = get_bits(&s->gb, 3); 136 w->j_ac_vlc[mode] = &j_ac_vlc[w->quant<13][mode>>1][table_index];//2 modes use same tables 137 av_assert2(w->j_ac_vlc[mode]); 138} 139 140static inline int x8_get_orient_vlc(IntraX8Context * w){ 141 MpegEncContext * const s= w->s; 142 int table_index; 143 144 if(!w->j_orient_vlc ){ 145 table_index = get_bits(&s->gb, 1+(w->quant<13) ); 146 w->j_orient_vlc = &j_orient_vlc[w->quant<13][table_index]; 147 } 148 149 return get_vlc2(&s->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD); 150} 151 152#define extra_bits(eb) (eb) 153#define extra_run (0xFF<<8) 154#define extra_level (0x00<<8) 155#define run_offset(r) ((r)<<16) 156#define level_offset(l) ((l)<<24) 157static const uint32_t ac_decode_table[]={ 158 /*46*/ extra_bits(3) | extra_run | run_offset(16) | level_offset( 0), 159 /*47*/ extra_bits(3) | extra_run | run_offset(24) | level_offset( 0), 160 /*48*/ extra_bits(2) | extra_run | run_offset( 4) | level_offset( 1), 161 /*49*/ extra_bits(3) | extra_run | run_offset( 8) | level_offset( 1), 162 163 /*50*/ extra_bits(5) | extra_run | run_offset(32) | level_offset( 0), 164 /*51*/ extra_bits(4) | extra_run | run_offset(16) | level_offset( 1), 165 166 /*52*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4), 167 /*53*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 8), 168 /*54*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset(12), 169 /*55*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(16), 170 /*56*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(24), 171 172 /*57*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3), 173 /*58*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7), 174 175 /*59*/ extra_bits(2) | extra_run | run_offset(16) | level_offset( 0), 176 /*60*/ extra_bits(2) | extra_run | run_offset(20) | level_offset( 0), 177 /*61*/ extra_bits(2) | extra_run | run_offset(24) | level_offset( 0), 178 /*62*/ extra_bits(2) | extra_run | run_offset(28) | level_offset( 0), 179 /*63*/ extra_bits(4) | extra_run | run_offset(32) | level_offset( 0), 180 /*64*/ extra_bits(4) | extra_run | run_offset(48) | level_offset( 0), 181 182 /*65*/ extra_bits(2) | extra_run | run_offset( 4) | level_offset( 1), 183 /*66*/ extra_bits(3) | extra_run | run_offset( 8) | level_offset( 1), 184 /*67*/ extra_bits(4) | extra_run | run_offset(16) | level_offset( 1), 185 186 /*68*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4), 187 /*69*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset( 8), 188 /*70*/ extra_bits(4) | extra_level | run_offset( 0) | level_offset(16), 189 190 /*71*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3), 191 /*72*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7), 192}; 193//extra_bits = 3bits; extra_run/level = 1 bit; run_offset = 6bits; level_offset = 5 bits; 194#undef extra_bits 195#undef extra_run 196#undef extra_level 197#undef run_offset 198#undef level_offset 199 200static void x8_get_ac_rlf(IntraX8Context * const w, const int mode, 201 int * const run, int * const level, int * const final){ 202 MpegEncContext * const s= w->s; 203 int i,e; 204 205// x8_select_ac_table(w,mode); 206 i = get_vlc2(&s->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD); 207 208 if(i<46){ //[0-45] 209 int t,l; 210 if(i<0){ 211 (*level)=(*final)=//prevent 'may be used unilitialized' 212 (*run)=64;//this would cause error exit in the ac loop 213 return; 214 } 215 216 (*final) = t = (i>22); 217 i-=23*t; 218/* 219 i== 0-15 r=0-15 l=0 ;r=i& %01111 220 i==16-19 r=0-3 l=1 ;r=i& %00011 221 i==20-21 r=0-1 l=2 ;r=i& %00001 222 i==22 r=0 l=3 ;r=i& %00000 223l=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 224t=lut_mask[l]={0x0f,0x03,0x01,0x00}[l]; as i<256 the higher bits do not matter */ 225 l=(0xE50000>>(i&(0x1E)))&3;/*0x1E or (~1) or ((i>>1)<<1)*/ 226 t=(0x01030F>>(l<<3)); 227 228 (*run) = i&t; 229 (*level) = l; 230 }else if(i<73){//[46-72] 231 uint32_t sm; 232 uint32_t mask; 233 234 i-=46; 235 sm=ac_decode_table[i]; 236 237 e=get_bits(&s->gb,sm&0xF);sm>>=8;//3bits 238 mask=sm&0xff;sm>>=8; //1bit 239 240 (*run) =(sm&0xff) + (e&( mask));//6bits 241 (*level)=(sm>>8) + (e&(~mask));//5bits 242 (*final)=i>(58-46); 243 }else if(i<75){//[73-74] 244 static const uint8_t crazy_mix_runlevel[32]={ 245 0x22,0x32,0x33,0x53,0x23,0x42,0x43,0x63, 246 0x24,0x52,0x34,0x73,0x25,0x62,0x44,0x83, 247 0x26,0x72,0x35,0x54,0x27,0x82,0x45,0x64, 248 0x28,0x92,0x36,0x74,0x29,0xa2,0x46,0x84}; 249 250 (*final)=!(i&1); 251 e=get_bits(&s->gb,5);//get the extra bits 252 (*run) =crazy_mix_runlevel[e]>>4; 253 (*level)=crazy_mix_runlevel[e]&0x0F; 254 }else{ 255 (*level)=get_bits( &s->gb, 7-3*(i&1)); 256 (*run) =get_bits( &s->gb, 6); 257 (*final)=get_bits1(&s->gb); 258 } 259 return; 260} 261 262//static const uint8_t dc_extra_sbits[] ={0, 1,1, 1,1, 2,2, 3,3, 4,4, 5,5, 6,6, 7,7 }; 263static const uint8_t dc_index_offset[] ={ 0, 1,2, 3,4, 5,7, 9,13, 17,25, 33,49, 65,97, 129,193}; 264 265static int x8_get_dc_rlf(IntraX8Context * const w,int const mode, int * const level, int * const final){ 266 MpegEncContext * const s= w->s; 267 int i,e,c; 268 269 av_assert2(mode<3); 270 if( !w->j_dc_vlc[mode] ) { 271 int table_index; 272 table_index = get_bits(&s->gb, 3); 273 //4 modes, same table 274 w->j_dc_vlc[mode]= &j_dc_vlc[w->quant<13][table_index]; 275 } 276 277 i=get_vlc2(&s->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD); 278 279 /*(i>=17) {i-=17;final=1;}*/ 280 c= i>16; 281 (*final)=c; 282 i-=17*c; 283 284 if(i<=0){ 285 (*level)=0; 286 return -i; 287 } 288 c=(i+1)>>1;//hackish way to calculate dc_extra_sbits[] 289 c-=c>1; 290 291 e=get_bits(&s->gb,c);//get the extra bits 292 i=dc_index_offset[i]+(e>>1); 293 294 e= -(e & 1);//0,0xffffff 295 (*level)= (i ^ e) - e;// (i^0)-0 , (i^0xff)-(-1) 296 return 0; 297} 298//end of huffman 299 300static int x8_setup_spatial_predictor(IntraX8Context * const w, const int chroma){ 301 MpegEncContext * const s= w->s; 302 int range; 303 int sum; 304 int quant; 305 306 w->dsp.setup_spatial_compensation(s->dest[chroma], s->edge_emu_buffer, 307 s->current_picture.f->linesize[chroma>0], 308 &range, &sum, w->edges); 309 if(chroma){ 310 w->orient=w->chroma_orient; 311 quant=w->quant_dc_chroma; 312 }else{ 313 quant=w->quant; 314 } 315 316 w->flat_dc=0; 317 if(range < quant || range < 3){ 318 w->orient=0; 319 if(range < 3){//yep you read right, a +-1 idct error may break decoding! 320 w->flat_dc=1; 321 sum+=9; 322 w->predicted_dc = (sum*6899)>>17;//((1<<17)+9)/(8+8+1+2)=6899 323 } 324 } 325 if(chroma) 326 return 0; 327 328 av_assert2(w->orient < 3); 329 if(range < 2*w->quant){ 330 if( (w->edges&3) == 0){ 331 if(w->orient==1) w->orient=11; 332 if(w->orient==2) w->orient=10; 333 }else{ 334 w->orient=0; 335 } 336 w->raw_orient=0; 337 }else{ 338 static const uint8_t prediction_table[3][12]={ 339 {0,8,4, 10,11, 2,6,9,1,3,5,7}, 340 {4,0,8, 11,10, 3,5,2,6,9,1,7}, 341 {8,0,4, 10,11, 1,7,2,6,9,3,5} 342 }; 343 w->raw_orient=x8_get_orient_vlc(w); 344 if(w->raw_orient<0) return -1; 345 av_assert2(w->raw_orient < 12 ); 346 av_assert2(w->orient<3); 347 w->orient=prediction_table[w->orient][w->raw_orient]; 348 } 349 return 0; 350} 351 352static void x8_update_predictions(IntraX8Context * const w, const int orient, const int est_run ){ 353 MpegEncContext * const s= w->s; 354 355 w->prediction_table[s->mb_x*2+(s->mb_y&1)] = (est_run<<2) + 1*(orient==4) + 2*(orient==8); 356/* 357 y=2n+0 ->//0 2 4 358 y=2n+1 ->//1 3 5 359*/ 360} 361static void x8_get_prediction_chroma(IntraX8Context * const w){ 362 MpegEncContext * const s= w->s; 363 364 w->edges = 1*( !(s->mb_x>>1) ); 365 w->edges|= 2*( !(s->mb_y>>1) ); 366 w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );//mb_x for chroma would always be odd 367 368 w->raw_orient=0; 369 if(w->edges&3){//lut_co[8]={inv,4,8,8, inv,4,8,8}<- =>{1,1,0,0;1,1,0,0} => 0xCC 370 w->chroma_orient=4<<((0xCC>>w->edges)&1); 371 return; 372 } 373 w->chroma_orient = (w->prediction_table[2*s->mb_x-2] & 0x03)<<2;//block[x-1][y|1-1)] 374} 375 376static void x8_get_prediction(IntraX8Context * const w){ 377 MpegEncContext * const s= w->s; 378 int a,b,c,i; 379 380 w->edges = 1*( !s->mb_x ); 381 w->edges|= 2*( !s->mb_y ); 382 w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) ); 383 384 switch(w->edges&3){ 385 case 0: 386 break; 387 case 1: 388 //take the one from the above block[0][y-1] 389 w->est_run = w->prediction_table[!(s->mb_y&1)]>>2; 390 w->orient = 1; 391 return; 392 case 2: 393 //take the one from the previous block[x-1][0] 394 w->est_run = w->prediction_table[2*s->mb_x-2]>>2; 395 w->orient = 2; 396 return; 397 case 3: 398 w->est_run = 16; 399 w->orient = 0; 400 return; 401 } 402 //no edge cases 403 b= w->prediction_table[2*s->mb_x + !(s->mb_y&1) ];//block[x ][y-1] 404 a= w->prediction_table[2*s->mb_x-2 + (s->mb_y&1) ];//block[x-1][y ] 405 c= w->prediction_table[2*s->mb_x-2 + !(s->mb_y&1) ];//block[x-1][y-1] 406 407 w->est_run = FFMIN(b,a); 408 /* This condition has nothing to do with w->edges, even if it looks 409 similar it would trigger if e.g. x=3;y=2; 410 I guess somebody wrote something wrong and it became standard. */ 411 if( (s->mb_x & s->mb_y) != 0 ) w->est_run=FFMIN(c,w->est_run); 412 w->est_run>>=2; 413 414 a&=3; 415 b&=3; 416 c&=3; 417 418 i=( 0xFFEAF4C4>>(2*b+8*a) )&3; 419 if(i!=3) w->orient=i; 420 else w->orient=( 0xFFEAD8>>(2*c+8*(w->quant>12)) )&3; 421/* 422lut1[b][a]={ 423->{0, 1, 0, pad}, 424 {0, 1, X, pad}, 425 {2, 2, 2, pad}} 426 pad 2 2 2; pad X 1 0; pad 0 1 0 <- 427-> 11 10 '10 10 '11 11'01 00 '11 00'01 00=>0xEAF4C4 428 429lut2[q>12][c]={ 430 ->{0,2,1,pad}, 431 {2,2,2,pad}} 432 pad 2 2 2; pad 1 2 0 <- 433-> 11 10'10 10 '11 01'10 00=>0xEAD8 434*/ 435} 436 437 438static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){ 439 MpegEncContext * const s= w->s; 440 int t; 441#define B(x,y) s->block[0][w->idct_permutation[(x)+(y)*8]] 442#define T(x) ((x) * dc_level + 0x8000) >> 16; 443 switch(direction){ 444 case 0: 445 t = T(3811);//h 446 B(1,0) -= t; 447 B(0,1) -= t; 448 449 t = T(487);//e 450 B(2,0) -= t; 451 B(0,2) -= t; 452 453 t = T(506);//f 454 B(3,0) -= t; 455 B(0,3) -= t; 456 457 t = T(135);//c 458 B(4,0) -= t; 459 B(0,4) -= t; 460 B(2,1) += t; 461 B(1,2) += t; 462 B(3,1) += t; 463 B(1,3) += t; 464 465 t = T(173);//d 466 B(5,0) -= t; 467 B(0,5) -= t; 468 469 t = T(61);//b 470 B(6,0) -= t; 471 B(0,6) -= t; 472 B(5,1) += t; 473 B(1,5) += t; 474 475 t = T(42); //a 476 B(7,0) -= t; 477 B(0,7) -= t; 478 B(4,1) += t; 479 B(1,4) += t; 480 B(4,4) += t; 481 482 t = T(1084);//g 483 B(1,1) += t; 484 485 s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8); 486 break; 487 case 1: 488 B(0,1) -= T(6269); 489 B(0,3) -= T( 708); 490 B(0,5) -= T( 172); 491 B(0,7) -= T( 73); 492 493 s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8); 494 break; 495 case 2: 496 B(1,0) -= T(6269); 497 B(3,0) -= T( 708); 498 B(5,0) -= T( 172); 499 B(7,0) -= T( 73); 500 501 s->block_last_index[0] = FFMAX(s->block_last_index[0], 7); 502 break; 503 } 504#undef B 505#undef T 506} 507 508static void dsp_x8_put_solidcolor(uint8_t const pix, uint8_t * dst, int const linesize){ 509 int k; 510 for(k=0;k<8;k++){ 511 memset(dst,pix,8); 512 dst+=linesize; 513 } 514} 515 516static const int16_t quant_table[64] = { 517 256, 256, 256, 256, 256, 256, 259, 262, 518 265, 269, 272, 275, 278, 282, 285, 288, 519 292, 295, 299, 303, 306, 310, 314, 317, 520 321, 325, 329, 333, 337, 341, 345, 349, 521 353, 358, 362, 366, 371, 375, 379, 384, 522 389, 393, 398, 403, 408, 413, 417, 422, 523 428, 433, 438, 443, 448, 454, 459, 465, 524 470, 476, 482, 488, 493, 499, 505, 511 525}; 526 527static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){ 528 MpegEncContext * const s= w->s; 529 530 uint8_t * scantable; 531 int final,run,level; 532 int ac_mode,dc_mode,est_run,dc_level; 533 int pos,n; 534 int zeros_only; 535 int use_quant_matrix; 536 int sign; 537 538 av_assert2(w->orient<12); 539 s->bdsp.clear_block(s->block[0]); 540 541 if(chroma){ 542 dc_mode=2; 543 }else{ 544 dc_mode=!!w->est_run;//0,1 545 } 546 547 if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1; 548 n=0; 549 zeros_only=0; 550 if(!final){//decode ac 551 use_quant_matrix=w->use_quant_matrix; 552 if(chroma){ 553 ac_mode = 1; 554 est_run = 64;//not used 555 }else{ 556 if (w->raw_orient < 3){ 557 use_quant_matrix = 0; 558 } 559 if(w->raw_orient > 4){ 560 ac_mode = 0; 561 est_run = 64; 562 }else{ 563 if(w->est_run > 1){ 564 ac_mode = 2; 565 est_run=w->est_run; 566 }else{ 567 ac_mode = 3; 568 est_run = 64; 569 } 570 } 571 } 572 x8_select_ac_table(w,ac_mode); 573 /*scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};<- 574 -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>0x928548 */ 575 scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated; 576 pos=0; 577 do { 578 n++; 579 if( n >= est_run ){ 580 ac_mode=3; 581 x8_select_ac_table(w,3); 582 } 583 584 x8_get_ac_rlf(w,ac_mode,&run,&level,&final); 585 586 pos+=run+1; 587 if(pos>63){ 588 //this also handles vlc error in x8_get_ac_rlf 589 return -1; 590 } 591 level= (level+1) * w->dquant; 592 level+= w->qsum; 593 594 sign = - get_bits1(&s->gb); 595 level = (level ^ sign) - sign; 596 597 if(use_quant_matrix){ 598 level = (level*quant_table[pos])>>8; 599 } 600 s->block[0][ scantable[pos] ]=level; 601 }while(!final); 602 603 s->block_last_index[0]=pos; 604 }else{//DC only 605 s->block_last_index[0]=0; 606 if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){//[-1;1] 607 int32_t divide_quant= !chroma ? w->divide_quant_dc_luma: 608 w->divide_quant_dc_chroma; 609 int32_t dc_quant = !chroma ? w->quant: 610 w->quant_dc_chroma; 611 612 //original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding 613 dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13; 614 615 dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3), 616 s->dest[chroma], s->current_picture.f->linesize[!!chroma]); 617 618 goto block_placed; 619 } 620 zeros_only = (dc_level == 0); 621 } 622 if(!chroma){ 623 s->block[0][0] = dc_level*w->quant; 624 }else{ 625 s->block[0][0] = dc_level*w->quant_dc_chroma; 626 } 627 628 //there is !zero_only check in the original, but dc_level check is enough 629 if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){ 630 int direction; 631 /*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<- 632 -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */ 633 direction= (0x6A017C>>(w->orient*2))&3; 634 if (direction != 3){ 635 x8_ac_compensation(w, direction, s->block[0][0]);//modify block_last[] 636 } 637 } 638 639 if(w->flat_dc){ 640 dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.f->linesize[!!chroma]); 641 }else{ 642 w->dsp.spatial_compensation[w->orient]( s->edge_emu_buffer, 643 s->dest[chroma], 644 s->current_picture.f->linesize[!!chroma] ); 645 } 646 if(!zeros_only) 647 w->wdsp.idct_add(s->dest[chroma], 648 s->current_picture.f->linesize[!!chroma], 649 s->block[0]); 650 651block_placed: 652 653 if(!chroma){ 654 x8_update_predictions(w,w->orient,n); 655 } 656 657 if(s->loop_filter){ 658 uint8_t* ptr = s->dest[chroma]; 659 int linesize = s->current_picture.f->linesize[!!chroma]; 660 661 if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){ 662 w->dsp.h_loop_filter(ptr, linesize, w->quant); 663 } 664 if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){ 665 w->dsp.v_loop_filter(ptr, linesize, w->quant); 666 } 667 } 668 return 0; 669} 670 671static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_* 672//not s->linesize as this would be wrong for field pics 673//not that IntraX8 has interlacing support ;) 674 const int linesize = s->current_picture.f->linesize[0]; 675 const int uvlinesize = s->current_picture.f->linesize[1]; 676 677 s->dest[0] = s->current_picture.f->data[0]; 678 s->dest[1] = s->current_picture.f->data[1]; 679 s->dest[2] = s->current_picture.f->data[2]; 680 681 s->dest[0] += s->mb_y * linesize << 3; 682 s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows 683 s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2; 684} 685 686/** 687 * Initialize IntraX8 frame decoder. 688 * Requires valid MpegEncContext with valid s->mb_width before calling. 689 * @param w pointer to IntraX8Context 690 * @param s pointer to MpegEncContext of the parent codec 691 */ 692av_cold void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s){ 693 694 w->s=s; 695 x8_vlc_init(); 696 av_assert0(s->mb_width>0); 697 w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb 698 699 ff_wmv2dsp_init(&w->wdsp); 700 ff_init_scantable_permutation(w->idct_permutation, 701 w->wdsp.idct_perm); 702 703 ff_init_scantable(w->idct_permutation, &w->scantable[0], ff_wmv1_scantable[0]); 704 ff_init_scantable(w->idct_permutation, &w->scantable[1], ff_wmv1_scantable[2]); 705 ff_init_scantable(w->idct_permutation, &w->scantable[2], ff_wmv1_scantable[3]); 706 707 ff_intrax8dsp_init(&w->dsp); 708} 709 710/** 711 * Destroy IntraX8 frame structure. 712 * @param w pointer to IntraX8Context 713 */ 714av_cold void ff_intrax8_common_end(IntraX8Context * w) 715{ 716 av_freep(&w->prediction_table); 717} 718 719/** 720 * Decode single IntraX8 frame. 721 * The parent codec must fill s->loopfilter and s->gb (bitstream). 722 * The parent codec must call MPV_frame_start(), ff_er_frame_start() before calling this function. 723 * The parent codec must call ff_er_frame_end(), MPV_frame_end() after calling this function. 724 * This function does not use MPV_decode_mb(). 725 * lowres decoding is theoretically impossible. 726 * @param w pointer to IntraX8Context 727 * @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1. 728 * @param quant_offset offset away from zero 729 */ 730int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){ 731 MpegEncContext * const s= w->s; 732 int mb_xy; 733 w->use_quant_matrix = get_bits1(&s->gb); 734 735 w->dquant = dquant; 736 w->quant = dquant >> 1; 737 w->qsum = quant_offset; 738 739 w->divide_quant_dc_luma = ((1<<16) + (w->quant>>1)) / w->quant; 740 if(w->quant < 5){ 741 w->quant_dc_chroma = w->quant; 742 w->divide_quant_dc_chroma = w->divide_quant_dc_luma; 743 }else{ 744 w->quant_dc_chroma = w->quant+((w->quant+3)>>3); 745 w->divide_quant_dc_chroma = ((1<<16) + (w->quant_dc_chroma>>1)) / w->quant_dc_chroma; 746 } 747 x8_reset_vlc_tables(w); 748 749 s->resync_mb_x=0; 750 s->resync_mb_y=0; 751 752 for(s->mb_y=0; s->mb_y < s->mb_height*2; s->mb_y++){ 753 x8_init_block_index(s); 754 mb_xy=(s->mb_y>>1)*s->mb_stride; 755 756 for(s->mb_x=0; s->mb_x < s->mb_width*2; s->mb_x++){ 757 x8_get_prediction(w); 758 if(x8_setup_spatial_predictor(w,0)) goto error; 759 if(x8_decode_intra_mb(w,0)) goto error; 760 761 if( s->mb_x & s->mb_y & 1 ){ 762 x8_get_prediction_chroma(w); 763 764 /*when setting up chroma, no vlc is read, 765 so no error condition can be reached*/ 766 x8_setup_spatial_predictor(w,1); 767 if(x8_decode_intra_mb(w,1)) goto error; 768 769 x8_setup_spatial_predictor(w,2); 770 if(x8_decode_intra_mb(w,2)) goto error; 771 772 s->dest[1]+= 8; 773 s->dest[2]+= 8; 774 775 /*emulate MB info in the relevant tables*/ 776 s->mbskip_table [mb_xy]=0; 777 s->mbintra_table[mb_xy]=1; 778 s->current_picture.qscale_table[mb_xy] = w->quant; 779 mb_xy++; 780 } 781 s->dest[0]+= 8; 782 } 783 if(s->mb_y&1){ 784 ff_mpeg_draw_horiz_band(s, (s->mb_y-1)*8, 16); 785 } 786 } 787 788error: 789 ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, 790 (s->mb_x>>1)-1, (s->mb_y>>1)-1, 791 ER_MB_END ); 792 return 0; 793} 794