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
x8_init_vlc(VLC * vlc,int nb_bits,int nb_codes,int * offset,const uint8_t table[][2])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 VLCElem vlc_buf[VLC_BUFFER_SIZE];
56
57 vlc->table = &vlc_buf[*offset];
58 vlc->table_allocated = VLC_BUFFER_SIZE - *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
x8_vlc_init(void)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
x8_reset_vlc_tables(IntraX8Context * w)93 static void x8_reset_vlc_tables(IntraX8Context *w)
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
x8_select_ac_table(IntraX8Context * const w,int mode)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
x8_get_orient_vlc(IntraX8Context * w)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
122 return get_vlc2(w->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD);
123 }
124
125 #define extra_bits(eb) (eb) // 3 bits
126 #define extra_run (0xFF << 8) // 1 bit
127 #define extra_level (0x00 << 8) // 1 bit
128 #define run_offset(r) ((r) << 16) // 6 bits
129 #define level_offset(l) ((l) << 24) // 5 bits
130 static const uint32_t ac_decode_table[] = {
131 /* 46 */ extra_bits(3) | extra_run | run_offset(16) | level_offset(0),
132 /* 47 */ extra_bits(3) | extra_run | run_offset(24) | level_offset(0),
133 /* 48 */ extra_bits(2) | extra_run | run_offset(4) | level_offset(1),
134 /* 49 */ extra_bits(3) | extra_run | run_offset(8) | level_offset(1),
135
136 /* 50 */ extra_bits(5) | extra_run | run_offset(32) | level_offset(0),
137 /* 51 */ extra_bits(4) | extra_run | run_offset(16) | level_offset(1),
138
139 /* 52 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(4),
140 /* 53 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(8),
141 /* 54 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(12),
142 /* 55 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(16),
143 /* 56 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(24),
144
145 /* 57 */ extra_bits(2) | extra_level | run_offset(1) | level_offset(3),
146 /* 58 */ extra_bits(3) | extra_level | run_offset(1) | level_offset(7),
147
148 /* 59 */ extra_bits(2) | extra_run | run_offset(16) | level_offset(0),
149 /* 60 */ extra_bits(2) | extra_run | run_offset(20) | level_offset(0),
150 /* 61 */ extra_bits(2) | extra_run | run_offset(24) | level_offset(0),
151 /* 62 */ extra_bits(2) | extra_run | run_offset(28) | level_offset(0),
152 /* 63 */ extra_bits(4) | extra_run | run_offset(32) | level_offset(0),
153 /* 64 */ extra_bits(4) | extra_run | run_offset(48) | level_offset(0),
154
155 /* 65 */ extra_bits(2) | extra_run | run_offset(4) | level_offset(1),
156 /* 66 */ extra_bits(3) | extra_run | run_offset(8) | level_offset(1),
157 /* 67 */ extra_bits(4) | extra_run | run_offset(16) | level_offset(1),
158
159 /* 68 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(4),
160 /* 69 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(8),
161 /* 70 */ extra_bits(4) | extra_level | run_offset(0) | level_offset(16),
162
163 /* 71 */ extra_bits(2) | extra_level | run_offset(1) | level_offset(3),
164 /* 72 */ extra_bits(3) | extra_level | run_offset(1) | level_offset(7),
165 };
166 #undef extra_bits
167 #undef extra_run
168 #undef extra_level
169 #undef run_offset
170 #undef level_offset
171
x8_get_ac_rlf(IntraX8Context * const w,const int mode,int * const run,int * const level,int * const final)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
x8_get_dc_rlf(IntraX8Context * const w,const int mode,int * const level,int * const final)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
x8_setup_spatial_predictor(IntraX8Context * const w,const int chroma)288 static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma)
289 {
290 int range;
291 int sum;
292 int quant;
293
294 w->dsp.setup_spatial_compensation(w->dest[chroma], w->scratchpad,
295 w->frame->linesize[chroma > 0],
296 &range, &sum, w->edges);
297 if (chroma) {
298 w->orient = w->chroma_orient;
299 quant = w->quant_dc_chroma;
300 } else {
301 quant = w->quant;
302 }
303
304 w->flat_dc = 0;
305 if (range < quant || range < 3) {
306 w->orient = 0;
307
308 // yep you read right, a +-1 idct error may break decoding!
309 if (range < 3) {
310 w->flat_dc = 1;
311 sum += 9;
312 // ((1 << 17) + 9) / (8 + 8 + 1 + 2) = 6899
313 w->predicted_dc = sum * 6899 >> 17;
314 }
315 }
316 if (chroma)
317 return 0;
318
319 av_assert2(w->orient < 3);
320 if (range < 2 * w->quant) {
321 if ((w->edges & 3) == 0) {
322 if (w->orient == 1)
323 w->orient = 11;
324 if (w->orient == 2)
325 w->orient = 10;
326 } else {
327 w->orient = 0;
328 }
329 w->raw_orient = 0;
330 } else {
331 static const uint8_t prediction_table[3][12] = {
332 { 0, 8, 4, 10, 11, 2, 6, 9, 1, 3, 5, 7 },
333 { 4, 0, 8, 11, 10, 3, 5, 2, 6, 9, 1, 7 },
334 { 8, 0, 4, 10, 11, 1, 7, 2, 6, 9, 3, 5 },
335 };
336 w->raw_orient = x8_get_orient_vlc(w);
337 if (w->raw_orient < 0)
338 return -1;
339 av_assert2(w->raw_orient < 12);
340 av_assert2(w->orient < 3);
341 w->orient=prediction_table[w->orient][w->raw_orient];
342 }
343 return 0;
344 }
345
x8_update_predictions(IntraX8Context * const w,const int orient,const int est_run)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
x8_get_prediction_chroma(IntraX8Context * const w)356 static void x8_get_prediction_chroma(IntraX8Context *const w)
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
x8_get_prediction(IntraX8Context * const w)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
x8_ac_compensation(IntraX8Context * const w,const int direction,const int dc_level)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
dsp_x8_put_solidcolor(const uint8_t pix,uint8_t * dst,const ptrdiff_t linesize)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
x8_decode_intra_mb(IntraX8Context * const w,const int chroma)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
613 : w->divide_quant_dc_chroma;
614 int32_t dc_quant = !chroma ? w->quant
615 : w->quant_dc_chroma;
616
617 // original intent dc_level += predicted_dc/quant;
618 // but it got lost somewhere in the rounding
619 dc_level += (w->predicted_dc * divide_quant + (1 << 12)) >> 13;
620
621 dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3),
622 w->dest[chroma],
623 w->frame->linesize[!!chroma]);
624
625 goto block_placed;
626 }
627 zeros_only = dc_level == 0;
628 }
629 if (!chroma)
630 w->block[0][0] = dc_level * w->quant;
631 else
632 w->block[0][0] = dc_level * w->quant_dc_chroma;
633
634 // there is !zero_only check in the original, but dc_level check is enough
635 if ((unsigned int) (dc_level + 1) >= 3 && (w->edges & 3) != 3) {
636 int direction;
637 /* ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 }; <-
638 * -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 => 0x6A017C */
639 direction = (0x6A017C >> (w->orient * 2)) & 3;
640 if (direction != 3) {
641 // modify block_last[]
642 x8_ac_compensation(w, direction, w->block[0][0]);
643 }
644 }
645
646 if (w->flat_dc) {
647 dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma],
648 w->frame->linesize[!!chroma]);
649 } else {
650 w->dsp.spatial_compensation[w->orient](w->scratchpad,
651 w->dest[chroma],
652 w->frame->linesize[!!chroma]);
653 }
654 if (!zeros_only)
655 w->wdsp.idct_add(w->dest[chroma],
656 w->frame->linesize[!!chroma],
657 w->block[0]);
658
659 block_placed:
660 if (!chroma)
661 x8_update_predictions(w, w->orient, n);
662
663 if (w->loopfilter) {
664 uint8_t *ptr = w->dest[chroma];
665 ptrdiff_t linesize = w->frame->linesize[!!chroma];
666
667 if (!((w->edges & 2) || (zeros_only && (w->orient | 4) == 4)))
668 w->dsp.h_loop_filter(ptr, linesize, w->quant);
669
670 if (!((w->edges & 1) || (zeros_only && (w->orient | 8) == 8)))
671 w->dsp.v_loop_filter(ptr, linesize, w->quant);
672 }
673 return 0;
674 }
675
676 // FIXME maybe merge with ff_*
x8_init_block_index(IntraX8Context * w,AVFrame * frame)677 static void x8_init_block_index(IntraX8Context *w, AVFrame *frame)
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
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)694 av_cold int ff_intrax8_common_init(AVCodecContext *avctx,
695 IntraX8Context *w, IDCTDSPContext *idsp,
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
716 ff_init_scantable_permutation(w->idct_permutation,
717 w->wdsp.idct_perm);
718
719 ff_init_scantable(w->idct_permutation, &w->scantable[0],
720 ff_wmv1_scantable[0]);
721 ff_init_scantable(w->idct_permutation, &w->scantable[1],
722 ff_wmv1_scantable[2]);
723 ff_init_scantable(w->idct_permutation, &w->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
ff_intrax8_common_end(IntraX8Context * w)734 av_cold void ff_intrax8_common_end(IntraX8Context *w)
735 {
736 av_freep(&w->prediction_table);
737 }
738
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)739 int ff_intrax8_decode_picture(IntraX8Context *w, Picture *pict,
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;
760 w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
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 }
765 x8_reset_vlc_tables(w);
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++) {
773 x8_get_prediction(w);
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) {
780 x8_get_prediction_chroma(w);
781
782 /* when setting up chroma, no vlc is read,
783 * so no error condition can be reached */
784 x8_setup_spatial_predictor(w, 1);
785 if (x8_decode_intra_mb(w, 1))
786 goto error;
787
788 x8_setup_spatial_predictor(w, 2);
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 }
812