FFmpeg
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++) {
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++) {
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++)
114  for (i = 0; i < 4; i++)
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 
156  return get_vlc2(w->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD);
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  };
370  w->raw_orient = x8_get_orient_vlc(w);
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
647  : w->divide_quant_dc_chroma;
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 {
684  w->dsp.spatial_compensation[w->orient](w->scratchpad,
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 
752  ff_init_scantable_permutation(w->idct_permutation,
753  w->wdsp.idct_perm);
754 
755  ff_init_scantable(w->idct_permutation, &w->scantable[0],
756  ff_wmv1_scantable[0]);
757  ff_init_scantable(w->idct_permutation, &w->scantable[1],
758  ff_wmv1_scantable[2]);
759  ff_init_scantable(w->idct_permutation, &w->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 {
770  av_freep(&w->prediction_table);
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;
794  w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
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  if (get_bits_left(gb) < 1)
805  goto error;
806  for (w->mb_x = 0; w->mb_x < w->mb_width * 2; w->mb_x++) {
809  goto error;
810  if (x8_decode_intra_mb(w, 0))
811  goto error;
812 
813  if (w->mb_x & w->mb_y & 1) {
815 
816  /* when setting up chroma, no vlc is read,
817  * so no error condition can be reached */
819  if (x8_decode_intra_mb(w, 1))
820  goto error;
821 
823  if (x8_decode_intra_mb(w, 2))
824  goto error;
825 
826  w->dest[1] += 8;
827  w->dest[2] += 8;
828 
829  pict->qscale_table[mb_xy] = w->quant;
830  mb_xy++;
831  }
832  w->dest[0] += 8;
833  }
834  if (w->mb_y & 1)
835  ff_draw_horiz_band(w->avctx, w->frame, w->frame,
836  (w->mb_y - 1) * 8, 16,
837  PICT_FRAME, 0, lowdelay);
838  }
839 
840 error:
841  *mb_x = w->mb_x;
842  *mb_y = w->mb_y;
843 
844  return 0;
845 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:29
PICT_FRAME
#define PICT_FRAME
Definition: mpegutils.h:39
ff_init_scantable
av_cold void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable)
Definition: idctdsp.c:29
x8_ac_compensation
static void x8_ac_compensation(IntraX8Context *const w, const int direction, const int dc_level)
Definition: intrax8.c:475
x8_decode_intra_mb
static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma)
Definition: intrax8.c:567
level
uint8_t level
Definition: svq3.c:210
extra_bits
#define extra_bits(eb)
Definition: intrax8.c:159
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
x8_setup_spatial_predictor
static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma)
Definition: intrax8.c:322
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
intrax8huf.h
AC_VLC_BITS
#define AC_VLC_BITS
Definition: intrax8.c:38
OR_VLC_MTD
#define OR_VLC_MTD
Definition: intrax8.c:43
ff_wmv1_scantable
const uint8_t ff_wmv1_scantable[WMV1_SCANTABLE_COUNT][64]
Definition: msmpeg4data.c:1809
j_orient_vlc
static VLC j_orient_vlc[2][4]
Definition: intrax8.c:47
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
extra_run
#define extra_run
Definition: intrax8.c:160
w
uint8_t w
Definition: llviddspenc.c:38
b
#define b
Definition: input.c:41
chroma
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, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1631
table
static const uint16_t table[]
Definition: prosumer.c:206
get_vlc2
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:797
Picture
Picture.
Definition: mpegpicture.h:45
x8_get_prediction
static void x8_get_prediction(IntraX8Context *const w)
Definition: intrax8.c:406
mpegutils.h
intrax8dsp.h
AC_VLC_MTD
#define AC_VLC_MTD
Definition: intrax8.c:42
x8_init_block_index
static void x8_init_block_index(IntraX8Context *w, AVFrame *frame)
Definition: intrax8.c:711
x8_update_predictions
static void x8_update_predictions(IntraX8Context *const w, const int orient, const int est_run)
Definition: intrax8.c:380
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
VLC_TYPE
#define VLC_TYPE
Definition: vlc.h:24
ff_intrax8_decode_picture
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
GetBitContext
Definition: get_bits.h:61
OR_VLC_BITS
#define OR_VLC_BITS
Definition: intrax8.c:39
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
av_cold
#define av_cold
Definition: attributes.h:90
ff_intrax8_common_init
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
mask
static const uint16_t mask[17]
Definition: lzw.c:38
msmpeg4data.h
x8_reset_vlc_tables
static void x8_reset_vlc_tables(IntraX8Context *w)
Definition: intrax8.c:127
x8_ac0_lowquant_table
static const uint16_t x8_ac0_lowquant_table[8][77][2]
Definition: intrax8huf.h:244
get_bits.h
IntraX8Context
Definition: intrax8.h:29
int32_t
int32_t
Definition: audio_convert.c:194
if
if(ret)
Definition: filter_design.txt:179
x8_orient_highquant_table
static const uint16_t x8_orient_highquant_table[2][12][2]
Definition: intrax8huf.h:47
quant_table
static const int16_t quant_table[64]
Definition: intrax8.c:556
NULL
#define NULL
Definition: coverity.c:32
sizes
static const int sizes[][2]
Definition: img2dec.c:53
run
uint8_t run
Definition: svq3.c:209
init_ac_vlc
#define init_ac_vlc(dst, src)
ff_intrax8_common_end
av_cold void ff_intrax8_common_end(IntraX8Context *w)
Destroy IntraX8 frame structure.
Definition: intrax8.c:768
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
x8_dc_lowquant_table
static const uint16_t x8_dc_lowquant_table[8][34][2]
Definition: intrax8huf.h:61
run_offset
#define run_offset(r)
Definition: intrax8.c:162
ff_wmv2dsp_init
av_cold void ff_wmv2dsp_init(WMV2DSPContext *c)
Definition: wmv2dsp.c:251
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
intrax8.h
x8_ac1_highquant_table
static const uint16_t x8_ac1_highquant_table[8][77][2]
Definition: intrax8huf.h:781
j_dc_vlc
static VLC j_dc_vlc[2][8]
Definition: intrax8.c:46
x8_get_orient_vlc
static int x8_get_orient_vlc(IntraX8Context *w)
Definition: intrax8.c:149
ff_draw_horiz_band
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
x8_dc_highquant_table
static const uint16_t x8_dc_highquant_table[8][34][2]
Definition: intrax8huf.h:152
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
init_dc_vlc
#define init_dc_vlc(dst, src)
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
x8_get_ac_rlf
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
x8_orient_lowquant_table
static const uint16_t x8_orient_lowquant_table[4][12][2]
Definition: intrax8huf.h:24
ff_init_scantable_permutation
av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation, enum idct_permutation_type perm_type)
Definition: idctdsp.c:50
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
ac_decode_table
static const uint32_t ac_decode_table[]
Definition: intrax8.c:164
x8_ac0_highquant_table
static const uint16_t x8_ac0_highquant_table[8][77][2]
Definition: intrax8huf.h:423
init_or_vlc
#define init_or_vlc(dst, src)
uint8_t
uint8_t
Definition: audio_convert.c:194
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:237
idctdsp.h
avcodec.h
ret
ret
Definition: filter_design.txt:187
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
Picture::qscale_table
int8_t * qscale_table
Definition: mpegpicture.h:50
dc_index_offset
static const uint8_t dc_index_offset[]
Definition: intrax8.c:282
pos
unsigned int pos
Definition: spdifenc.c:412
IDCTDSPContext
Definition: idctdsp.h:53
j_ac_vlc
static VLC j_ac_vlc[2][2][8]
Definition: intrax8.c:45
SIZE_SPECIFIER
#define SIZE_SPECIFIER
Definition: internal.h:264
x8_ac1_lowquant_table
static const uint16_t x8_ac1_lowquant_table[8][77][2]
Definition: intrax8huf.h:602
AVCodecContext
main external API structure.
Definition: avcodec.h:526
T
#define T(x)
B
#define B(x, y)
mode
mode
Definition: ebur128.h:83
Picture::f
struct AVFrame * f
Definition: mpegpicture.h:46
VLC
Definition: vlc.h:26
level_offset
#define level_offset(l)
Definition: intrax8.c:163
x8_get_prediction_chroma
static void x8_get_prediction_chroma(IntraX8Context *const w)
Definition: intrax8.c:390
dsp_x8_put_solidcolor
static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst, const ptrdiff_t linesize)
Definition: intrax8.c:546
extra_level
#define extra_level
Definition: intrax8.c:161
quant
const uint8_t * quant
Definition: vorbis_enc_data.h:458
x8_get_dc_rlf
static int x8_get_dc_rlf(IntraX8Context *const w, const int mode, int *const level, int *const final)
Definition: intrax8.c:286
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
x8_vlc_init
static av_cold int x8_vlc_init(void)
Definition: intrax8.c:49
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
DC_VLC_BITS
#define DC_VLC_BITS
Definition: intrax8.c:37
ff_blockdsp_init
av_cold void ff_blockdsp_init(BlockDSPContext *c, AVCodecContext *avctx)
Definition: blockdsp.c:60
x8_select_ac_table
static void x8_select_ac_table(IntraX8Context *const w, int mode)
Definition: intrax8.c:134
ff_intrax8dsp_init
av_cold void ff_intrax8dsp_init(IntraX8DSPContext *dsp)
Definition: intrax8dsp.c:448
DC_VLC_MTD
#define DC_VLC_MTD
Definition: intrax8.c:41