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