2 * This file is part of FFmpeg.
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.
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.
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
21 * @brief IntraX8 (J-Frame) subdecoder, used by WMV2 and VC-1
24 #include "libavutil/avassert.h"
25 #include "libavutil/thread.h"
29 #include "msmpeg4data.h"
30 #include "intrax8huf.h"
32 #include "intrax8dsp.h"
33 #include "mpegutils.h"
35 #define VLC_BUFFER_SIZE 28150
37 #define MAX_TABLE_DEPTH(table_bits, max_bits) \
38 ((max_bits + table_bits - 1) / table_bits)
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)
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]
52 static av_cold void x8_init_vlc(VLC *vlc, int nb_bits, int nb_codes,
53 int *offset, const uint8_t table[][2])
55 static VLC_TYPE vlc_buf[VLC_BUFFER_SIZE][2];
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;
64 static av_cold void x8_vlc_init(void)
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]);
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]);
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]);
90 av_assert2(offset == VLC_BUFFER_SIZE);
93 static void x8_reset_vlc_tables(IntraX8Context *w)
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;
100 static inline void x8_select_ac_table(IntraX8Context *const w, int mode)
104 av_assert2(mode < 4);
106 if (w->j_ac_vlc[mode])
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]);
115 static inline int x8_get_orient_vlc(IntraX8Context *w)
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];
122 return get_vlc2(w->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD);
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),
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),
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),
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),
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),
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),
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),
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),
172 static void x8_get_ac_rlf(IntraX8Context *const w, const int mode,
173 int *const run, int *const level, int *const final)
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);
180 if (i < 46) { // [0-45]
184 *final = // prevent 'may be used uninitialized'
185 *run = 64; // this would cause error exit in the ac loop
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
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)
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);
210 } else if (i < 73) { // [46-72]
215 sm = ac_decode_table[i];
217 e = get_bits(w->gb, sm & 0xF);
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,
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;
238 *level = get_bits(w->gb, 7 - 3 * (i & 1));
239 *run = get_bits(w->gb, 6);
240 *final = get_bits1(w->gb);
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,
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,
252 static int x8_get_dc_rlf(IntraX8Context *const w, const int mode,
253 int *const level, int *const final)
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];
264 i = get_vlc2(w->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD);
266 /* (i >= 17) { i -= 17; final =1; } */
275 c = (i + 1) >> 1; // hackish way to calculate dc_extra_sbits[]
278 e = get_bits(w->gb, c); // get the extra bits
279 i = dc_index_offset[i] + (e >> 1);
281 e = -(e & 1); // 0, 0xffffff
282 *level = (i ^ e) - e; // (i ^ 0) - 0, (i ^ 0xff) - (-1)
288 static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma)
294 w->dsp.setup_spatial_compensation(w->dest[chroma], w->scratchpad,
295 w->frame->linesize[chroma > 0],
296 &range, &sum, w->edges);
298 w->orient = w->chroma_orient;
299 quant = w->quant_dc_chroma;
305 if (range < quant || range < 3) {
308 // yep you read right, a +-1 idct error may break decoding!
312 // ((1 << 17) + 9) / (8 + 8 + 1 + 2) = 6899
313 w->predicted_dc = sum * 6899 >> 17;
319 av_assert2(w->orient < 3);
320 if (range < 2 * w->quant) {
321 if ((w->edges & 3) == 0) {
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 },
336 w->raw_orient = x8_get_orient_vlc(w);
337 if (w->raw_orient < 0)
339 av_assert2(w->raw_orient < 12);
340 av_assert2(w->orient < 3);
341 w->orient=prediction_table[w->orient][w->raw_orient];
346 static void x8_update_predictions(IntraX8Context *const w, const int orient,
349 w->prediction_table[w->mb_x * 2 + (w->mb_y & 1)] = (est_run << 2) + 1 * (orient == 4) + 2 * (orient == 8);
351 * y = 2n + 0 -> // 0 2 4
352 * y = 2n + 1 -> // 1 3 5
356 static void x8_get_prediction_chroma(IntraX8Context *const w)
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
363 // lut_co[8] = {inv,4,8,8, inv,4,8,8} <- => {1,1,0,0;1,1,0,0} => 0xCC
365 w->chroma_orient = 4 << ((0xCC >> w->edges) & 1);
368 // block[x - 1][y | 1 - 1)]
369 w->chroma_orient = (w->prediction_table[2 * w->mb_x - 2] & 0x03) << 2;
372 static void x8_get_prediction(IntraX8Context *const w)
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));
380 switch (w->edges & 3) {
384 // take the one from the above block[0][y - 1]
385 w->est_run = w->prediction_table[!(w->mb_y & 1)] >> 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;
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]
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);
415 i = (0xFFEAF4C4 >> (2 * b + 8 * a)) & 3;
419 w->orient = (0xFFEAD8 >> (2 * c + 8 * (w->quant > 12))) & 3;
422 * ->{ 0, 1, 0, pad },
429 * -> 11 10 '10 10 '11 11'01 00 '11 00'01 00 => 0xEAF4C4
437 * -> 11 10'10 10 '11 01'10 00 => 0xEAD8
441 static void x8_ac_compensation(IntraX8Context *const w, const int direction,
445 #define B(x,y) w->block[0][w->idct_permutation[(x) + (y) * 8]]
446 #define T(x) ((x) * dc_level + 0x8000) >> 16;
489 w->block_last_index[0] = FFMAX(w->block_last_index[0], 7 * 8);
497 w->block_last_index[0] = FFMAX(w->block_last_index[0], 7 * 8);
505 w->block_last_index[0] = FFMAX(w->block_last_index[0], 7);
512 static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst,
513 const ptrdiff_t linesize)
516 for (k = 0; k < 8; k++) {
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,
533 static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma)
536 int final, run, level;
537 int ac_mode, dc_mode, est_run, dc_level;
540 int use_quant_matrix;
543 av_assert2(w->orient < 12);
544 w->bdsp.clear_block(w->block[0]);
549 dc_mode = !!w->est_run; // 0, 1
551 if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final))
555 if (!final) { // decode ac
556 use_quant_matrix = w->use_quant_matrix;
559 est_run = 64; // not used
561 if (w->raw_orient < 3)
562 use_quant_matrix = 0;
564 if (w->raw_orient > 4) {
568 if (w->est_run > 1) {
570 est_run = w->est_run;
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;
586 x8_select_ac_table(w, 3);
589 x8_get_ac_rlf(w, ac_mode, &run, &level, &final);
593 // this also handles vlc error in x8_get_ac_rlf
596 level = (level + 1) * w->dquant;
599 sign = -get_bits1(w->gb);
600 level = (level ^ sign) - sign;
602 if (use_quant_matrix)
603 level = (level * quant_table[pos]) >> 8;
605 w->block[0][scantable[pos]] = level;
608 w->block_last_index[0] = pos;
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;
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;
621 dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3),
623 w->frame->linesize[!!chroma]);
627 zeros_only = dc_level == 0;
630 w->block[0][0] = dc_level * w->quant;
632 w->block[0][0] = dc_level * w->quant_dc_chroma;
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) {
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]);
647 dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma],
648 w->frame->linesize[!!chroma]);
650 w->dsp.spatial_compensation[w->orient](w->scratchpad,
652 w->frame->linesize[!!chroma]);
655 w->wdsp.idct_add(w->dest[chroma],
656 w->frame->linesize[!!chroma],
661 x8_update_predictions(w, w->orient, n);
664 uint8_t *ptr = w->dest[chroma];
665 ptrdiff_t linesize = w->frame->linesize[!!chroma];
667 if (!((w->edges & 2) || (zeros_only && (w->orient | 4) == 4)))
668 w->dsp.h_loop_filter(ptr, linesize, w->quant);
670 if (!((w->edges & 1) || (zeros_only && (w->orient | 8) == 8)))
671 w->dsp.v_loop_filter(ptr, linesize, w->quant);
676 // FIXME maybe merge with ff_*
677 static void x8_init_block_index(IntraX8Context *w, AVFrame *frame)
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];
684 w->dest[0] = frame->data[0];
685 w->dest[1] = frame->data[1];
686 w->dest[2] = frame->data[2];
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;
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)
700 static AVOnce init_static_once = AV_ONCE_INIT;
704 w->mb_width = mb_width;
705 w->mb_height = mb_height;
707 w->block_last_index = block_last_index;
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);
714 ff_wmv2dsp_init(&w->wdsp);
716 ff_init_scantable_permutation(w->idct_permutation,
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]);
726 ff_intrax8dsp_init(&w->dsp);
727 ff_blockdsp_init(&w->bdsp, avctx);
729 ff_thread_once(&init_static_once, x8_vlc_init);
734 av_cold void ff_intrax8_common_end(IntraX8Context *w)
736 av_freep(&w->prediction_table);
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)
748 w->quant = dquant >> 1;
749 w->qsum = quant_offset;
751 w->loopfilter = loopfilter;
752 w->use_quant_matrix = get_bits1(w->gb);
757 w->divide_quant_dc_luma = ((1 << 16) + (w->quant >> 1)) / w->quant;
759 w->quant_dc_chroma = w->quant;
760 w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
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;
765 x8_reset_vlc_tables(w);
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)
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))
776 if (x8_decode_intra_mb(w, 0))
779 if (w->mb_x & w->mb_y & 1) {
780 x8_get_prediction_chroma(w);
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))
788 x8_setup_spatial_predictor(w, 2);
789 if (x8_decode_intra_mb(w, 2))
795 pict->qscale_table[mb_xy] = w->quant;
801 ff_draw_horiz_band(w->avctx, w->frame, w->frame,
802 (w->mb_y - 1) * 8, 16,
803 PICT_FRAME, 0, lowdelay);