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 "get_bits.h"
26 #include "mpegvideo.h"
27 #include "msmpeg4data.h"
28 #include "intrax8huf.h"
29 #include "intrax8.h"
30 #include "intrax8dsp.h"
31 
32 #define MAX_TABLE_DEPTH(table_bits, max_bits) ((max_bits+table_bits-1)/table_bits)
33 
34 #define DC_VLC_BITS 9
35 #define AC_VLC_BITS 9
36 #define OR_VLC_BITS 7
37 
38 #define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS)
39 #define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
40 #define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS)
41 
42 static VLC j_ac_vlc[2][2][8]; //[quant<13],[intra/inter],[select]
43 static VLC j_dc_vlc[2][8]; //[quant], [select]
44 static VLC j_orient_vlc[2][4]; //[quant], [select]
45 
46 static av_cold void x8_vlc_init(void){
47  int i;
48  int offset = 0;
49  int sizeidx = 0;
50  static const uint16_t sizes[8*4 + 8*2 + 2 + 4] = {
51  576, 548, 582, 618, 546, 616, 560, 642,
52  584, 582, 704, 664, 512, 544, 656, 640,
53  512, 648, 582, 566, 532, 614, 596, 648,
54  586, 552, 584, 590, 544, 578, 584, 624,
55 
56  528, 528, 526, 528, 536, 528, 526, 544,
57  544, 512, 512, 528, 528, 544, 512, 544,
58 
59  128, 128, 128, 128, 128, 128};
60 
61  static VLC_TYPE table[28150][2];
62 
63 #define init_ac_vlc(dst,src) \
64  dst.table = &table[offset]; \
65  dst.table_allocated = sizes[sizeidx]; \
66  offset += sizes[sizeidx++]; \
67  init_vlc(&dst, \
68  AC_VLC_BITS,77, \
69  &src[1],4,2, \
70  &src[0],4,2, \
71  INIT_VLC_USE_NEW_STATIC)
72 //set ac tables
73  for(i=0;i<8;i++){
74  init_ac_vlc( j_ac_vlc[0][0][i], x8_ac0_highquant_table[i][0] );
75  init_ac_vlc( j_ac_vlc[0][1][i], x8_ac1_highquant_table[i][0] );
76  init_ac_vlc( j_ac_vlc[1][0][i], x8_ac0_lowquant_table [i][0] );
77  init_ac_vlc( j_ac_vlc[1][1][i], x8_ac1_lowquant_table [i][0] );
78  }
79 #undef init_ac_vlc
80 
81 //set dc tables
82 #define init_dc_vlc(dst,src) \
83  dst.table = &table[offset]; \
84  dst.table_allocated = sizes[sizeidx]; \
85  offset += sizes[sizeidx++]; \
86  init_vlc(&dst, \
87  DC_VLC_BITS,34, \
88  &src[1],4,2, \
89  &src[0],4,2, \
90  INIT_VLC_USE_NEW_STATIC);
91  for(i=0;i<8;i++){
92  init_dc_vlc( j_dc_vlc[0][i], x8_dc_highquant_table[i][0]);
93  init_dc_vlc( j_dc_vlc[1][i], x8_dc_lowquant_table [i][0]);
94  }
95 #undef init_dc_vlc
96 
97 //set orient tables
98 #define init_or_vlc(dst,src) \
99  dst.table = &table[offset]; \
100  dst.table_allocated = sizes[sizeidx]; \
101  offset += sizes[sizeidx++]; \
102  init_vlc(&dst, \
103  OR_VLC_BITS,12, \
104  &src[1],4,2, \
105  &src[0],4,2, \
106  INIT_VLC_USE_NEW_STATIC);
107  for(i=0;i<2;i++){
108  init_or_vlc( j_orient_vlc[0][i], x8_orient_highquant_table[i][0]);
109  }
110  for(i=0;i<4;i++){
111  init_or_vlc( j_orient_vlc[1][i], x8_orient_lowquant_table [i][0])
112  }
113  if (offset != sizeof(table)/sizeof(VLC_TYPE)/2)
114  av_log(NULL, AV_LOG_ERROR, "table size %i does not match needed %i\n", (int)(sizeof(table)/sizeof(VLC_TYPE)/2), offset);
115 }
116 #undef init_or_vlc
117 
119  memset(w->j_dc_vlc,0,sizeof(w->j_dc_vlc));
120  memset(w->j_ac_vlc,0,sizeof(w->j_ac_vlc));
121  w->j_orient_vlc=NULL;
122 }
123 
124 static inline void x8_select_ac_table(IntraX8Context * const w , int mode){
125  MpegEncContext * const s= w->s;
126  int table_index;
127 
128  assert(mode<4);
129 
130  if( w->j_ac_vlc[mode] ) return;
131 
132  table_index = get_bits(&s->gb, 3);
133  w->j_ac_vlc[mode] = &j_ac_vlc[w->quant<13][mode>>1][table_index];//2 modes use same tables
134  assert(w->j_ac_vlc[mode]);
135 }
136 
137 static inline int x8_get_orient_vlc(IntraX8Context * w){
138  MpegEncContext * const s= w->s;
139  int table_index;
140 
141  if(!w->j_orient_vlc ){
142  table_index = get_bits(&s->gb, 1+(w->quant<13) );
143  w->j_orient_vlc = &j_orient_vlc[w->quant<13][table_index];
144  }
145  assert(w->j_orient_vlc);
146  assert(w->j_orient_vlc->table);
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  assert(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  assert(w->j_dc_vlc);
276  assert(w->j_dc_vlc[mode]->table);
277 
278  i=get_vlc2(&s->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD);
279 
280  /*(i>=17) {i-=17;final=1;}*/
281  c= i>16;
282  (*final)=c;
283  i-=17*c;
284 
285  if(i<=0){
286  (*level)=0;
287  return -i;
288  }
289  c=(i+1)>>1;//hackish way to calculate dc_extra_sbits[]
290  c-=c>1;
291 
292  e=get_bits(&s->gb,c);//get the extra bits
293  i=dc_index_offset[i]+(e>>1);
294 
295  e= -(e & 1);//0,0xffffff
296  (*level)= (i ^ e) - e;// (i^0)-0 , (i^0xff)-(-1)
297  return 0;
298 }
299 //end of huffman
300 
301 static int x8_setup_spatial_predictor(IntraX8Context * const w, const int chroma){
302  MpegEncContext * const s= w->s;
303  int range;
304  int sum;
305  int quant;
306 
308  s->current_picture.f.linesize[chroma>0],
309  &range, &sum, w->edges);
310  if(chroma){
311  w->orient=w->chroma_orient;
312  quant=w->quant_dc_chroma;
313  }else{
314  quant=w->quant;
315  }
316 
317  w->flat_dc=0;
318  if(range < quant || range < 3){
319  w->orient=0;
320  if(range < 3){//yep you read right, a +-1 idct error may break decoding!
321  w->flat_dc=1;
322  sum+=9;
323  w->predicted_dc = (sum*6899)>>17;//((1<<17)+9)/(8+8+1+2)=6899
324  }
325  }
326  if(chroma)
327  return 0;
328 
329  assert(w->orient < 3);
330  if(range < 2*w->quant){
331  if( (w->edges&3) == 0){
332  if(w->orient==1) w->orient=11;
333  if(w->orient==2) w->orient=10;
334  }else{
335  w->orient=0;
336  }
337  w->raw_orient=0;
338  }else{
339  static const uint8_t prediction_table[3][12]={
340  {0,8,4, 10,11, 2,6,9,1,3,5,7},
341  {4,0,8, 11,10, 3,5,2,6,9,1,7},
342  {8,0,4, 10,11, 1,7,2,6,9,3,5}
343  };
345  if(w->raw_orient<0) return -1;
346  assert(w->raw_orient < 12 );
347  assert(w->orient<3);
348  w->orient=prediction_table[w->orient][w->raw_orient];
349  }
350  return 0;
351 }
352 
353 static void x8_update_predictions(IntraX8Context * const w, const int orient, const int est_run ){
354  MpegEncContext * const s= w->s;
355 
356  w->prediction_table[s->mb_x*2+(s->mb_y&1)] = (est_run<<2) + 1*(orient==4) + 2*(orient==8);
357 /*
358  y=2n+0 ->//0 2 4
359  y=2n+1 ->//1 3 5
360 */
361 }
363  MpegEncContext * const s= w->s;
364 
365  w->edges = 1*( !(s->mb_x>>1) );
366  w->edges|= 2*( !(s->mb_y>>1) );
367  w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );//mb_x for chroma would always be odd
368 
369  w->raw_orient=0;
370  if(w->edges&3){//lut_co[8]={inv,4,8,8, inv,4,8,8}<- =>{1,1,0,0;1,1,0,0} => 0xCC
371  w->chroma_orient=4<<((0xCC>>w->edges)&1);
372  return;
373  }
374  w->chroma_orient = (w->prediction_table[2*s->mb_x-2] & 0x03)<<2;//block[x-1][y|1-1)]
375 }
376 
377 static void x8_get_prediction(IntraX8Context * const w){
378  MpegEncContext * const s= w->s;
379  int a,b,c,i;
380 
381  w->edges = 1*( !s->mb_x );
382  w->edges|= 2*( !s->mb_y );
383  w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );
384 
385  switch(w->edges&3){
386  case 0:
387  break;
388  case 1:
389  //take the one from the above block[0][y-1]
390  w->est_run = w->prediction_table[!(s->mb_y&1)]>>2;
391  w->orient = 1;
392  return;
393  case 2:
394  //take the one from the previous block[x-1][0]
395  w->est_run = w->prediction_table[2*s->mb_x-2]>>2;
396  w->orient = 2;
397  return;
398  case 3:
399  w->est_run = 16;
400  w->orient = 0;
401  return;
402  }
403  //no edge cases
404  b= w->prediction_table[2*s->mb_x + !(s->mb_y&1) ];//block[x ][y-1]
405  a= w->prediction_table[2*s->mb_x-2 + (s->mb_y&1) ];//block[x-1][y ]
406  c= w->prediction_table[2*s->mb_x-2 + !(s->mb_y&1) ];//block[x-1][y-1]
407 
408  w->est_run = FFMIN(b,a);
409  /* This condition has nothing to do with w->edges, even if it looks
410  similar it would trigger if e.g. x=3;y=2;
411  I guess somebody wrote something wrong and it became standard. */
412  if( (s->mb_x & s->mb_y) != 0 ) w->est_run=FFMIN(c,w->est_run);
413  w->est_run>>=2;
414 
415  a&=3;
416  b&=3;
417  c&=3;
418 
419  i=( 0xFFEAF4C4>>(2*b+8*a) )&3;
420  if(i!=3) w->orient=i;
421  else w->orient=( 0xFFEAD8>>(2*c+8*(w->quant>12)) )&3;
422 /*
423 lut1[b][a]={
424 ->{0, 1, 0, pad},
425  {0, 1, X, pad},
426  {2, 2, 2, pad}}
427  pad 2 2 2; pad X 1 0; pad 0 1 0 <-
428 -> 11 10 '10 10 '11 11'01 00 '11 00'01 00=>0xEAF4C4
429 
430 lut2[q>12][c]={
431  ->{0,2,1,pad},
432  {2,2,2,pad}}
433  pad 2 2 2; pad 1 2 0 <-
434 -> 11 10'10 10 '11 01'10 00=>0xEAD8
435 */
436 }
437 
438 
439 static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){
440  MpegEncContext * const s= w->s;
441  int t;
442 #define B(x,y) s->block[0][s->dsp.idct_permutation[(x)+(y)*8]]
443 #define T(x) ((x) * dc_level + 0x8000) >> 16;
444  switch(direction){
445  case 0:
446  t = T(3811);//h
447  B(1,0) -= t;
448  B(0,1) -= t;
449 
450  t = T(487);//e
451  B(2,0) -= t;
452  B(0,2) -= t;
453 
454  t = T(506);//f
455  B(3,0) -= t;
456  B(0,3) -= t;
457 
458  t = T(135);//c
459  B(4,0) -= t;
460  B(0,4) -= t;
461  B(2,1) += t;
462  B(1,2) += t;
463  B(3,1) += t;
464  B(1,3) += t;
465 
466  t = T(173);//d
467  B(5,0) -= t;
468  B(0,5) -= t;
469 
470  t = T(61);//b
471  B(6,0) -= t;
472  B(0,6) -= t;
473  B(5,1) += t;
474  B(1,5) += t;
475 
476  t = T(42); //a
477  B(7,0) -= t;
478  B(0,7) -= t;
479  B(4,1) += t;
480  B(1,4) += t;
481  B(4,4) += t;
482 
483  t = T(1084);//g
484  B(1,1) += t;
485 
486  s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
487  break;
488  case 1:
489  B(0,1) -= T(6269);
490  B(0,3) -= T( 708);
491  B(0,5) -= T( 172);
492  B(0,7) -= T( 73);
493 
494  s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
495  break;
496  case 2:
497  B(1,0) -= T(6269);
498  B(3,0) -= T( 708);
499  B(5,0) -= T( 172);
500  B(7,0) -= T( 73);
501 
502  s->block_last_index[0] = FFMAX(s->block_last_index[0], 7);
503  break;
504  }
505 #undef B
506 #undef T
507 }
508 
509 static void dsp_x8_put_solidcolor(uint8_t const pix, uint8_t * dst, int const linesize){
510  int k;
511  for(k=0;k<8;k++){
512  memset(dst,pix,8);
513  dst+=linesize;
514  }
515 }
516 
517 static const int16_t quant_table[64] = {
518  256, 256, 256, 256, 256, 256, 259, 262,
519  265, 269, 272, 275, 278, 282, 285, 288,
520  292, 295, 299, 303, 306, 310, 314, 317,
521  321, 325, 329, 333, 337, 341, 345, 349,
522  353, 358, 362, 366, 371, 375, 379, 384,
523  389, 393, 398, 403, 408, 413, 417, 422,
524  428, 433, 438, 443, 448, 454, 459, 465,
525  470, 476, 482, 488, 493, 499, 505, 511
526 };
527 
528 static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){
529  MpegEncContext * const s= w->s;
530 
531  uint8_t * scantable;
532  int final,run,level;
533  int ac_mode,dc_mode,est_run,dc_level;
534  int pos,n;
535  int zeros_only;
536  int use_quant_matrix;
537  int sign;
538 
539  assert(w->orient<12);
540  s->dsp.clear_block(s->block[0]);
541 
542  if(chroma){
543  dc_mode=2;
544  }else{
545  dc_mode=!!w->est_run;//0,1
546  }
547 
548  if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1;
549  n=0;
550  zeros_only=0;
551  if(!final){//decode ac
552  use_quant_matrix=w->use_quant_matrix;
553  if(chroma){
554  ac_mode = 1;
555  est_run = 64;//not used
556  }else{
557  if (w->raw_orient < 3){
558  use_quant_matrix = 0;
559  }
560  if(w->raw_orient > 4){
561  ac_mode = 0;
562  est_run = 64;
563  }else{
564  if(w->est_run > 1){
565  ac_mode = 2;
566  est_run=w->est_run;
567  }else{
568  ac_mode = 3;
569  est_run = 64;
570  }
571  }
572  }
573  x8_select_ac_table(w,ac_mode);
574  /*scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};<-
575  -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>0x928548 */
576  scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated;
577  pos=0;
578  do {
579  n++;
580  if( n >= est_run ){
581  ac_mode=3;
582  x8_select_ac_table(w,3);
583  }
584 
585  x8_get_ac_rlf(w,ac_mode,&run,&level,&final);
586 
587  pos+=run+1;
588  if(pos>63){
589  //this also handles vlc error in x8_get_ac_rlf
590  return -1;
591  }
592  level= (level+1) * w->dquant;
593  level+= w->qsum;
594 
595  sign = - get_bits1(&s->gb);
596  level = (level ^ sign) - sign;
597 
598  if(use_quant_matrix){
599  level = (level*quant_table[pos])>>8;
600  }
601  s->block[0][ scantable[pos] ]=level;
602  }while(!final);
603 
604  s->block_last_index[0]=pos;
605  }else{//DC only
606  s->block_last_index[0]=0;
607  if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){//[-1;1]
608  int32_t divide_quant= !chroma ? w->divide_quant_dc_luma:
610  int32_t dc_quant = !chroma ? w->quant:
611  w->quant_dc_chroma;
612 
613  //original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding
614  dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13;
615 
616  dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3),
617  s->dest[chroma], s->current_picture.f.linesize[!!chroma]);
618 
619  goto block_placed;
620  }
621  zeros_only = (dc_level == 0);
622  }
623  if(!chroma){
624  s->block[0][0] = dc_level*w->quant;
625  }else{
626  s->block[0][0] = dc_level*w->quant_dc_chroma;
627  }
628 
629  //there is !zero_only check in the original, but dc_level check is enough
630  if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){
631  int direction;
632  /*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<-
633  -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */
634  direction= (0x6A017C>>(w->orient*2))&3;
635  if (direction != 3){
636  x8_ac_compensation(w, direction, s->block[0][0]);//modify block_last[]
637  }
638  }
639 
640  if(w->flat_dc){
641  dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.f.linesize[!!chroma]);
642  }else{
644  s->dest[chroma],
645  s->current_picture.f.linesize[!!chroma] );
646  }
647  if(!zeros_only)
648  s->dsp.idct_add ( s->dest[chroma],
649  s->current_picture.f.linesize[!!chroma],
650  s->block[0] );
651 
652 block_placed:
653 
654  if(!chroma){
656  }
657 
658  if(s->loop_filter){
659  uint8_t* ptr = s->dest[chroma];
660  int linesize = s->current_picture.f.linesize[!!chroma];
661 
662  if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){
663  w->dsp.h_loop_filter(ptr, linesize, w->quant);
664  }
665  if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){
666  w->dsp.v_loop_filter(ptr, linesize, w->quant);
667  }
668  }
669  return 0;
670 }
671 
672 static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_*
673 //not s->linesize as this would be wrong for field pics
674 //not that IntraX8 has interlacing support ;)
675  const int linesize = s->current_picture.f.linesize[0];
676  const int uvlinesize = s->current_picture.f.linesize[1];
677 
678  s->dest[0] = s->current_picture.f.data[0];
679  s->dest[1] = s->current_picture.f.data[1];
680  s->dest[2] = s->current_picture.f.data[2];
681 
682  s->dest[0] += s->mb_y * linesize << 3;
683  s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows
684  s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2;
685 }
686 
694 
695  w->s=s;
696  x8_vlc_init();
697  assert(s->mb_width>0);
698  w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb
699 
703 
704  ff_intrax8dsp_init(&w->dsp);
705 }
706 
712 {
714 }
715 
726 //FIXME extern uint8_t ff_wmv3_dc_scale_table[32];
727 int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){
728  MpegEncContext * const s= w->s;
729  int mb_xy;
730  assert(s);
731  w->use_quant_matrix = get_bits1(&s->gb);
732 
733  w->dquant = dquant;
734  w->quant = dquant >> 1;
735  w->qsum = quant_offset;
736 
737  w->divide_quant_dc_luma = ((1<<16) + (w->quant>>1)) / w->quant;
738  if(w->quant < 5){
739  w->quant_dc_chroma = w->quant;
741  }else{
742  w->quant_dc_chroma = w->quant+((w->quant+3)>>3);
743  w->divide_quant_dc_chroma = ((1<<16) + (w->quant_dc_chroma>>1)) / w->quant_dc_chroma;
744  }
746 
747  s->resync_mb_x=0;
748  s->resync_mb_y=0;
749 
750  for(s->mb_y=0; s->mb_y < s->mb_height*2; s->mb_y++){
752  mb_xy=(s->mb_y>>1)*s->mb_stride;
753 
754  for(s->mb_x=0; s->mb_x < s->mb_width*2; s->mb_x++){
756  if(x8_setup_spatial_predictor(w,0)) goto error;
757  if(x8_decode_intra_mb(w,0)) goto error;
758 
759  if( s->mb_x & s->mb_y & 1 ){
761 
762  /*when setting up chroma, no vlc is read,
763  so no error condition can be reached*/
765  if(x8_decode_intra_mb(w,1)) goto error;
766 
768  if(x8_decode_intra_mb(w,2)) goto error;
769 
770  s->dest[1]+= 8;
771  s->dest[2]+= 8;
772 
773  /*emulate MB info in the relevant tables*/
774  s->mbskip_table [mb_xy]=0;
775  s->mbintra_table[mb_xy]=1;
776  s->current_picture.f.qscale_table[mb_xy] = w->quant;
777  mb_xy++;
778  }
779  s->dest[0]+= 8;
780  }
781  if(s->mb_y&1){
782  ff_mpeg_draw_horiz_band(s, (s->mb_y-1)*8, 16);
783  }
784  }
785 
786 error:
788  (s->mb_x>>1)-1, (s->mb_y>>1)-1,
789  ER_MB_END );
790  return 0;
791 }
#define extra_bits(eb)
Definition: intrax8.c:151
static void x8_get_prediction(IntraX8Context *const w)
Definition: intrax8.c:377
static void x8_ac_compensation(IntraX8Context *const w, int const direction, int const dc_level)
Definition: intrax8.c:439
#define DC_VLC_MTD
Definition: intrax8.c:38
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:509
static void x8_update_predictions(IntraX8Context *const w, const int orient, const int est_run)
Definition: intrax8.c:353
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:237
#define ER_MB_END
#define extra_run
Definition: intrax8.c:152
#define AC_VLC_BITS
Definition: intrax8.c:35
void(* spatial_compensation[12])(uint8_t *src, uint8_t *dst, int linesize)
Definition: intrax8dsp.h:28
void(* idct_add)(uint8_t *dest, int line_size, DCTELEM *block)
block -> idct -> add dest -> clip to unsigned 8 bit -> dest.
Definition: dsputil.h:411
#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:183
uint8_t run
Definition: svq3.c:132
static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma)
Definition: intrax8.c:528
static void x8_reset_vlc_tables(IntraX8Context *w)
Definition: intrax8.c:118
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:151
#define OR_VLC_MTD
Definition: intrax8.c:40
void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h)
Definition: mpegvideo.c:2534
uint8_t
#define AC_VLC_MTD
Definition: intrax8.c:39
#define b
Definition: input.c:52
Picture current_picture
copy of the current picture structure.
Definition: mpegvideo.h:314
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:425
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:248
#define run_offset(r)
Definition: intrax8.c:154
static float t
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:38
static const int sizes[][2]
Definition: img2dec.c:46
static int x8_get_orient_vlc(IntraX8Context *w)
Definition: intrax8.c:137
ERContext er
Definition: mpegvideo.h:704
static const int16_t quant_table[64]
Definition: intrax8.c:517
uint8_t * edge_emu_buffer
temporary buffer for if MVs point to out-of-frame data
Definition: mpegvideo.h:338
static const uint16_t x8_ac0_lowquant_table[8][77][2]
Definition: intrax8huf.h:229
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:146
#define OR_VLC_BITS
Definition: intrax8.c:36
GetBitContext gb
Definition: mpegvideo.h:614
void(* clear_block)(DCTELEM *block)
Definition: dsputil.h:218
Definition: get_bits.h:63
int resync_mb_x
x position of last resync marker
Definition: mpegvideo.h:493
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
av_cold void ff_intrax8_common_init(IntraX8Context *w, MpegEncContext *const s)
Initialize IntraX8 frame decoder.
Definition: intrax8.c:693
av_cold void ff_intrax8_common_end(IntraX8Context *w)
Destroy IntraX8 frame structure.
Definition: intrax8.c:711
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:333
VLC * j_ac_vlc[4]
Definition: intrax8.h:27
static VLC j_dc_vlc[2][8]
Definition: intrax8.c:43
int32_t
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:515
int block_last_index[12]
last non zero coefficient in block
Definition: mpegvideo.h:262
uint8_t * mbintra_table
used to avoid setting {ac, dc, cbp}-pred stuff to zero on inter MB decoding
Definition: mpegvideo.h:335
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
NULL
Definition: eval.c:52
static VLC j_ac_vlc[2][2][8]
Definition: intrax8.c:42
external API header
int linesize[AV_NUM_DATA_POINTERS]
Size, in bytes, of the data for each picture/channel plane.
Definition: avcodec.h:1008
#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:155
IntraX8DSPContext dsp
Definition: intrax8.h:37
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:268
int quant_dc_chroma
Definition: intrax8.h:42
#define extra_level
Definition: intrax8.c:153
static void x8_init_block_index(MpegEncContext *s)
Definition: intrax8.c:672
DSPContext dsp
pointers for accelerated dsp functions
Definition: mpegvideo.h:362
av_cold void ff_intrax8dsp_init(IntraX8DSPContext *dsp)
Definition: intrax8dsp.c:416
int ff_intrax8_decode_picture(IntraX8Context *const w, int dquant, int quant_offset)
Decode single IntraX8 frame.
Definition: intrax8.c:727
ScanTable scantable[3]
Definition: intrax8.h:34
DCTELEM(* block)[64]
points to one of the following blocks
Definition: mpegvideo.h:662
const uint8_t * quant
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: avcodec.h:997
int8_t * qscale_table
QP table.
Definition: avcodec.h:1139
uint8_t level
Definition: svq3.c:133
#define DC_VLC_BITS
Definition: intrax8.c:34
MpegEncContext.
Definition: mpegvideo.h:212
void(* setup_spatial_compensation)(uint8_t *src, uint8_t *dst, int linesize, int *range, int *sum, int edges)
Definition: intrax8dsp.h:29
int mb_stride
mb_width+1 used for some arrays to allow simple addressing of left & top MBs without sig11 ...
Definition: mpegvideo.h:249
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:436
static void x8_select_ac_table(IntraX8Context *const w, int mode)
Definition: intrax8.c:124
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:122
int resync_mb_y
y position of last resync marker
Definition: mpegvideo.h:494
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:362
static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma)
Definition: intrax8.c:301
void(* h_loop_filter)(uint8_t *src, int stride, int qscale)
Definition: intrax8dsp.h:26
struct AVFrame f
Definition: mpegvideo.h:96
static av_cold void x8_vlc_init(void)
Definition: intrax8.c:46
int divide_quant_dc_chroma
Definition: intrax8.h:44
static VLC j_orient_vlc[2][4]
Definition: intrax8.c:44
void(* v_loop_filter)(uint8_t *src, int stride, int qscale)
Definition: intrax8dsp.h:25
VLC * j_orient_vlc
Definition: intrax8.h:28
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:158
int use_quant_matrix
Definition: intrax8.h:31
uint8_t * prediction_table
Definition: intrax8.h:33