00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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];
00042 static VLC j_dc_vlc[2][8];
00043 static VLC j_orient_vlc[2][4];
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
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
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
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];
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 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 assert(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 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
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;
00289 c-=c>1;
00290
00291 e=get_bits(&s->gb,c);
00292 i=dc_index_offset[i]+(e>>1);
00293
00294 e= -(e & 1);
00295 (*level)= (i ^ e) - e;
00296 return 0;
00297 }
00298
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.f.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){
00320 w->flat_dc=1;
00321 sum+=9;
00322 w->predicted_dc = (sum*6899)>>17;
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
00358
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) );
00367
00368 w->raw_orient=0;
00369 if(w->edges&3){
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;
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
00389 w->est_run = w->prediction_table[!(s->mb_y&1)]>>2;
00390 w->orient = 1;
00391 return;
00392 case 2:
00393
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
00403 b= w->prediction_table[2*s->mb_x + !(s->mb_y&1) ];
00404 a= w->prediction_table[2*s->mb_x-2 + (s->mb_y&1) ];
00405 c= w->prediction_table[2*s->mb_x-2 + !(s->mb_y&1) ];
00406
00407 w->est_run = FFMIN(b,a);
00408
00409
00410
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
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
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);
00446 B(1,0) -= t;
00447 B(0,1) -= t;
00448
00449 t = T(487);
00450 B(2,0) -= t;
00451 B(0,2) -= t;
00452
00453 t = T(506);
00454 B(3,0) -= t;
00455 B(0,3) -= t;
00456
00457 t = T(135);
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);
00466 B(5,0) -= t;
00467 B(0,5) -= t;
00468
00469 t = T(61);
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);
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);
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;
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){
00551 use_quant_matrix=w->use_quant_matrix;
00552 if(chroma){
00553 ac_mode = 1;
00554 est_run = 64;
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
00574
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
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{
00605 s->block_last_index[0]=0;
00606 if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){
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
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.f.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
00629 if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){
00630 int direction;
00631
00632
00633 direction= (0x6A017C>>(w->orient*2))&3;
00634 if (direction != 3){
00635 x8_ac_compensation(w, direction, s->block[0][0]);
00636 }
00637 }
00638
00639 if(w->flat_dc){
00640 dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.f.linesize[!!chroma]);
00641 }else{
00642 s->dsp.x8_spatial_compensation[w->orient]( s->edge_emu_buffer,
00643 s->dest[chroma],
00644 s->current_picture.f.linesize[!!chroma] );
00645 }
00646 if(!zeros_only)
00647 s->dsp.idct_add ( s->dest[chroma],
00648 s->current_picture.f.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.f.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){
00672
00673
00674 const int linesize = s->current_picture.f.linesize[0];
00675 const int uvlinesize = s->current_picture.f.linesize[1];
00676
00677 s->dest[0] = s->current_picture.f.data[0];
00678 s->dest[1] = s->current_picture.f.data[1];
00679 s->dest[2] = s->current_picture.f.data[2];
00680
00681 s->dest[0] += s->mb_y * linesize << 3;
00682 s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;
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);
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
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
00761
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
00772 s->mbskip_table [mb_xy]=0;
00773 s->mbintra_table[mb_xy]=1;
00774 s->current_picture.f.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 }