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