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 "libavutil/thread.h"
26 #include "avcodec.h"
27 #include "get_bits.h"
28 #include "idctdsp.h"
29 #include "msmpeg4_vc1_data.h"
30 #include "intrax8huf.h"
31 #include "intrax8.h"
32 #include "intrax8dsp.h"
33 #include "mpegutils.h"
34 
35 #define VLC_BUFFER_SIZE 28150
36 
37 #define MAX_TABLE_DEPTH(table_bits, max_bits) \
38  ((max_bits + table_bits - 1) / table_bits)
39 
40 #define DC_VLC_BITS 9
41 #define AC_VLC_BITS 9
42 #define OR_VLC_BITS 7
43 
44 #define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS)
45 #define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
46 #define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS)
47 
48 static const VLCElem *j_ac_vlc[2][2][8]; // [quant < 13], [intra / inter], [select]
49 static const VLCElem *j_dc_vlc[2][8]; // [quant], [select]
50 static const VLCElem *j_orient_vlc[2][4]; // [quant], [select]
51 
52 static av_cold const VLCElem *x8_init_vlc(VLCInitState *state, int nb_bits,
53  int nb_codes, const uint8_t table[][2])
54 {
55  return ff_vlc_init_tables_from_lengths(state, nb_bits, nb_codes, &table[0][1], 2,
56  &table[0][0], 2, 1, 0, 0);
57 }
58 
59 static av_cold void x8_vlc_init(void)
60 {
61  static VLCElem vlc_buf[VLC_BUFFER_SIZE];
63  int i;
64 
65 // set ac tables
66  for (int i = 0; i < 2; i++)
67  for (int j = 0; j < 2; j++)
68  for (int k = 0; k < 8; k++)
69  j_ac_vlc[i][j][k] = x8_init_vlc(&state, AC_VLC_BITS, 77,
70  x8_ac_quant_table[i][j][k]);
71 
72 // set dc tables
73  for (int i = 0; i < 2; i++)
74  for (int j = 0; j < 8; j++)
76  x8_dc_quant_table[i][j]);
77 
78 // set orient tables
79  for (i = 0; i < 2; i++)
82  for (i = 0; i < 4; i++)
85 }
86 
88 {
89  memset(w->j_dc_vlc_table, 0, sizeof(w->j_dc_vlc_table));
90  memset(w->j_ac_vlc_table, 0, sizeof(w->j_ac_vlc_table));
91  w->j_orient_vlc_table = NULL;
92 }
93 
94 static inline void x8_select_ac_table(IntraX8Context *const w, int mode)
95 {
96  int table_index;
97 
98  av_assert2(mode < 4);
99 
100  if (w->j_ac_vlc_table[mode])
101  return;
102 
103  table_index = get_bits(w->gb, 3);
104  // 2 modes use same tables
105  w->j_ac_vlc_table[mode] = j_ac_vlc[w->quant < 13][mode >> 1][table_index];
106  av_assert2(w->j_ac_vlc_table[mode]);
107 }
108 
109 static inline int x8_get_orient_vlc(IntraX8Context *w)
110 {
111  if (!w->j_orient_vlc_table) {
112  int table_index = get_bits(w->gb, 1 + (w->quant < 13));
113  w->j_orient_vlc_table = j_orient_vlc[w->quant < 13][table_index];
114  }
115 
116  return get_vlc2(w->gb, w->j_orient_vlc_table, OR_VLC_BITS, OR_VLC_MTD);
117 }
118 
119 #define extra_bits(eb) (eb) // 3 bits
120 #define extra_run (0xFF << 8) // 1 bit
121 #define extra_level (0x00 << 8) // 1 bit
122 #define run_offset(r) ((r) << 16) // 6 bits
123 #define level_offset(l) ((l) << 24) // 5 bits
124 static const uint32_t ac_decode_table[] = {
125  /* 46 */ extra_bits(3) | extra_run | run_offset(16) | level_offset(0),
126  /* 47 */ extra_bits(3) | extra_run | run_offset(24) | level_offset(0),
127  /* 48 */ extra_bits(2) | extra_run | run_offset(4) | level_offset(1),
128  /* 49 */ extra_bits(3) | extra_run | run_offset(8) | level_offset(1),
129 
130  /* 50 */ extra_bits(5) | extra_run | run_offset(32) | level_offset(0),
131  /* 51 */ extra_bits(4) | extra_run | run_offset(16) | level_offset(1),
132 
133  /* 52 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(4),
134  /* 53 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(8),
135  /* 54 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(12),
136  /* 55 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(16),
137  /* 56 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(24),
138 
139  /* 57 */ extra_bits(2) | extra_level | run_offset(1) | level_offset(3),
140  /* 58 */ extra_bits(3) | extra_level | run_offset(1) | level_offset(7),
141 
142  /* 59 */ extra_bits(2) | extra_run | run_offset(16) | level_offset(0),
143  /* 60 */ extra_bits(2) | extra_run | run_offset(20) | level_offset(0),
144  /* 61 */ extra_bits(2) | extra_run | run_offset(24) | level_offset(0),
145  /* 62 */ extra_bits(2) | extra_run | run_offset(28) | level_offset(0),
146  /* 63 */ extra_bits(4) | extra_run | run_offset(32) | level_offset(0),
147  /* 64 */ extra_bits(4) | extra_run | run_offset(48) | level_offset(0),
148 
149  /* 65 */ extra_bits(2) | extra_run | run_offset(4) | level_offset(1),
150  /* 66 */ extra_bits(3) | extra_run | run_offset(8) | level_offset(1),
151  /* 67 */ extra_bits(4) | extra_run | run_offset(16) | level_offset(1),
152 
153  /* 68 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(4),
154  /* 69 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(8),
155  /* 70 */ extra_bits(4) | extra_level | run_offset(0) | level_offset(16),
156 
157  /* 71 */ extra_bits(2) | extra_level | run_offset(1) | level_offset(3),
158  /* 72 */ extra_bits(3) | extra_level | run_offset(1) | level_offset(7),
159 };
160 #undef extra_bits
161 #undef extra_run
162 #undef extra_level
163 #undef run_offset
164 #undef level_offset
165 
166 static void x8_get_ac_rlf(IntraX8Context *const w, const int mode,
167  int *const run, int *const level, int *const final)
168 {
169  int i, e;
170 
171 // x8_select_ac_table(w, mode);
172  i = get_vlc2(w->gb, w->j_ac_vlc_table[mode], AC_VLC_BITS, AC_VLC_MTD);
173 
174  if (i < 46) { // [0-45]
175  int t, l;
176  if (i < 0) {
177  *level =
178  *final = // prevent 'may be used uninitialized'
179  *run = 64; // this would cause error exit in the ac loop
180  return;
181  }
182 
183  /*
184  * i == 0-15 r = 0-15 l = 0; r = i & %01111
185  * i == 16-19 r = 0-3 l = 1; r = i & %00011
186  * i == 20-21 r = 0-1 l = 2; r = i & %00001
187  * i == 22 r = 0 l = 3; r = i & %00000
188  */
189 
190  *final =
191  t = i > 22;
192  i -= 23 * t;
193 
194  /* l = lut_l[i / 2] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3 }[i >> 1];
195  * 11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000 */
196  l = (0xE50000 >> (i & 0x1E)) & 3; // 0x1E or ~1 or (i >> 1 << 1)
197 
198  /* t = lut_mask[l] = { 0x0f, 0x03, 0x01, 0x00 }[l];
199  * as i < 256 the higher bits do not matter */
200  t = 0x01030F >> (l << 3);
201 
202  *run = i & t;
203  *level = l;
204  } else if (i < 73) { // [46-72]
205  uint32_t sm;
206  uint32_t mask;
207 
208  i -= 46;
209  sm = ac_decode_table[i];
210 
211  e = get_bits(w->gb, sm & 0xF);
212  sm >>= 8; // 3 bits
213  mask = sm & 0xff;
214  sm >>= 8; // 1 bit
215 
216  *run = (sm & 0xff) + (e & mask); // 6 bits
217  *level = (sm >> 8) + (e & ~mask); // 5 bits
218  *final = i > (58 - 46);
219  } else if (i < 75) { // [73-74]
220  static const uint8_t crazy_mix_runlevel[32] = {
221  0x22, 0x32, 0x33, 0x53, 0x23, 0x42, 0x43, 0x63,
222  0x24, 0x52, 0x34, 0x73, 0x25, 0x62, 0x44, 0x83,
223  0x26, 0x72, 0x35, 0x54, 0x27, 0x82, 0x45, 0x64,
224  0x28, 0x92, 0x36, 0x74, 0x29, 0xa2, 0x46, 0x84,
225  };
226 
227  *final = !(i & 1);
228  e = get_bits(w->gb, 5); // get the extra bits
229  *run = crazy_mix_runlevel[e] >> 4;
230  *level = crazy_mix_runlevel[e] & 0x0F;
231  } else {
232  *level = get_bits(w->gb, 7 - 3 * (i & 1));
233  *run = get_bits(w->gb, 6);
234  *final = get_bits1(w->gb);
235  }
236  return;
237 }
238 
239 /* static const uint8_t dc_extra_sbits[] = {
240  * 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
241  * }; */
242 static const uint8_t dc_index_offset[] = {
243  0, 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
244 };
245 
246 static int x8_get_dc_rlf(IntraX8Context *const w, const int mode,
247  int *const level, int *const final)
248 {
249  int i, e, c;
250 
251  av_assert2(mode < 3);
252  if (!w->j_dc_vlc_table[mode]) {
253  int table_index = get_bits(w->gb, 3);
254  // 4 modes, same table
255  w->j_dc_vlc_table[mode] = j_dc_vlc[w->quant < 13][table_index];
256  }
257 
258  i = get_vlc2(w->gb, w->j_dc_vlc_table[mode], DC_VLC_BITS, DC_VLC_MTD);
259 
260  /* (i >= 17) { i -= 17; final =1; } */
261  c = i > 16;
262  *final = c;
263  i -= 17 * c;
264 
265  if (i <= 0) {
266  *level = 0;
267  return -i;
268  }
269  c = (i + 1) >> 1; // hackish way to calculate dc_extra_sbits[]
270  c -= c > 1;
271 
272  e = get_bits(w->gb, c); // get the extra bits
273  i = dc_index_offset[i] + (e >> 1);
274 
275  e = -(e & 1); // 0, 0xffffff
276  *level = (i ^ e) - e; // (i ^ 0) - 0, (i ^ 0xff) - (-1)
277  return 0;
278 }
279 
280 // end of huffman
281 
282 static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma)
283 {
284  int range;
285  int sum;
286  int quant;
287 
288  w->dsp.setup_spatial_compensation(w->dest[chroma], w->scratchpad,
289  w->frame->linesize[chroma > 0],
290  &range, &sum, w->edges);
291  if (chroma) {
292  w->orient = w->chroma_orient;
293  quant = w->quant_dc_chroma;
294  } else {
295  quant = w->quant;
296  }
297 
298  w->flat_dc = 0;
299  if (range < quant || range < 3) {
300  w->orient = 0;
301 
302  // yep you read right, a +-1 idct error may break decoding!
303  if (range < 3) {
304  w->flat_dc = 1;
305  sum += 9;
306  // ((1 << 17) + 9) / (8 + 8 + 1 + 2) = 6899
307  w->predicted_dc = sum * 6899 >> 17;
308  }
309  }
310  if (chroma)
311  return 0;
312 
313  av_assert2(w->orient < 3);
314  if (range < 2 * w->quant) {
315  if ((w->edges & 3) == 0) {
316  if (w->orient == 1)
317  w->orient = 11;
318  if (w->orient == 2)
319  w->orient = 10;
320  } else {
321  w->orient = 0;
322  }
323  w->raw_orient = 0;
324  } else {
325  static const uint8_t prediction_table[3][12] = {
326  { 0, 8, 4, 10, 11, 2, 6, 9, 1, 3, 5, 7 },
327  { 4, 0, 8, 11, 10, 3, 5, 2, 6, 9, 1, 7 },
328  { 8, 0, 4, 10, 11, 1, 7, 2, 6, 9, 3, 5 },
329  };
330  w->raw_orient = x8_get_orient_vlc(w);
331  if (w->raw_orient < 0)
332  return -1;
333  av_assert2(w->raw_orient < 12);
334  av_assert2(w->orient < 3);
335  w->orient=prediction_table[w->orient][w->raw_orient];
336  }
337  return 0;
338 }
339 
340 static void x8_update_predictions(IntraX8Context *const w, const int orient,
341  const int est_run)
342 {
343  w->prediction_table[w->mb_x * 2 + (w->mb_y & 1)] = (est_run << 2) + 1 * (orient == 4) + 2 * (orient == 8);
344 /*
345  * y = 2n + 0 -> // 0 2 4
346  * y = 2n + 1 -> // 1 3 5
347  */
348 }
349 
351 {
352  w->edges = 1 * !(w->mb_x >> 1);
353  w->edges |= 2 * !(w->mb_y >> 1);
354  w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1)); // mb_x for chroma would always be odd
355 
356  w->raw_orient = 0;
357  // lut_co[8] = {inv,4,8,8, inv,4,8,8} <- => {1,1,0,0;1,1,0,0} => 0xCC
358  if (w->edges & 3) {
359  w->chroma_orient = 4 << ((0xCC >> w->edges) & 1);
360  return;
361  }
362  // block[x - 1][y | 1 - 1)]
363  w->chroma_orient = (w->prediction_table[2 * w->mb_x - 2] & 0x03) << 2;
364 }
365 
366 static void x8_get_prediction(IntraX8Context *const w)
367 {
368  int a, b, c, i;
369 
370  w->edges = 1 * !w->mb_x;
371  w->edges |= 2 * !w->mb_y;
372  w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1));
373 
374  switch (w->edges & 3) {
375  case 0:
376  break;
377  case 1:
378  // take the one from the above block[0][y - 1]
379  w->est_run = w->prediction_table[!(w->mb_y & 1)] >> 2;
380  w->orient = 1;
381  return;
382  case 2:
383  // take the one from the previous block[x - 1][0]
384  w->est_run = w->prediction_table[2 * w->mb_x - 2] >> 2;
385  w->orient = 2;
386  return;
387  case 3:
388  w->est_run = 16;
389  w->orient = 0;
390  return;
391  }
392  // no edge cases
393  b = w->prediction_table[2 * w->mb_x + !(w->mb_y & 1)]; // block[x ][y - 1]
394  a = w->prediction_table[2 * w->mb_x - 2 + (w->mb_y & 1)]; // block[x - 1][y ]
395  c = w->prediction_table[2 * w->mb_x - 2 + !(w->mb_y & 1)]; // block[x - 1][y - 1]
396 
397  w->est_run = FFMIN(b, a);
398  /* This condition has nothing to do with w->edges, even if it looks
399  * similar it would trigger if e.g. x = 3; y = 2;
400  * I guess somebody wrote something wrong and it became standard. */
401  if ((w->mb_x & w->mb_y) != 0)
402  w->est_run = FFMIN(c, w->est_run);
403  w->est_run >>= 2;
404 
405  a &= 3;
406  b &= 3;
407  c &= 3;
408 
409  i = (0xFFEAF4C4 >> (2 * b + 8 * a)) & 3;
410  if (i != 3)
411  w->orient = i;
412  else
413  w->orient = (0xFFEAD8 >> (2 * c + 8 * (w->quant > 12))) & 3;
414 /*
415  * lut1[b][a] = {
416  * ->{ 0, 1, 0, pad },
417  * { 0, 1, X, pad },
418  * { 2, 2, 2, pad }
419  * }
420  * pad 2 2 2;
421  * pad X 1 0;
422  * pad 0 1 0 <-
423  * -> 11 10 '10 10 '11 11'01 00 '11 00'01 00 => 0xEAF4C4
424  *
425  * lut2[q>12][c] = {
426  * ->{ 0, 2, 1, pad},
427  * { 2, 2, 2, pad}
428  * }
429  * pad 2 2 2;
430  * pad 1 2 0 <-
431  * -> 11 10'10 10 '11 01'10 00 => 0xEAD8
432  */
433 }
434 
435 static void x8_ac_compensation(IntraX8Context *const w, const int direction,
436  const int dc_level)
437 {
438  int t;
439 #define B(x,y) w->block[0][w->idct_permutation[(x) + (y) * 8]]
440 #define T(x) ((x) * dc_level + 0x8000) >> 16;
441  switch (direction) {
442  case 0:
443  t = T(3811); // h
444  B(1, 0) -= t;
445  B(0, 1) -= t;
446 
447  t = T(487); // e
448  B(2, 0) -= t;
449  B(0, 2) -= t;
450 
451  t = T(506); // f
452  B(3, 0) -= t;
453  B(0, 3) -= t;
454 
455  t = T(135); // c
456  B(4, 0) -= t;
457  B(0, 4) -= t;
458  B(2, 1) += t;
459  B(1, 2) += t;
460  B(3, 1) += t;
461  B(1, 3) += t;
462 
463  t = T(173); // d
464  B(5, 0) -= t;
465  B(0, 5) -= t;
466 
467  t = T(61); // b
468  B(6, 0) -= t;
469  B(0, 6) -= t;
470  B(5, 1) += t;
471  B(1, 5) += t;
472 
473  t = T(42); // a
474  B(7, 0) -= t;
475  B(0, 7) -= t;
476  B(4, 1) += t;
477  B(1, 4) += t;
478  B(4, 4) += t;
479 
480  t = T(1084); // g
481  B(1, 1) += t;
482 
483  w->block_last_index[0] = FFMAX(w->block_last_index[0], 7 * 8);
484  break;
485  case 1:
486  B(0, 1) -= T(6269);
487  B(0, 3) -= T(708);
488  B(0, 5) -= T(172);
489  B(0, 7) -= T(73);
490 
491  w->block_last_index[0] = FFMAX(w->block_last_index[0], 7 * 8);
492  break;
493  case 2:
494  B(1, 0) -= T(6269);
495  B(3, 0) -= T(708);
496  B(5, 0) -= T(172);
497  B(7, 0) -= T(73);
498 
499  w->block_last_index[0] = FFMAX(w->block_last_index[0], 7);
500  break;
501  }
502 #undef B
503 #undef T
504 }
505 
506 static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst,
507  const ptrdiff_t linesize)
508 {
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 {
529  uint8_t *scantable;
530  int final, run, level;
531  int ac_mode, dc_mode, est_run, dc_level;
532  int pos, n;
533  int zeros_only;
534  int use_quant_matrix;
535  int sign;
536 
537  av_assert2(w->orient < 12);
538  w->bdsp.clear_block(w->block[0]);
539 
540  if (chroma)
541  dc_mode = 2;
542  else
543  dc_mode = !!w->est_run; // 0, 1
544 
545  if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final))
546  return -1;
547  n = 0;
548  zeros_only = 0;
549  if (!final) { // decode ac
550  use_quant_matrix = w->use_quant_matrix;
551  if (chroma) {
552  ac_mode = 1;
553  est_run = 64; // not used
554  } else {
555  if (w->raw_orient < 3)
556  use_quant_matrix = 0;
557 
558  if (w->raw_orient > 4) {
559  ac_mode = 0;
560  est_run = 64;
561  } else {
562  if (w->est_run > 1) {
563  ac_mode = 2;
564  est_run = w->est_run;
565  } else {
566  ac_mode = 3;
567  est_run = 64;
568  }
569  }
570  }
571  x8_select_ac_table(w, ac_mode);
572  /* scantable_selector[12] = { 0, 2, 0, 1, 1, 1, 0, 2, 2, 0, 1, 2 }; <-
573  * -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 => 0x928548 */
574  scantable = w->permutated_scantable[(0x928548 >> (2 * w->orient)) & 3];
575  pos = 0;
576  do {
577  n++;
578  if (n >= est_run) {
579  ac_mode = 3;
580  x8_select_ac_table(w, 3);
581  }
582 
583  x8_get_ac_rlf(w, ac_mode, &run, &level, &final);
584 
585  pos += run + 1;
586  if (pos > 63) {
587  // this also handles vlc error in x8_get_ac_rlf
588  return -1;
589  }
590  level = (level + 1) * w->dquant;
591  level += w->qsum;
592 
593  sign = -get_bits1(w->gb);
594  level = (level ^ sign) - sign;
595 
596  if (use_quant_matrix)
597  level = (level * quant_table[pos]) >> 8;
598 
599  w->block[0][scantable[pos]] = level;
600  } while (!final);
601 
602  w->block_last_index[0] = pos;
603  } else { // DC only
604  w->block_last_index[0] = 0;
605  if (w->flat_dc && ((unsigned) (dc_level + 1)) < 3) { // [-1; 1]
606  int32_t divide_quant = !chroma ? w->divide_quant_dc_luma
607  : w->divide_quant_dc_chroma;
608  int32_t dc_quant = !chroma ? w->quant
609  : w->quant_dc_chroma;
610 
611  // original intent dc_level += predicted_dc/quant;
612  // 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  w->dest[chroma],
617  w->frame->linesize[!!chroma]);
618 
619  goto block_placed;
620  }
621  zeros_only = dc_level == 0;
622  }
623  if (!chroma)
624  w->block[0][0] = dc_level * w->quant;
625  else
626  w->block[0][0] = dc_level * w->quant_dc_chroma;
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  // modify block_last[]
636  x8_ac_compensation(w, direction, w->block[0][0]);
637  }
638  }
639 
640  if (w->flat_dc) {
641  dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma],
642  w->frame->linesize[!!chroma]);
643  } else {
644  w->dsp.spatial_compensation[w->orient](w->scratchpad,
645  w->dest[chroma],
646  w->frame->linesize[!!chroma]);
647  }
648  if (!zeros_only)
649  w->wdsp.idct_add(w->dest[chroma],
650  w->frame->linesize[!!chroma],
651  w->block[0]);
652 
653 block_placed:
654  if (!chroma)
655  x8_update_predictions(w, w->orient, n);
656 
657  if (w->loopfilter) {
658  uint8_t *ptr = w->dest[chroma];
659  ptrdiff_t linesize = w->frame->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  return 0;
668 }
669 
670 // FIXME maybe merge with ff_*
672 {
673  // not parent codec linesize as this would be wrong for field pics
674  // not that IntraX8 has interlacing support ;)
675  const ptrdiff_t linesize = frame->linesize[0];
676  const ptrdiff_t uvlinesize = frame->linesize[1];
677 
678  w->dest[0] = frame->data[0];
679  w->dest[1] = frame->data[1];
680  w->dest[2] = frame->data[2];
681 
682  w->dest[0] += w->mb_y * linesize << 3;
683  // chroma blocks are on add rows
684  w->dest[1] += (w->mb_y & ~1) * uvlinesize << 2;
685  w->dest[2] += (w->mb_y & ~1) * uvlinesize << 2;
686 }
687 
689  IntraX8Context *w,
690  int16_t (*block)[64],
691  int block_last_index[12],
692  int mb_width, int mb_height)
693 {
694  static AVOnce init_static_once = AV_ONCE_INIT;
695 
696  w->avctx = avctx;
697  w->mb_width = mb_width;
698  w->mb_height = mb_height;
699  w->block = block;
700  w->block_last_index = block_last_index;
701 
702  // two rows, 2 blocks per cannon mb
703  w->prediction_table = av_mallocz(w->mb_width * 2 * 2);
704  if (!w->prediction_table)
705  return AVERROR(ENOMEM);
706 
707  ff_wmv2dsp_init(&w->wdsp);
708 
709  ff_init_scantable_permutation(w->idct_permutation,
710  w->wdsp.idct_perm);
711 
712  ff_permute_scantable(w->permutated_scantable[0], ff_wmv1_scantable[0],
713  w->idct_permutation);
714  ff_permute_scantable(w->permutated_scantable[1], ff_wmv1_scantable[2],
715  w->idct_permutation);
716  ff_permute_scantable(w->permutated_scantable[2], ff_wmv1_scantable[3],
717  w->idct_permutation);
718 
719  ff_intrax8dsp_init(&w->dsp);
720  ff_blockdsp_init(&w->bdsp);
721 
722  ff_thread_once(&init_static_once, x8_vlc_init);
723 
724  return 0;
725 }
726 
728 {
729  av_freep(&w->prediction_table);
730 }
731 
733  GetBitContext *gb, int *mb_x, int *mb_y,
734  int dquant, int quant_offset,
735  int loopfilter, int lowdelay)
736 {
737  int mb_xy;
738 
739  w->gb = gb;
740  w->dquant = dquant;
741  w->quant = dquant >> 1;
742  w->qsum = quant_offset;
743  w->frame = pict->f;
744  w->loopfilter = loopfilter;
745  w->use_quant_matrix = get_bits1(w->gb);
746 
747  w->mb_x = *mb_x;
748  w->mb_y = *mb_y;
749 
750  w->divide_quant_dc_luma = ((1 << 16) + (w->quant >> 1)) / w->quant;
751  if (w->quant < 5) {
752  w->quant_dc_chroma = w->quant;
753  w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
754  } else {
755  w->quant_dc_chroma = w->quant + ((w->quant + 3) >> 3);
756  w->divide_quant_dc_chroma = ((1 << 16) + (w->quant_dc_chroma >> 1)) / w->quant_dc_chroma;
757  }
759 
760  for (w->mb_y = 0; w->mb_y < w->mb_height * 2; w->mb_y++) {
761  x8_init_block_index(w, w->frame);
762  mb_xy = (w->mb_y >> 1) * (w->mb_width + 1);
763  if (get_bits_left(gb) < 1)
764  goto error;
765  for (w->mb_x = 0; w->mb_x < w->mb_width * 2; w->mb_x++) {
768  goto error;
769  if (x8_decode_intra_mb(w, 0))
770  goto error;
771 
772  if (w->mb_x & w->mb_y & 1) {
774 
775  /* when setting up chroma, no vlc is read,
776  * so no error condition can be reached */
778  if (x8_decode_intra_mb(w, 1))
779  goto error;
780 
782  if (x8_decode_intra_mb(w, 2))
783  goto error;
784 
785  w->dest[1] += 8;
786  w->dest[2] += 8;
787 
788  pict->qscale_table[mb_xy] = w->quant;
789  mb_xy++;
790  }
791  w->dest[0] += 8;
792  }
793  if (w->mb_y & 1)
794  ff_draw_horiz_band(w->avctx, w->frame, w->frame,
795  (w->mb_y - 1) * 8, 16,
796  PICT_FRAME, 0, lowdelay);
797  }
798 
799 error:
800  *mb_x = w->mb_x;
801  *mb_y = w->mb_y;
802 
803  return 0;
804 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
PICT_FRAME
#define PICT_FRAME
Definition: mpegutils.h:38
x8_orient_lowquant_table
static const uint8_t x8_orient_lowquant_table[4][12][2]
Definition: intrax8huf.h:24
ff_draw_horiz_band
void ff_draw_horiz_band(AVCodecContext *avctx, const AVFrame *cur, const AVFrame *last, int y, int h, int picture_structure, int first_field, int low_delay)
Draw a horizontal band if supported.
Definition: mpegutils.c:53
x8_ac_compensation
static void x8_ac_compensation(IntraX8Context *const w, const int direction, const int dc_level)
Definition: intrax8.c:435
x8_decode_intra_mb
static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma)
Definition: intrax8.c:527
level
uint8_t level
Definition: svq3.c:204
extra_bits
#define extra_bits(eb)
Definition: intrax8.c:119
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:694
x8_setup_spatial_predictor
static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma)
Definition: intrax8.c:282
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:41
OR_VLC_MTD
#define OR_VLC_MTD
Definition: intrax8.c:46
thread.h
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
extra_run
#define extra_run
Definition: intrax8.c:120
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:1639
table
static const uint16_t table[]
Definition: prosumer.c:205
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
Picture
Picture.
Definition: mpegpicture.h:46
x8_get_prediction
static void x8_get_prediction(IntraX8Context *const w)
Definition: intrax8.c:366
mpegutils.h
intrax8dsp.h
AC_VLC_MTD
#define AC_VLC_MTD
Definition: intrax8.c:45
x8_init_block_index
static void x8_init_block_index(IntraX8Context *w, AVFrame *frame)
Definition: intrax8.c:671
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:361
x8_update_predictions
static void x8_update_predictions(IntraX8Context *const w, const int orient, const int est_run)
Definition: intrax8.c:340
ff_permute_scantable
av_cold void ff_permute_scantable(uint8_t dst[64], const uint8_t src[64], const uint8_t permutation[64])
Definition: idctdsp.c:30
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:335
state
static struct @377 state
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:732
GetBitContext
Definition: get_bits.h:108
OR_VLC_BITS
#define OR_VLC_BITS
Definition: intrax8.c:42
quant
static const uint8_t quant[64]
Definition: vmixdec.c:71
avassert.h
ff_thread_once
static int ff_thread_once(char *control, void(*routine)(void))
Definition: thread.h:205
av_cold
#define av_cold
Definition: attributes.h:90
VLCInitState
For static VLCs, the number of bits can often be hardcoded at each get_vlc2() callsite.
Definition: vlc.h:209
mask
static const uint16_t mask[17]
Definition: lzw.c:38
ff_blockdsp_init
av_cold void ff_blockdsp_init(BlockDSPContext *c)
Definition: blockdsp.c:58
x8_reset_vlc_tables
static void x8_reset_vlc_tables(IntraX8Context *w)
Definition: intrax8.c:87
get_bits.h
ff_intrax8_common_init
av_cold int ff_intrax8_common_init(AVCodecContext *avctx, IntraX8Context *w, int16_t(*block)[64], int block_last_index[12], int mb_width, int mb_height)
Initialize IntraX8 frame decoder.
Definition: intrax8.c:688
frame
static AVFrame * frame
Definition: demux_decode.c:54
IntraX8Context
Definition: intrax8.h:28
if
if(ret)
Definition: filter_design.txt:179
quant_table
static const int16_t quant_table[64]
Definition: intrax8.c:516
AV_ONCE_INIT
#define AV_ONCE_INIT
Definition: thread.h:203
NULL
#define NULL
Definition: coverity.c:32
run
uint8_t run
Definition: svq3.c:203
ff_intrax8_common_end
av_cold void ff_intrax8_common_end(IntraX8Context *w)
Destroy IntraX8 frame structure.
Definition: intrax8.c:727
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:388
x8_dc_quant_table
static const uint8_t x8_dc_quant_table[2][8][34][2]
Definition: intrax8huf.h:55
run_offset
#define run_offset(r)
Definition: intrax8.c:122
ff_wmv2dsp_init
av_cold void ff_wmv2dsp_init(WMV2DSPContext *c)
Definition: wmv2dsp.c:252
get_vlc2
static av_always_inline int get_vlc2(GetBitContext *s, const VLCElem *table, int bits, int max_depth)
Parse a vlc code.
Definition: get_bits.h:652
AVOnce
#define AVOnce
Definition: thread.h:202
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_orient_highquant_table
static const uint8_t x8_orient_highquant_table[2][12][2]
Definition: intrax8huf.h:43
x8_get_orient_vlc
static int x8_get_orient_vlc(IntraX8Context *w)
Definition: intrax8.c:109
VLCElem
Definition: vlc.h:32
range
enum AVColorRange range
Definition: mediacodec_wrapper.c:2646
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
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:166
x8_ac_quant_table
static const uint8_t x8_ac_quant_table[2][2][8][77][2]
Definition: intrax8huf.h:207
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:67
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
ac_decode_table
static const uint32_t ac_decode_table[]
Definition: intrax8.c:124
j_ac_vlc
static const VLCElem * j_ac_vlc[2][2][8]
Definition: intrax8.c:48
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
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:254
idctdsp.h
avcodec.h
Picture::qscale_table
int8_t * qscale_table
Definition: mpegpicture.h:51
dc_index_offset
static const uint8_t dc_index_offset[]
Definition: intrax8.c:242
x8_init_vlc
static const av_cold VLCElem * x8_init_vlc(VLCInitState *state, int nb_bits, int nb_codes, const uint8_t table[][2])
Definition: intrax8.c:52
pos
unsigned int pos
Definition: spdifenc.c:413
j_dc_vlc
static const VLCElem * j_dc_vlc[2][8]
Definition: intrax8.c:49
AVCodecContext
main external API structure.
Definition: avcodec.h:445
VLC_BUFFER_SIZE
#define VLC_BUFFER_SIZE
Definition: intrax8.c:35
T
#define T(x)
B
#define B(x, y)
mode
mode
Definition: ebur128.h:83
Picture::f
struct AVFrame * f
Definition: mpegpicture.h:47
level_offset
#define level_offset(l)
Definition: intrax8.c:123
x8_get_prediction_chroma
static void x8_get_prediction_chroma(IntraX8Context *const w)
Definition: intrax8.c:350
x8_vlc_init
static av_cold void x8_vlc_init(void)
Definition: intrax8.c:59
dsp_x8_put_solidcolor
static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst, const ptrdiff_t linesize)
Definition: intrax8.c:506
av_clip_uint8
#define av_clip_uint8
Definition: common.h:104
ff_vlc_init_tables_from_lengths
const av_cold VLCElem * ff_vlc_init_tables_from_lengths(VLCInitState *state, int nb_bits, int nb_codes, const int8_t *lens, int lens_wrap, const void *symbols, int symbols_wrap, int symbols_size, int offset, int flags)
Definition: vlc.c:366
msmpeg4_vc1_data.h
extra_level
#define extra_level
Definition: intrax8.c:121
ff_init_scantable_permutation
av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation, enum idct_permutation_type perm_type)
Definition: idctdsp.c:39
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:246
VLC_INIT_STATE
#define VLC_INIT_STATE(_table)
Definition: vlc.h:214
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
int32_t
int32_t
Definition: audioconvert.c:56
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:385
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
DC_VLC_BITS
#define DC_VLC_BITS
Definition: intrax8.c:40
ff_wmv1_scantable
const uint8_t ff_wmv1_scantable[WMV1_SCANTABLE_COUNT][64]
Definition: msmpeg4_vc1_data.c:220
x8_select_ac_table
static void x8_select_ac_table(IntraX8Context *const w, int mode)
Definition: intrax8.c:94
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:44
j_orient_vlc
static const VLCElem * j_orient_vlc[2][4]
Definition: intrax8.c:50