diff mbox series

[FFmpeg-devel,v2,104/162] avcodec/vc1: Use symbols table to parse macroblock mode

Message ID 20201120073327.820745-5-andreas.rheinhardt@gmail.com
State New
Headers show
Series VLC, esp. init_vlc patches
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished

Commit Message

Andreas Rheinhardt Nov. 20, 2020, 7:32 a.m. UTC
Expressions like array[get_vlc2()] can be optimized by using a symbols
table if the array is always the same for a given VLC. This requirement
is fulfilled for the VLCs used to parse the macroblock mode (MBMODE)
element for frame P and B pictures. MBMODE consists of four pieces of
information which can easily be encoded on one byte. Doing so not only
avoids a dereference, but also some space as the table containing this
information becomes redundant; furthermore, some of the VLCs used were
initialized with code tables of type uint16_t which are now replaced by
symbol tables of type uint8_t (thanks to ff_init_vlc_from_lengths()),
thereby saving space.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
 libavcodec/vc1.c       |  14 ++--
 libavcodec/vc1_block.c |  41 +++++-----
 libavcodec/vc1data.c   | 177 +++++++++++++++++++++++++++--------------
 libavcodec/vc1data.h   |  18 +++--
 4 files changed, 155 insertions(+), 95 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c
index a7cc11de54..84617913ba 100644
--- a/libavcodec/vc1.c
+++ b/libavcodec/vc1.c
@@ -1439,15 +1439,17 @@  av_cold int ff_vc1_init_common(VC1Context *v)
             /* initialize 4MV MBMODE VLC tables for interlaced frame P picture */
             ff_vc1_intfr_4mv_mbmode_vlc[i].table           = &vlc_table[vlc_offs[i * 3 + 37]];
             ff_vc1_intfr_4mv_mbmode_vlc[i].table_allocated = vlc_offs[i * 3 + 38] - vlc_offs[i * 3 + 37];
