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 "msmpeg4data.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 {
55  static VLC_TYPE vlc_buf[VLC_BUFFER_SIZE][2];
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++)
79  x8_init_vlc(&j_dc_vlc[i][j], DC_VLC_BITS, 34, &offset,
80  x8_dc_quant_table[i][j]);
81 
82 // set orient tables
83  for (i = 0; i < 2; i++)
84  x8_init_vlc(&j_orient_vlc[0][i], OR_VLC_BITS, 12,
85  &offset, x8_orient_highquant_table[i]);
86  for (i = 0; i < 4; i++)
87  x8_init_vlc(&j_orient_vlc[1][i], OR_VLC_BITS, 12,
88  &offset, x8_orient_lowquant_table[i]);
89 
90  av_assert2(offset == VLC_BUFFER_SIZE);
91 }
92 
94 {
95  memset(w->j_dc_vlc, 0, sizeof(w->j_dc_vlc));
96  memset(w->j_ac_vlc, 0, sizeof(w->j_ac_vlc));
97  w->j_orient_vlc = 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[mode])
107  return;
108 
109  table_index = get_bits(w->gb, 3);
110  // 2 modes use same tables
111  w->j_ac_vlc[mode] = &j_ac_vlc[w->quant < 13][mode >> 1][table_index];
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) {
118  int table_index = get_bits(w->gb, 1 + (w->quant < 13));
119  w->j_orient_vlc = &j_orient_vlc[w->quant < 13][table_index];
120  }
121 
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[mode]->table, 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[mode]) {
259  int table_index = get_bits(w->gb, 3);
260  // 4 modes, same table
261  w->j_dc_vlc[mode] = &j_dc_vlc[w->quant < 13][table_index];
262  }
263 
264  i = get_vlc2(w->gb, w->j_dc_vlc[mode]->table, 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  };
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->scantable[(0x928548 >> (2 * w->orient)) & 3].permutated;
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
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 {
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 
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->idsp = *idsp;
704  w->mb_width = mb_width;
705  w->mb_height = mb_height;
706  w->block = block;
707  w->block_last_index = block_last_index;
708 
709  // two rows, 2 blocks per cannon mb
710  w->prediction_table = av_mallocz(w->mb_width * 2 * 2);
711  if (!w->prediction_table)
712  return AVERROR(ENOMEM);
713 
714  ff_wmv2dsp_init(&w->wdsp);
715 
717  w->wdsp.idct_perm);
718 
720  ff_wmv1_scantable[0]);
722  ff_wmv1_scantable[2]);
724  ff_wmv1_scantable[3]);
725 
726  ff_intrax8dsp_init(&w->dsp);
727  ff_blockdsp_init(&w->bdsp, avctx);
728 
729  ff_thread_once(&init_static_once, x8_vlc_init);
730 
731  return 0;
732 }
733 
735 {
737 }
738 
740  GetBitContext *gb, int *mb_x, int *mb_y,
741  int dquant, int quant_offset,
742  int loopfilter, int lowdelay)
743 {
744  int mb_xy;
745 
746  w->gb = gb;
747  w->dquant = dquant;
748  w->quant = dquant >> 1;
749  w->qsum = quant_offset;
750  w->frame = pict->f;
751  w->loopfilter = loopfilter;
752  w->use_quant_matrix = get_bits1(w->gb);
753 
754  w->mb_x = *mb_x;
755  w->mb_y = *mb_y;
756 
757  w->divide_quant_dc_luma = ((1 << 16) + (w->quant >> 1)) / w->quant;
758  if (w->quant < 5) {
759  w->quant_dc_chroma = w->quant;
761  } else {
762  w->quant_dc_chroma = w->quant + ((w->quant + 3) >> 3);
763  w->divide_quant_dc_chroma = ((1 << 16) + (w->quant_dc_chroma >> 1)) / w->quant_dc_chroma;
764  }
766 
767  for (w->mb_y = 0; w->mb_y < w->mb_height * 2; w->mb_y++) {
768  x8_init_block_index(w, w->frame);
769  mb_xy = (w->mb_y >> 1) * (w->mb_width + 1);
770  if (get_bits_left(gb) < 1)
771  goto error;
772  for (w->mb_x = 0; w->mb_x < w->mb_width * 2; w->mb_x++) {
774  if (x8_setup_spatial_predictor(w, 0))
775  goto error;
776  if (x8_decode_intra_mb(w, 0))
777  goto error;
778 
779  if (w->mb_x & w->mb_y & 1) {
781 
782  /* when setting up chroma, no vlc is read,
783  * so no error condition can be reached */
785  if (x8_decode_intra_mb(w, 1))
786  goto error;
787 
789  if (x8_decode_intra_mb(w, 2))
790  goto error;
791 
792  w->dest[1] += 8;
793  w->dest[2] += 8;
794 
795  pict->qscale_table[mb_xy] = w->quant;
796  mb_xy++;
797  }
798  w->dest[0] += 8;
799  }
800  if (w->mb_y & 1)
801  ff_draw_horiz_band(w->avctx, w->frame, w->frame,
802  (w->mb_y - 1) * 8, 16,
803  PICT_FRAME, 0, lowdelay);
804  }
805 
806 error:
807  *mb_x = w->mb_x;
808  *mb_y = w->mb_y;
809 
810  return 0;
811 }
#define extra_bits(eb)
Definition: intrax8.c:125
static void x8_get_prediction(IntraX8Context *const w)
Definition: intrax8.c:372
#define NULL
Definition: coverity.c:32
int table_size
Definition: vlc.h:29
#define DC_VLC_MTD
Definition: intrax8.c:44
int predicted_dc
Definition: intrax8.h:66
This structure describes decoded (raw) audio or video data.
Definition: frame.h:314
WMV2DSPContext wdsp
Definition: intrax8.h:39
static void x8_update_predictions(IntraX8Context *const w, const int orient, const int est_run)
Definition: intrax8.c:346
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
#define extra_run
Definition: intrax8.c:126
#define AC_VLC_BITS
Definition: intrax8.c:41
void(* clear_block)(int16_t *block)
Definition: blockdsp.h:36
uint8_t * dest[3]
Definition: intrax8.h:60
av_cold void ff_blockdsp_init(BlockDSPContext *c, AVCodecContext *avctx)
Definition: blockdsp.c:60
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:36
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:237
uint8_t permutated[64]
Definition: idctdsp.h:33
uint8_t run
Definition: svq3.c:205
static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma)
Definition: intrax8.c:533
static void error(const char *err)
void ff_draw_horiz_band(AVCodecContext *avctx, AVFrame *cur, AVFrame *last, int y, int h, int picture_structure, int first_field, int low_delay)
Draw a horizontal band if supported.
Definition: mpegutils.c:51
av_cold int ff_intrax8_common_init(AVCodecContext *avctx, IntraX8Context *w, IDCTDSPContext *idsp, int16_t(*block)[64], int block_last_index[12], int mb_width, int mb_height)
Initialize IntraX8 frame decoder.
Definition: intrax8.c:694
static void x8_reset_vlc_tables(IntraX8Context *w)
Definition: intrax8.c:93
#define OR_VLC_MTD
Definition: intrax8.c:46
IDCTDSPContext idsp
Definition: intrax8.h:47
static const uint8_t x8_orient_highquant_table[2][12][2]
Definition: intrax8huf.h:43
The exact code depends on how similar the blocks are and how related they are to the block
uint8_t
#define av_cold
Definition: attributes.h:88
int idct_perm
Definition: wmv2dsp.h:32
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
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
#define AC_VLC_MTD
Definition: intrax8.c:45
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
MSMPEG4 data tables.
int chroma_orient
Definition: intrax8.h:68
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:739
bitstream reader API header.
int loopfilter
Definition: intrax8.h:52
#define AVOnce
Definition: thread.h:172
#define run_offset(r)
Definition: intrax8.c:128
static const uint16_t table[]
Definition: prosumer.c:206
static void x8_init_block_index(IntraX8Context *w, AVFrame *frame)
Definition: intrax8.c:677
BlockDSPContext bdsp
Definition: intrax8.h:48
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
static const uint16_t mask[17]
Definition: lzw.c:38
static av_always_inline void chroma(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1631
static const uint8_t x8_ac_quant_table[2][2][8][77][2]
Definition: intrax8huf.h:207
static int x8_get_orient_vlc(IntraX8Context *w)
Definition: intrax8.c:115
static const int16_t quant_table[64]
Definition: intrax8.c:522
AVFrame * frame
Definition: intrax8.h:53
unsigned int pos
Definition: spdifenc.c:410
int * block_last_index
last nonzero coefficient in block
Definition: intrax8.h:42
simple assert() macros that are a bit more flexible than ISO C assert().
#define OR_VLC_BITS
Definition: intrax8.c:42
av_cold void ff_wmv2dsp_init(WMV2DSPContext *c)
Definition: wmv2dsp.c:251
#define FFMAX(a, b)
Definition: common.h:94
Definition: vlc.h:26
static const uint8_t x8_dc_quant_table[2][8][34][2]
Definition: intrax8huf.h:55
uint8_t scratchpad[42]
Definition: intrax8.h:61
const uint8_t ff_wmv1_scantable[WMV1_SCANTABLE_COUNT][64]
Definition: msmpeg4data.c:1809
#define b
Definition: input.c:41
#define FFMIN(a, b)
Definition: common.h:96
av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation, enum idct_permutation_type perm_type)
Definition: idctdsp.c:50
void(* setup_spatial_compensation)(uint8_t *src, uint8_t *dst, ptrdiff_t stride, int *range, int *sum, int edges)
Definition: intrax8dsp.h:31
av_cold void ff_intrax8_common_end(IntraX8Context *w)
Destroy IntraX8 frame structure.
Definition: intrax8.c:734
uint8_t w
Definition: llviddspenc.c:39
VLC * j_ac_vlc[4]
Definition: intrax8.h:30
static VLC j_dc_vlc[2][8]
Definition: intrax8.c:49
Picture.
Definition: mpegpicture.h:45
int32_t
static const uint32_t ac_decode_table[]
Definition: intrax8.c:130
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
static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE(*table)[2], int bits, int max_depth)
Parse a vlc code.
Definition: get_bits.h:797
if(ret)
static const uint8_t dc_index_offset[]
Definition: intrax8.c:248
int table_allocated
Definition: vlc.h:29
static VLC j_ac_vlc[2][2][8]
Definition: intrax8.c:48
#define AV_ONCE_INIT
Definition: thread.h:173
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:345
main external API structure.
Definition: avcodec.h:531
int16_t(* block)[64]
Definition: intrax8.h:43
void(* h_loop_filter)(uint8_t *src, ptrdiff_t stride, int qscale)
Definition: intrax8dsp.h:27
#define level_offset(l)
Definition: intrax8.c:129
IntraX8DSPContext dsp
Definition: intrax8.h:46
void(* spatial_compensation[12])(uint8_t *src, uint8_t *dst, ptrdiff_t stride)
Definition: intrax8dsp.h:29
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
int quant_dc_chroma
Definition: intrax8.h:57
#define extra_level
Definition: intrax8.c:127
struct AVFrame * f
Definition: mpegpicture.h:46
int ff_init_vlc_from_lengths(VLC *vlc_arg, 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: bitstream.c:381
static const uint8_t x8_orient_lowquant_table[4][12][2]
Definition: intrax8huf.h:24
uint8_t idct_permutation[64]
Definition: intrax8.h:40
av_cold void ff_intrax8dsp_init(IntraX8DSPContext *dsp)
Definition: intrax8dsp.c:448
ScanTable scantable[3]
Definition: intrax8.h:38
const uint8_t * quant
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:328
uint8_t level
Definition: svq3.c:206
#define DC_VLC_BITS
Definition: intrax8.c:40
GetBitContext * gb
Definition: intrax8.h:54
int8_t * qscale_table
Definition: mpegpicture.h:50
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
static void x8_select_ac_table(IntraX8Context *const w, int mode)
Definition: intrax8.c:100
int divide_quant_dc_luma
Definition: intrax8.h:58
int mb_width
Definition: intrax8.h:74
#define T(x)
static int x8_get_dc_rlf(IntraX8Context *const w, const int mode, int *const level, int *const final)
Definition: intrax8.c:252
#define B(x, y)
VLC * j_dc_vlc[3]
Definition: intrax8.h:32
void(* v_loop_filter)(uint8_t *src, ptrdiff_t stride, int qscale)
Definition: intrax8dsp.h:26
#define PICT_FRAME
Definition: mpegutils.h:39
#define VLC_BUFFER_SIZE
Definition: intrax8.c:35
av_cold void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable)
Definition: idctdsp.c:29
AVCodecContext * avctx
Definition: intrax8.h:41
static int ff_thread_once(char *control, void(*routine)(void))
Definition: thread.h:175
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
VLC_TYPE(* table)[2]
code, bits
Definition: vlc.h:28
int raw_orient
Definition: intrax8.h:67
static void x8_get_prediction_chroma(IntraX8Context *const w)
Definition: intrax8.c:356
static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma)
Definition: intrax8.c:288
static av_cold void x8_vlc_init(void)
Definition: intrax8.c:64
int divide_quant_dc_chroma
Definition: intrax8.h:59
static VLC_TYPE vlc_buf[16716][2]
Definition: clearvideo.c:86
int mb_height
Definition: intrax8.h:74
#define av_freep(p)
static VLC j_orient_vlc[2][4]
Definition: intrax8.c:50
#define VLC_TYPE
Definition: vlc.h:24
VLC * j_orient_vlc
Definition: intrax8.h:31
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
#define INIT_VLC_STATIC_OVERLONG
Definition: vlc.h:96
void(* idct_add)(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
Definition: wmv2dsp.h:27
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83
static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst, const ptrdiff_t linesize)
Definition: intrax8.c:512
int i
Definition: input.c:407
int use_quant_matrix
Definition: intrax8.h:34
uint8_t * prediction_table
Definition: intrax8.h:37
static void x8_ac_compensation(IntraX8Context *const w, const int direction, const int dc_level)
Definition: intrax8.c:441