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