-            init_vlc(&ff_vc1_intfr_4mv_mbmode_vlc[i], VC1_INTFR_4MV_MBMODE_VLC_BITS, 15,
-                     ff_vc1_intfr_4mv_mbmode_bits[i], 1, 1,
-                     ff_vc1_intfr_4mv_mbmode_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
+            ff_init_vlc_from_lengths(&ff_vc1_intfr_4mv_mbmode_vlc[i], VC1_INTFR_4MV_MBMODE_VLC_BITS, 15,
+                                     &ff_vc1_intfr_4mv_mbmode_tabs[i][0][1], 2,
+                                     &ff_vc1_intfr_4mv_mbmode_tabs[i][0][0], 2, 1,
+                                     0, INIT_VLC_USE_NEW_STATIC, NULL);
             /* initialize NON-4MV MBMODE VLC tables for the same */
             ff_vc1_intfr_non4mv_mbmode_vlc[i].table           = &vlc_table[vlc_offs[i * 3 + 38]];
             ff_vc1_intfr_non4mv_mbmode_vlc[i].table_allocated = vlc_offs[i * 3 + 39] - vlc_offs[i * 3 + 38];
-            init_vlc(&ff_vc1_intfr_non4mv_mbmode_vlc[i], VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 9,
-                     ff_vc1_intfr_non4mv_mbmode_bits[i], 1, 1,
-                     ff_vc1_intfr_non4mv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
+            ff_init_vlc_from_lengths(&ff_vc1_intfr_non4mv_mbmode_vlc[i], VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 9,
+                                     &ff_vc1_intfr_non4mv_mbmode_tabs[i][0][1], 2,
+                                     &ff_vc1_intfr_non4mv_mbmode_tabs[i][0][0], 2, 1,
+                                     0, INIT_VLC_USE_NEW_STATIC, NULL);
             /* initialize interlaced MVDATA tables (1-Ref) */
             ff_vc1_1ref_mvdata_vlc[i].table           = &vlc_table[vlc_offs[i * 3 + 39]];
             ff_vc1_1ref_mvdata_vlc[i].table_allocated = vlc_offs[i * 3 + 40] - vlc_offs[i * 3 + 39];
diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c
index 6820ffb0d7..18637e75d8 100644
--- a/libavcodec/vc1_block.c
+++ b/libavcodec/vc1_block.c
@@ -1518,7 +1518,7 @@  static int vc1_decode_p_mb_intfr(VC1Context *v)
     int dst_idx, off;
     int skipped, fourmv = 0, twomv = 0;
     int block_cbp = 0, pat, block_tt = 0;
-    int idx_mbmode = 0, mvbp;
+    int mvbp;
     int fieldtx;
 
     mquant = v->pq; /* Lossy initialization */
@@ -1528,11 +1528,11 @@  static int vc1_decode_p_mb_intfr(VC1Context *v)
     else
         skipped = v->s.mbskip_table[mb_pos];
     if (!skipped) {
-        if (v->fourmvswitch)
-            idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_4MV_MBMODE_VLC_BITS, 2); // try getting this done
-        else
-            idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2); // in a single line
-        switch (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0]) {
+        int bits = v->fourmvswitch ? VC1_INTFR_4MV_MBMODE_VLC_BITS :
+                                     VC1_INTFR_NON4MV_MBMODE_VLC_BITS;
+        int mbmode = get_vlc2(gb, v->mbmode_vlc->table, bits, 2);
+
+        switch (mbmode & 0x1F) {
         /* store the motion vector type in a flag (useful later) */
         case MV_PMODE_INTFR_4MV:
             fourmv = 1;
@@ -1562,7 +1562,7 @@  static int vc1_decode_p_mb_intfr(VC1Context *v)
             v->blk_mv_type[s->block_index[3]] = 0;
             break;
         }
-        if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB
+        if ((mbmode & 0x1F) == MV_PMODE_INTFR_INTRA) { // intra MB
             for (i = 0; i < 4; i++) {
                 s->current_picture.motion_val[1][s->block_index[i]][0] = 0;
                 s->current_picture.motion_val[1][s->block_index[i]][1] = 0;
@@ -1605,21 +1605,21 @@  static int vc1_decode_p_mb_intfr(VC1Context *v)
             }
 
         } else { // inter MB
-            mb_has_coeffs = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][3];
+            mb_has_coeffs = !!(mbmode & RESIDUAL);
             if (mb_has_coeffs)
                 cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
-            if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) {
+            if ((mbmode & 0x1F) == MV_PMODE_INTFR_2MV_FIELD) {
                 v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1);
             } else {
-                if ((ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_4MV)
-                    || (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_4MV_FIELD)) {
+                if (((mbmode & 0x1F) == MV_PMODE_INTFR_4MV) ||
+                    ((mbmode & 0x1F) == MV_PMODE_INTFR_4MV_FIELD)) {
                     v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
                 }
             }
             s->mb_intra = v->is_intra[s->mb_x] = 0;
             for (i = 0; i < 6; i++)
                 v->mb_type[0][s->block_index[i]] = 0;
-            fieldtx = v->fieldtx_plane[mb_pos] = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][1];
+            fieldtx = v->fieldtx_plane[mb_pos] = !!(mbmode & FIELDTX);
             /* for all motion vector read MVDATA and motion compensate each block */
             dst_idx = 0;
             if (fourmv) {
@@ -1650,7 +1650,7 @@  static int vc1_decode_p_mb_intfr(VC1Context *v)
                 ff_vc1_mc_4mv_luma(v, 3, 0, 0);
                 ff_vc1_mc_4mv_chroma4(v, 0, 0, 0);
             } else {
-                mvbp = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][2];
+                mvbp = !!(mbmode & MVDIFF);
                 dmv_x = dmv_y = 0;
                 if (mvbp) {
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, NULL);
@@ -2175,7 +2175,7 @@  static int vc1_decode_b_mb_intfr(VC1Context *v)
     int dst_idx, off;
     int skipped, direct, twomv = 0;
     int block_cbp = 0, pat, block_tt = 0;
-    int idx_mbmode = 0, mvbp;
+    int mbmode = MV_PMODE_INTFR_1MV | MVDIFF | RESIDUAL, mvbp;
     int stride_y, fieldtx;
     int bmvtype = BMV_TYPE_BACKWARD;
     int dir, dir2;
