libavcodec/intrax8.c

Go to the documentation of this file.
00001 /*
00002  * This file is part of FFmpeg.
00003  *
00004  * FFmpeg is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * FFmpeg is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with FFmpeg; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00017  */
00018 
00024 #include "avcodec.h"
00025 #include "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 }

Generated on Fri Oct 26 02:35:37 2012 for FFmpeg by doxygen 1.5.8

AltStyle によって変換されたページ (->オリジナル) /