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