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