]> git.sesse.net Git - ffmpeg/commitdiff
avcodec/rv10: Simplify handling of skip VLC entries
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
Wed, 28 Oct 2020 12:15:15 +0000 (13:15 +0100)
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
Tue, 8 Dec 2020 16:51:45 +0000 (17:51 +0100)
The VLC tables to be used for parsing RealVideo 1.0 DC coefficients are
weird: The luma table contains a block of 2^11 codes beginning with the
same prefix and length that all have the same symbol (i.e. value only
depends upon the prefix); the same goes for the chroma block (except
it's only 2^9 codes). Up until now, these entries (which generally could
be parsed like ordinary entries with subtables) have been treated
specially: They have been treated like open ends of the tree, so that
get_vlc2() returned a value < 0 upon encountering them; afterwards it
was checked whether the right prefix was used and if so, the appropriate
number of bytes was skipped.

But there is actually an easy albeit slightly hacky way to support them
directly without pointless subtables: Just modify the VLC table so that
all the entries sharing the right prefix have a length that equals the
length of the whole entry.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
libavcodec/rv10.c

index 072789933732e4dbd18ec8ca619d92f36ae3b0af..d118515c3b36519084939835744e0b8a2654c48f 100644 (file)
@@ -84,22 +84,11 @@ int ff_rv_decode_dc(MpegEncContext *s, int n)
 
     if (n < 4) {
         code = get_vlc2(&s->gb, rv_dc_lum.table, DC_VLC_BITS, 2);
-        if (code < 0) {
-            /* Skip entry - no error. */
-            skip_bits(&s->gb, 18);
-            code = 255;
-        }
     } else {
         code = get_vlc2(&s->gb, rv_dc_chrom.table, DC_VLC_BITS, 2);
         if (code < 0) {
-            if (show_bits(&s->gb, 9) == 0x1FE) {
-                /* Skip entry - no error. */
-                skip_bits(&s->gb, 18);
-                code = 255;
-            } else {
-                av_log(s->avctx, AV_LOG_ERROR, "chroma dc error\n");
-                return -1;
-            }
+            av_log(s->avctx, AV_LOG_ERROR, "chroma dc error\n");
+            return -1;
         }
     }
     return code;
@@ -352,10 +341,21 @@ static av_cold void rv10_init_static(void)
     rv_dc_lum.table_allocated   = 1472;
     rv10_build_vlc(&rv_dc_lum, rv_lum_len_count,
                    rv_sym_run_len, FF_ARRAY_ELEMS(rv_sym_run_len));
+    for (int i = 0; i < 1 << (DC_VLC_BITS - 7 /* Length of skip prefix */); i++) {
+        /* All codes beginning with 0x7F have the same length and value.
+         * Modifying the table directly saves us the useless subtables. */
+        rv_dc_lum.table[(0x7F << (DC_VLC_BITS - 7)) + i][0] = 255;
+        rv_dc_lum.table[(0x7F << (DC_VLC_BITS - 7)) + i][1] = 18;
+    }
     rv_dc_chrom.table           = &table[1472];
     rv_dc_chrom.table_allocated = 992;
     rv10_build_vlc(&rv_dc_chrom, rv_chrom_len_count,
                    rv_sym_run_len, FF_ARRAY_ELEMS(rv_sym_run_len) - 2);
+    for (int i = 0; i < 1 << (DC_VLC_BITS - 9 /* Length of skip prefix */); i++) {
+        /* Same as above. */
+        rv_dc_chrom.table[(0x1FE << (DC_VLC_BITS - 9)) + i][0] = 255;
+        rv_dc_chrom.table[(0x1FE << (DC_VLC_BITS - 9)) + i][1] = 18;
+    }
     ff_h263_decode_init_vlc();
 }