@@ -2188,8 +2188,9 @@  static int vc1_decode_b_mb_intfr(VC1Context *v)
         skipped = v->s.mbskip_table[mb_pos];
 
     if (!skipped) {
-        idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2);
-        if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) {
+        mbmode = get_vlc2(gb, v->mbmode_vlc->table,
+                          VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2);
+        if ((mbmode & 0x1F) == MV_PMODE_INTFR_2MV_FIELD) {
             twomv = 1;
             v->blk_mv_type[s->block_index[0]] = 1;
             v->blk_mv_type[s->block_index[1]] = 1;
@@ -2203,7 +2204,7 @@  static int vc1_decode_b_mb_intfr(VC1Context *v)
         }
     }
 
-    if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB
+    if ((mbmode & 0x1F) == MV_PMODE_INTFR_INTRA) { // intra MB
         for (i = 0; i < 4; i++) {
             s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = 0;
             s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = 0;
@@ -2309,7 +2310,7 @@  static int vc1_decode_b_mb_intfr(VC1Context *v)
         }
 
         if (!skipped) { // inter MB
-            mb_has_coeffs = ff_vc1_mbmode_intfrp[0][idx_mbmode][3];
+            mb_has_coeffs = !!(mbmode & RESIDUAL);
             if (mb_has_coeffs)
                 cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
             if (!direct) {
@@ -2322,7 +2323,7 @@  static int vc1_decode_b_mb_intfr(VC1Context *v)
 
             for (i = 0; i < 6; i++)
                 v->mb_type[0][s->block_index[i]] = 0;
-            fieldtx = v->fieldtx_plane[mb_pos] = ff_vc1_mbmode_intfrp[0][idx_mbmode][1];
+            fieldtx = v->fieldtx_plane[mb_pos] = !!(mbmode & FIELDTX);
             /* for all motion vector read MVDATA and motion compensate each block */
             dst_idx = 0;
             if (direct) {
@@ -2404,7 +2405,7 @@  static int vc1_decode_b_mb_intfr(VC1Context *v)
             } else {
                 dir = bmvtype == BMV_TYPE_BACKWARD;
 
-                mvbp = ff_vc1_mbmode_intfrp[0][idx_mbmode][2];
+                mvbp = !!(mbmode & MVDIFF);
                 dmv_x = dmv_y = 0;
                 if (mvbp)
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, NULL);
diff --git a/libavcodec/vc1data.c b/libavcodec/vc1data.c
index be5cd3bffe..682d7d174f 100644
--- a/libavcodec/vc1data.c
+++ b/libavcodec/vc1data.c
@@ -42,41 +42,6 @@  const uint8_t ff_vc1_mv_pmode_table2[2][4] = {
     { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_1MV_HPEL_BILIN }
 };
 
-/* MBMODE table for interlaced frame P-picture */
-const uint8_t ff_vc1_mbmode_intfrp[2][15][4] = {
-    { /* 1: 4-MV, 0: non-4-MV */
-        /* Type, FIELDTX, 1-MV Differential present, Residuals (CBP) present */
-        /* Table 164 - Table 167 */
-        { MV_PMODE_INTFR_1MV      , 0, 1, 1 },
-        { MV_PMODE_INTFR_1MV      , 1, 1, 1 },
-        { MV_PMODE_INTFR_1MV      , 0, 1, 0 },
-        { MV_PMODE_INTFR_1MV      , 0, 0, 1 },
-        { MV_PMODE_INTFR_1MV      , 1, 0, 1 },
-        { MV_PMODE_INTFR_2MV_FIELD, 0, 0, 1 },
-        { MV_PMODE_INTFR_2MV_FIELD, 1, 0, 1 },
-        { MV_PMODE_INTFR_2MV_FIELD, 1, 0, 0 },
-        { MV_PMODE_INTFR_INTRA    , 0, 0, 0 }
-    },
-    {
-        /* Table 160 - Table 163 */
-        { MV_PMODE_INTFR_1MV      , 0, 1, 1 },
-        { MV_PMODE_INTFR_1MV      , 1, 1, 1 },
-        { MV_PMODE_INTFR_1MV      , 0, 1, 0 },
-        { MV_PMODE_INTFR_1MV      , 0, 0, 1 },
-        { MV_PMODE_INTFR_1MV      , 1, 0, 1 },
-        { MV_PMODE_INTFR_2MV_FIELD, 0, 0, 1 },
-        { MV_PMODE_INTFR_2MV_FIELD, 1, 0, 1 },
-        { MV_PMODE_INTFR_2MV_FIELD, 1, 0, 0 },
-        { MV_PMODE_INTFR_4MV      , 0, 0, 1 },
-        { MV_PMODE_INTFR_4MV      , 1, 0, 1 },
-        { MV_PMODE_INTFR_4MV      , 0, 0, 0 },
-        { MV_PMODE_INTFR_4MV_FIELD, 0, 0, 1 },
-        { MV_PMODE_INTFR_4MV_FIELD, 1, 0, 1 },
-        { MV_PMODE_INTFR_4MV_FIELD, 1, 0, 0 },
-        { MV_PMODE_INTFR_INTRA    , 0, 0, 0 }
-    }
-};
-
 const int ff_vc1_fps_nr[7] = { 24, 25, 30, 50, 60, 48, 72 },
           ff_vc1_fps_dr[2] = { 1000, 1001 };
 const uint8_t ff_vc1_pquant_table[3][32] = {
@@ -256,34 +221,124 @@  const uint8_t ff_vc1_2mv_block_pattern_bits[4][4] = {
     { 2, 2, 2, 2 }, { 1, 2, 3, 3 }, { 3, 2, 3, 1 }, { 1, 3, 3, 2 }
 };
 
-/* Interlaced frame picture 4MV MBMODE VLC tables (p. 246, p. 360) */
-const uint16_t ff_vc1_intfr_4mv_mbmode_codes[4][15] = {
-    { 22,  17,  0, 47,  32, 10,  1,  3, 67,  133, 132,  92,  19,  93,   18 },
-    {  3,  45,  0,  7,  23,  6,  1,  2, 10,   39,  44,   8,  18,  77,   76 },
-    { 15,   6, 28,  9,  41,  6,  2, 15, 14,    8,  40,  29,   0,  21,   11 },
-    {  7, 198,  1,  2, 193, 13, 25,  0, 97, 1599,  98, 398, 798, 192, 1598 }
-};
-
-const uint8_t ff_vc1_intfr_4mv_mbmode_bits[4][15] = {
-    { 5, 5, 2, 6, 6, 4, 2, 2, 7,  8, 8,  7,  5, 7,  5 },
-    { 3, 6, 3, 3, 5, 3, 3, 3, 4,  6, 6,  4,  5, 7,  7 },
-    { 4, 3, 5, 5, 7, 4, 2, 5, 5,  5, 7,  5,  2, 6,  5 },
-    { 4, 9, 1, 3, 9, 5, 6, 2, 8, 12, 8, 10, 11, 9, 12 }
-};
-
-/* Interlaced frame picture NON-4MV MBMODE VLC tables (p. 363) */
-const uint8_t ff_vc1_intfr_non4mv_mbmode_codes[4][9] = {
-    {  9, 22,  0, 17, 16, 10,  1,  3, 23 },
-    {  7,  0,  5,  2,  1,  1,  6,  3,  4 },
-    {  1,  0, 10, 23, 44,  8,  3,  9, 45 },
-    {  7, 97,  1,  2, 49, 13, 25,  0, 96 }
+/* Interlaced frame picture 4MV MBMODE VLC tables (tables 160-163) */
+const uint8_t ff_vc1_intfr_4mv_mbmode_tabs[4][15][2] = {
+    {
+        { MV_PMODE_INTFR_1MV | MVDIFF,  2 },
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX | RESIDUAL,  2 },
+        { MV_PMODE_INTFR_1MV | FIELDTX | RESIDUAL,  6 },
+        { MV_PMODE_INTFR_4MV,  8 },
+        { MV_PMODE_INTFR_4MV | FIELDTX | RESIDUAL,  8 },
+        { MV_PMODE_INTFR_4MV | RESIDUAL,  7 },
+        { MV_PMODE_INTFR_1MV | FIELDTX | MVDIFF | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_INTRA,  5 },
+        { MV_PMODE_INTFR_4MV_FIELD | FIELDTX | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_2MV_FIELD | RESIDUAL,  4 },
+        { MV_PMODE_INTFR_1MV | MVDIFF | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_4MV_FIELD | RESIDUAL,  7 },
+        { MV_PMODE_INTFR_4MV_FIELD | FIELDTX,  7 },
+        { MV_PMODE_INTFR_1MV | RESIDUAL,  6 },
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX,  2 },
+    },
+    {
+        { MV_PMODE_INTFR_1MV | MVDIFF,  3 },
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX | RESIDUAL,  3 },
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX,  3 },
+        { MV_PMODE_INTFR_1MV | MVDIFF | RESIDUAL,  3 },
+        { MV_PMODE_INTFR_4MV_FIELD | RESIDUAL,  4 },
+        { MV_PMODE_INTFR_4MV_FIELD | FIELDTX | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_INTRA,  7 },
+        { MV_PMODE_INTFR_4MV_FIELD | FIELDTX,  7 },
+        { MV_PMODE_INTFR_4MV | FIELDTX | RESIDUAL,  6 },
+        { MV_PMODE_INTFR_4MV | RESIDUAL,  4 },
+        { MV_PMODE_INTFR_4MV,  6 },
+        { MV_PMODE_INTFR_1MV | FIELDTX | MVDIFF | RESIDUAL,  6 },
+        { MV_PMODE_INTFR_1MV | FIELDTX | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_2MV_FIELD | RESIDUAL,  3 },
+        { MV_PMODE_INTFR_1MV | RESIDUAL,  3 },
+    },
+    {
+        { MV_PMODE_INTFR_4MV_FIELD | FIELDTX | RESIDUAL,  2 },
+        { MV_PMODE_INTFR_4MV | FIELDTX | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_1MV | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_4MV,  7 },
+        { MV_PMODE_INTFR_1MV | FIELDTX | RESIDUAL,  7 },
+        { MV_PMODE_INTFR_4MV_FIELD | FIELDTX,  6 },
+        { MV_PMODE_INTFR_INTRA,  5 },
+        { MV_PMODE_INTFR_2MV_FIELD | RESIDUAL,  4 },
+        { MV_PMODE_INTFR_4MV | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX,  5 },
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX | RESIDUAL,  2 },
+        { MV_PMODE_INTFR_1MV | FIELDTX | MVDIFF | RESIDUAL,  3 },
+        { MV_PMODE_INTFR_1MV | MVDIFF,  5 },
+        { MV_PMODE_INTFR_4MV_FIELD | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_1MV | MVDIFF | RESIDUAL,  4 },
+    },
+    {
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX,  2 },
+        { MV_PMODE_INTFR_1MV | RESIDUAL,  3 },
+        { MV_PMODE_INTFR_4MV_FIELD | FIELDTX,  9 },
+        { MV_PMODE_INTFR_1MV | FIELDTX | RESIDUAL,  9 },
+        { MV_PMODE_INTFR_4MV | RESIDUAL,  8 },
+        { MV_PMODE_INTFR_4MV,  8 },
+        { MV_PMODE_INTFR_1MV | FIELDTX | MVDIFF | RESIDUAL,  9 },
+        { MV_PMODE_INTFR_4MV_FIELD | RESIDUAL, 10 },
+        { MV_PMODE_INTFR_4MV_FIELD | FIELDTX | RESIDUAL, 11 },
+        { MV_PMODE_INTFR_INTRA, 12 },
+        { MV_PMODE_INTFR_4MV | FIELDTX | RESIDUAL, 12 },
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX | RESIDUAL,  6 },
+        { MV_PMODE_INTFR_2MV_FIELD | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_1MV | MVDIFF | RESIDUAL,  4 },
+        { MV_PMODE_INTFR_1MV | MVDIFF,  1 },
+    },
 };
 
