The VC1 decoder currently follows the spec very closely when decoding MV differentials: The spec uses tables with contiguous indexes and derives four values from it using a pseudo-code procedure: Two flags and two values with a range of 0..5 each; the latter are obtained as the result resp. the remainder of dividing the index by 6 in the spec and in the earlier code.
Yet two flags can be encoded on two bits and the two values can be encoded on three bits each. Therefore the new symbols use the two lowest bits for the flags; the two other values are coded separately on three bits each. There is just one additional minor complication: The two three-bits values don't always exist; there is another mode. Instead of using an arbitrary six bit value for the higher bits that is different from all the values used by the ordinary mode this commit instead uses a negative number for it; this is possible by shifting the symbols as stored in the table (to make all fit into an uint8_t) and then shifting the codes downwards when creating the table. The latter is possible thanks to ff_init_vlc_from_lengths(). Switching to ff_init_vlc_from_lengths() also entails replacing 16bit codes by 8bit symbols, thereby saving space. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- libavcodec/vc1.c | 7 +- libavcodec/vc1_block.c | 30 ++++----- libavcodec/vc1data.c | 149 +++++++++++++++++++---------------------- libavcodec/vc1data.h | 14 +++- 4 files changed, 96 insertions(+), 104 deletions(-) diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 478fe7d66d..a7cc11de54 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -1414,9 +1414,10 @@ av_cold int ff_vc1_init_common(VC1Context *v) ff_vc1_cbpcy_p_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); ff_vc1_mv_diff_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 11]]; ff_vc1_mv_diff_vlc[i].table_allocated = vlc_offs[i * 3 + 12] - vlc_offs[i * 3 + 11]; - init_vlc(&ff_vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73, - ff_vc1_mv_diff_bits[i], 1, 1, - ff_vc1_mv_diff_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); + ff_init_vlc_from_lengths(&ff_vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73, + &ff_vc1_mv_diff_tabs[i][0][1], 2, + &ff_vc1_mv_diff_tabs[i][0][0], 2, 1, + -4, INIT_VLC_USE_NEW_STATIC, NULL); } for (int i = 0, ac_offset = 0; i < 8; i++) { ff_vc1_ac_coeff_table[i].table = &vlc_table[vlc_offs[i * 2 + 21]]; diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index 3ff67d83bf..6820ffb0d7 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -223,25 +223,16 @@ static void vc1_put_blocks_clamped(VC1Context *v, int put_signed) */ #define GET_MVDATA(_dmv_x, _dmv_y) \ do { \ - int index = 1 + get_vlc2(gb, ff_vc1_mv_diff_vlc[s->mv_table_index].table, \ + int symbol = get_vlc2(gb, ff_vc1_mv_diff_vlc[s->mv_table_index].table, \ VC1_MV_DIFF_VLC_BITS, 2); \ - if (index > 36) { \ - mb_has_coeffs = 1; \ - index -= 37; \ - } else \ - mb_has_coeffs = 0; \ - s->mb_intra = 0; \ - if (!index) { \ + mb_has_coeffs = symbol & 1; \ + symbol >>= 1; \ + s->mb_intra = symbol & 1; \ + symbol >>= 1; \ + if (!symbol) { \ _dmv_x = _dmv_y = 0; \ - } else if (index == 35) { \ - _dmv_x = get_bits(gb, v->k_x - 1 + s->quarter_sample); \ - _dmv_y = get_bits(gb, v->k_y - 1 + s->quarter_sample); \ - } else if (index == 36) { \ - _dmv_x = 0; \ - _dmv_y = 0; \ - s->mb_intra = 1; \ - } else { \ - int index1 = index % 6, sign, val; \ + } else if (symbol > 0) { \ + int index1 = symbol & 7, sign, val; \ _dmv_x = offset_table[1][index1]; \ val = size_table[index1] - (!s->quarter_sample && index1 == 5); \ if (val > 0) { \ @@ -250,7 +241,7 @@ do { \ _dmv_x = (sign ^ ((val >> 1) + _dmv_x)) - sign; \ } \ \ - index1 = index / 6; \ + index1 = symbol >> 3; \ _dmv_y = offset_table[1][index1]; \ val = size_table[index1] - (!s->quarter_sample && index1 == 5); \ if (val > 0) { \ @@ -258,6 +249,9 @@ do { \ sign = 0 - (val & 1); \ _dmv_y = (sign ^ ((val >> 1) + _dmv_y)) - sign; \ } \ + } else { \ + _dmv_x = get_bits(gb, v->k_x - 1 + s->quarter_sample); \ + _dmv_y = get_bits(gb, v->k_y - 1 + s->quarter_sample); \ } \ } while (0) diff --git a/libavcodec/vc1data.c b/libavcodec/vc1data.c index 57bc1fa9d6..be5cd3bffe 100644 --- a/libavcodec/vc1data.c +++ b/libavcodec/vc1data.c @@ -931,86 +931,75 @@ const uint8_t ff_vc1_subblkpat_tabs[3][15][2] = { }; /* MV differential tables, p265 */ -const uint16_t ff_vc1_mv_diff_codes[4][73] = { - { - 0, 2, 3, 8, 576, 3, 2, 6, - 5, 577, 578, 7, 8, 9, 40, 19, - 37, 82, 21, 22, 23, 579, 580, 166, - 96, 167, 49, 194, 195, 581, 582, 583, - 292, 293, 294, 13, 2, 7, 24, 50, - 102, 295, 13, 7, 8, 18, 50, 103, - 38, 20, 21, 22, 39, 204, 103, 23, - 24, 25, 104, 410, 105, 106, 107, 108, - 109, 220, 411, 442, 222, 443, 446, 447, - 7 /* 73 elements */ - }, - { - 0, 4, 5, 3, 4, 3, 4, 5, - 20, 6, 21, 44, 45, 46, 3008, 95, - 112, 113, 57, 3009, 3010, 116, 117, 3011, - 118, 3012, 3013, 3014, 3015, 3016, 3017, 3018, - 3019, 3020, 3021, 3022, 1, 4, 15, 160, - 161, 41, 6, 11, 42, 162, 43, 119, - 56, 57, 58, 163, 236, 237, 3023, 119, - 120, 242, 122, 486, 1512, 487, 246, 494, - 1513, 495, 1514, 1515, 1516, 1517, 1518, 1519, - 31 /* 73 elements */ - }, - { - 0, 512, 513, 514, 515, 2, 3, 258, - 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 1, 5, 287, 288, - 289, 290, 6, 7, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, 318, - 319 /* 73 elements */ - }, - { - 0, 1, 1, 2, 3, 4, 1, 5, - 4, 3, 5, 8, 6, 9, 10, 11, - 12, 7, 104, 14, 105, 4, 10, 15, - 11, 6, 14, 8, 106, 107, 108, 15, - 109, 9, 55, 10, 1, 2, 1, 2, - 3, 12, 6, 2, 6, 7, 28, 7, - 15, 8, 5, 18, 29, 152, 77, 24, - 25, 26, 39, 108, 13, 109, 55, 56, - 57, 116, 11, 153, 234, 235, 118, 119, - 15 /* 73 elements */ - } -}; -const uint8_t ff_vc1_mv_diff_bits[4][73] = { - { - 6, 7, 7, 8, 14, 6, 5, 6, 7, 14, 14, 6, 6, 6, 8, 9, - 10, 9, 7, 7, 7, 14, 14, 10, 9, 10, 8, 10, 10, 14, 14, 14, - 13, 13, 13, 6, 3, 5, 6, 8, 9, 13, 5, 4, 4, 5, 7, 9, - 6, 5, 5, 5, 6, 9, 8, 5, 5, 5, 7, 10, 7, 7, 7, 7, - 7, 8, 10, 9, 8, 9, 9, 9, 3 /* 73 elements */ - }, - { - 5, 7, 7, 6, 6, 5, 5, 6, 7, 5, 7, 8, 8, 8, 14, 9, - 9, 9, 8, 14, 14, 9, 9, 14, 9, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 2, 3, 6, 8, 8, 6, 3, 4, 6, 8, 6, 9, - 6, 6, 6, 8, 8, 8, 14, 7, 7, 8, 7, 9, 13, 9, 8, 9, - 13, 9, 13, 13, 13, 13, 13, 13, 5 /* 73 elements */ - - }, - { - 3, 12, 12, 12, 12, 3, 4, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 1, 5, 11, 11, 11, 11, 4, 4, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11 /* 73 elements */ - }, - { - 15, 11, 15, 15, 15, 15, 12, 15, 12, 11, 12, 12, 15, 12, 12, 12, - 12, 15, 15, 12, 15, 10, 11, 12, 11, 10, 11, 10, 15, 15, 15, 11, - 15, 10, 14, 10, 4, 4, 5, 7, 8, 9, 5, 3, 4, 5, 6, 8, - 5, 4, 3, 5, 6, 8, 7, 5, 5, 5, 6, 7, 9, 7, 6, 6, - 6, 7, 10, 8, 8, 8, 7, 7, 4 /* 73 elements */ - } +const uint8_t ff_vc1_mv_diff_tabs[4][73][2] = { + { /* Based upon table 246 */ + { 0x08, 6 }, { 0x0C, 7 }, { 0x10, 7 }, { 0x14, 8 }, { 0x18, 14 }, + { 0x34, 14 }, { 0x38, 14 }, { 0x74, 14 }, { 0x78, 14 }, { 0xA4, 14 }, + { 0xA8, 14 }, { 0xAC, 14 }, { 0xB0, 13 }, { 0xB4, 13 }, { 0x00, 13 }, + { 0x19, 13 }, { 0x58, 10 }, { 0x54, 9 }, { 0x30, 7 }, { 0x24, 6 }, + { 0x28, 5 }, { 0x2C, 6 }, { 0x44, 6 }, { 0x48, 6 }, { 0x4C, 6 }, + { 0x50, 8 }, { 0x64, 9 }, { 0x84, 10 }, { 0x8C, 10 }, { 0x68, 7 }, + { 0x6C, 7 }, { 0x70, 7 }, { 0x88, 9 }, { 0x94, 10 }, { 0x98, 10 }, + { 0x90, 8 }, { 0x11, 8 }, { 0x15, 9 }, { 0x39, 9 }, { 0x06, 6 }, + { 0x09, 5 }, { 0x05, 3 }, { 0x0D, 6 }, { 0x35, 7 }, { 0x59, 9 }, + { 0x79, 10 }, { 0xA5, 10 }, { 0x65, 8 }, { 0x25, 5 }, { 0x29, 4 }, + { 0x2D, 4 }, { 0x31, 5 }, { 0x45, 6 }, { 0x55, 6 }, { 0x49, 5 }, + { 0x4D, 5 }, { 0x51, 5 }, { 0x69, 5 }, { 0x6D, 5 }, { 0x71, 5 }, + { 0x75, 7 }, { 0x85, 7 }, { 0x89, 7 }, { 0x8D, 7 }, { 0x91, 7 }, + { 0x95, 7 }, { 0x99, 8 }, { 0xA9, 9 }, { 0xB1, 9 }, { 0xAD, 8 }, + { 0xB5, 9 }, { 0x01, 9 }, { 0x07, 3 }, /* 73 elements */ + }, + { /* Based upon table 247 */ + { 0x08, 5 }, { 0x0C, 7 }, { 0x10, 7 }, { 0x14, 6 }, { 0x18, 6 }, + { 0x2C, 6 }, { 0x24, 5 }, { 0x28, 5 }, { 0x30, 7 }, { 0x38, 7 }, + { 0x44, 8 }, { 0x48, 8 }, { 0x4C, 8 }, { 0x50, 14 }, { 0x6C, 14 }, + { 0x70, 14 }, { 0x84, 14 }, { 0x8C, 14 }, { 0x90, 14 }, { 0x94, 14 }, + { 0x98, 14 }, { 0xA4, 14 }, { 0xA8, 14 }, { 0xAC, 14 }, { 0xB0, 14 }, + { 0xB4, 14 }, { 0x00, 14 }, { 0x06, 14 }, { 0x65, 14 }, { 0x85, 13 }, + { 0x95, 13 }, { 0xA5, 13 }, { 0xA9, 13 }, { 0xAD, 13 }, { 0xB1, 13 }, + { 0xB5, 13 }, { 0x01, 13 }, { 0x54, 9 }, { 0x34, 5 }, { 0x58, 9 }, + { 0x64, 9 }, { 0x68, 8 }, { 0x74, 9 }, { 0x78, 9 }, { 0x88, 9 }, + { 0x39, 9 }, { 0x0D, 6 }, { 0x05, 2 }, { 0x09, 3 }, { 0x11, 8 }, + { 0x15, 8 }, { 0x31, 8 }, { 0x51, 8 }, { 0x19, 6 }, { 0x2D, 6 }, + { 0x35, 6 }, { 0x29, 4 }, { 0x25, 3 }, { 0x45, 6 }, { 0x49, 6 }, + { 0x4D, 6 }, { 0x55, 8 }, { 0x59, 8 }, { 0x69, 7 }, { 0x6D, 7 }, + { 0x71, 8 }, { 0x79, 9 }, { 0x89, 9 }, { 0x75, 7 }, { 0x8D, 8 }, + { 0x91, 9 }, { 0x99, 9 }, { 0x07, 5 }, /* 73 elements */ + }, + { /* Based upon table 248 */ + { 0x08, 3 }, { 0x0C, 12 }, { 0x10, 12 }, { 0x14, 12 }, { 0x18, 12 }, + { 0x2C, 11 }, { 0x30, 11 }, { 0x34, 11 }, { 0x38, 11 }, { 0x44, 11 }, + { 0x48, 11 }, { 0x4C, 11 }, { 0x50, 11 }, { 0x54, 11 }, { 0x58, 11 }, + { 0x64, 11 }, { 0x68, 11 }, { 0x6C, 11 }, { 0x70, 11 }, { 0x74, 11 }, + { 0x78, 11 }, { 0x84, 11 }, { 0x88, 11 }, { 0x8C, 11 }, { 0x90, 11 }, + { 0x94, 11 }, { 0x98, 11 }, { 0xA4, 11 }, { 0xA8, 11 }, { 0xAC, 11 }, + { 0xB0, 11 }, { 0xB4, 11 }, { 0x00, 11 }, { 0x06, 11 }, { 0x0D, 11 }, + { 0x11, 11 }, { 0x15, 11 }, { 0x19, 11 }, { 0x2D, 11 }, { 0x31, 11 }, + { 0x35, 11 }, { 0x39, 11 }, { 0x45, 11 }, { 0x49, 11 }, { 0x4D, 11 }, + { 0x51, 11 }, { 0x55, 11 }, { 0x59, 11 }, { 0x65, 11 }, { 0x69, 11 }, + { 0x6D, 11 }, { 0x71, 11 }, { 0x75, 11 }, { 0x79, 11 }, { 0x85, 11 }, + { 0x89, 11 }, { 0x8D, 11 }, { 0x91, 11 }, { 0x95, 11 }, { 0x99, 11 }, + { 0xA5, 11 }, { 0xA9, 11 }, { 0xAD, 11 }, { 0xB1, 11 }, { 0xB5, 11 }, + { 0x01, 11 }, { 0x07, 11 }, { 0x09, 5 }, { 0x28, 4 }, { 0x24, 3 }, + { 0x25, 4 }, { 0x29, 4 }, { 0x05, 1 }, /* 73 elements */ + }, + { /* Based upon table 249 */ + { 0x08, 15 }, { 0x10, 15 }, { 0x14, 15 }, { 0x18, 15 }, { 0x24, 15 }, + { 0x2C, 15 }, { 0x48, 15 }, { 0x64, 15 }, { 0x28, 12 }, { 0x0C, 11 }, + { 0x30, 12 }, { 0x38, 12 }, { 0x34, 11 }, { 0x44, 12 }, { 0x4C, 12 }, + { 0x50, 12 }, { 0x54, 12 }, { 0x58, 12 }, { 0x68, 15 }, { 0x70, 15 }, + { 0x98, 15 }, { 0xA4, 15 }, { 0xA8, 15 }, { 0xB0, 15 }, { 0x00, 14 }, + { 0x6C, 12 }, { 0x84, 12 }, { 0x74, 10 }, { 0x78, 11 }, { 0x88, 11 }, + { 0x8C, 10 }, { 0x90, 11 }, { 0xAC, 11 }, { 0x94, 10 }, { 0xB4, 10 }, + { 0x06, 10 }, { 0xA5, 10 }, { 0x15, 8 }, { 0x11, 7 }, { 0x19, 9 }, + { 0x85, 9 }, { 0x39, 8 }, { 0x0D, 5 }, { 0x05, 4 }, { 0x09, 4 }, + { 0x25, 5 }, { 0x31, 5 }, { 0x29, 3 }, { 0x2D, 4 }, { 0x35, 6 }, + { 0x55, 6 }, { 0x45, 5 }, { 0x49, 4 }, { 0x51, 5 }, { 0x59, 8 }, + { 0xA9, 8 }, { 0x65, 7 }, { 0x75, 6 }, { 0x4D, 3 }, { 0x69, 5 }, + { 0x6D, 5 }, { 0x71, 5 }, { 0x79, 7 }, { 0x89, 7 }, { 0x8D, 6 }, + { 0x91, 6 }, { 0x95, 6 }, { 0x99, 7 }, { 0xAD, 8 }, { 0xB1, 8 }, + { 0xB5, 7 }, { 0x01, 7 }, { 0x07, 4 }, /* 73 elements */ + }, }; /* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */ diff --git a/libavcodec/vc1data.h b/libavcodec/vc1data.h index 136e48e773..ccd2a0ec57 100644 --- a/libavcodec/vc1data.h +++ b/libavcodec/vc1data.h @@ -153,9 +153,17 @@ extern const uint8_t ff_vc1_ttblk_tabs[3][8][2]; * The symbols contain the Subblock Pattern. */ extern const uint8_t ff_vc1_subblkpat_tabs[3][15][2]; -/* MV differential tables, p265 */ -extern const uint16_t ff_vc1_mv_diff_codes[4][73]; -extern const uint8_t ff_vc1_mv_diff_bits[4][73]; +/* + * MV differential tables. Based upon tables #246-249. + * + * After offsetting the symbols by -4 the symbols contain all + * relevant information: The 0x01 bit contains 'more_present_flag', + * the 0x02 bit contains 'intra_flag'. The case of a negative symbol + * corresponds to the escape mechanism (i.e. index == 35 in the spec). + * Otherwise if the 0xFC bits are zero, both motion vectors are zero + * (index == 0 and index == 36 in the spec); otherwise the 0x1C bits + * contain the spec's index % 6 and bits 0xE0 contain index / 6. */ +extern const uint8_t ff_vc1_mv_diff_tabs[4][73][2]; /* Interlaced frame picture MBMODE VLC tables (p. 246, p. 360) */ extern const uint16_t ff_vc1_intfr_4mv_mbmode_codes[4][15]; -- 2.25.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".