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