[FFmpeg-devel] [PATCH 083/114] avcodec/vc1: Use symbols table to decode MV differentials

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Tue Nov 10 12:48:20 EET 2020


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 uses the two
lowest bits for the flags; the two other values are coded separately
on three bits each. There is just one more 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.rheinhardt at gmail.com>
---
 libavcodec/vc1.c       |   7 +-
 libavcodec/vc1_block.c |  30 ++++-----
 libavcodec/vc1data.c   | 149 +++++++++++++++++++----------------------
 libavcodec/vc1data.h   |   3 +-
 4 files changed, 86 insertions(+), 103 deletions(-)

diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c
index 599a77af31..8c8d701ef8 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);
         }
         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 bde500ebe5..701d285561 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] = {
+    {
+        { 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 */
+    },
+    {
+        { 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 */
+    },
+    {
+        { 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 */
+    },
+    {
+        { 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 04cc9a22bf..5a071eb972 100644
--- a/libavcodec/vc1data.h
+++ b/libavcodec/vc1data.h
@@ -152,8 +152,7 @@ extern const uint8_t ff_vc1_ttblk_tabs[3][8][2];
 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];
+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



More information about the ffmpeg-devel mailing list