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