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