-const uint8_t ff_vc1_intfr_non4mv_mbmode_bits[4][9] = {
-    {  4,  5,  2,  5,  5,  4,  2,  2,  5 },
-    {  3,  4,  6,  2,  3,  2,  3,  5,  6 },
-    {  2,  2,  4,  5,  6,  4,  2,  4,  6 },
-    {  4,  8,  1,  3,  7,  5,  6,  2,  8 }
+/* Interlaced frame picture NON-4MV MBMODE VLC tables (tables 164-167) */
+const uint8_t ff_vc1_intfr_non4mv_mbmode_tabs[4][9][2] = {
+    {
+        { MV_PMODE_INTFR_1MV | MVDIFF,  2 },
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX | RESIDUAL,  2 },
+        { MV_PMODE_INTFR_1MV | FIELDTX | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_1MV | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_1MV | MVDIFF | RESIDUAL,  4 },
+        { MV_PMODE_INTFR_2MV_FIELD | RESIDUAL,  4 },
+        { MV_PMODE_INTFR_1MV | FIELDTX | MVDIFF | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_INTRA,  5 },
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX,  2 },
+    },
+    {
+        { MV_PMODE_INTFR_1MV | FIELDTX | MVDIFF | RESIDUAL,  4 },
+        { MV_PMODE_INTFR_INTRA,  6 },
+        { MV_PMODE_INTFR_1MV | MVDIFF,  6 },
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX,  5 },
+        { MV_PMODE_INTFR_1MV | FIELDTX | RESIDUAL,  3 },
+        { MV_PMODE_INTFR_2MV_FIELD | RESIDUAL,  2 },
+        { MV_PMODE_INTFR_1MV | RESIDUAL,  2 },
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX | RESIDUAL,  3 },
+        { MV_PMODE_INTFR_1MV | MVDIFF | RESIDUAL,  3 },
+    },
+    {
+        { MV_PMODE_INTFR_1MV | FIELDTX | MVDIFF | RESIDUAL,  2 },
+        { MV_PMODE_INTFR_1MV | MVDIFF | RESIDUAL,  2 },
+        { MV_PMODE_INTFR_2MV_FIELD | RESIDUAL,  4 },
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX,  4 },
+        { MV_PMODE_INTFR_1MV | MVDIFF,  4 },
+        { MV_PMODE_INTFR_1MV | FIELDTX | RESIDUAL,  6 },
+        { MV_PMODE_INTFR_INTRA,  6 },
+        { MV_PMODE_INTFR_1MV | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX | RESIDUAL,  2 },
+    },
+    {
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX,  2 },
+        { MV_PMODE_INTFR_1MV | RESIDUAL,  3 },
+        { MV_PMODE_INTFR_INTRA,  8 },
+        { MV_PMODE_INTFR_1MV | FIELDTX | MVDIFF | RESIDUAL,  8 },
+        { MV_PMODE_INTFR_1MV | FIELDTX | RESIDUAL,  7 },
+        { MV_PMODE_INTFR_2MV_FIELD | FIELDTX | RESIDUAL,  6 },
+        { MV_PMODE_INTFR_2MV_FIELD | RESIDUAL,  5 },
+        { MV_PMODE_INTFR_1MV | MVDIFF | RESIDUAL,  4 },
+        { MV_PMODE_INTFR_1MV | MVDIFF,  1 },
+    },
 };
 
 /* Interlaced field picture MBMODE VLC tables (p. 356 - 11.4.1, 11.4.2) */
