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