diff --git a/libavcodec/vc1data.h b/libavcodec/vc1data.h
index ccd2a0ec57..21dec20390 100644
--- a/libavcodec/vc1data.h
+++ b/libavcodec/vc1data.h
@@ -43,9 +43,6 @@  extern const uint8_t ff_vc1_mv_pmode_table2[2][4];
 extern const int ff_vc1_fps_nr[7], ff_vc1_fps_dr[2];
 extern const uint8_t ff_vc1_pquant_table[3][32];
 
-/* MBMODE table for interlaced frame P-picture */
-extern const uint8_t ff_vc1_mbmode_intfrp[2][15][4];
-
 /** @name VC-1 VLC tables and defines
  *  @todo TODO move this into the context
  */
@@ -165,11 +162,16 @@  extern const uint8_t ff_vc1_subblkpat_tabs[3][15][2];
  * 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];
-extern const uint8_t ff_vc1_intfr_4mv_mbmode_bits[4][15];
-extern const uint8_t ff_vc1_intfr_non4mv_mbmode_codes[4][9];
-extern const uint8_t ff_vc1_intfr_non4mv_mbmode_bits[4][9];
+/* Interlaced frame picture MBMODE VLC tables (tables 160-167)
+ * The lowest five bits of the symbol contain the MBMODE (enum MBModesIntfr),
+ * the next three bits the following properties: */
+enum MBModeProperties {
+    FIELDTX  = 1 << 5,
+    MVDIFF   = 1 << 6,
+    RESIDUAL = 1 << 7,
+};
+extern const uint8_t ff_vc1_intfr_4mv_mbmode_tabs[4][15][2];
+extern const uint8_t ff_vc1_intfr_non4mv_mbmode_tabs[4][9][2];
 
 /* Interlaced field picture MBMODE VLC tables (p. 356 - 11.4.1, 11.4.2) */
 extern const uint8_t ff_vc1_if_mmv_mbmode_codes[8][8];