diff mbox series

[FFmpeg-devel,v2,033/162] avcodec/rv10: Use symbol table more effectively

Message ID 20201120072116.818090-34-andreas.rheinhardt@gmail.com
State Accepted
Headers show
Series VLC, esp. init_vlc patches | expand

Checks

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

Commit Message

Andreas Rheinhardt Nov. 20, 2020, 7:19 a.m. UTC
The RealVideo 1.0 decoder uses VLCs to parse DC coefficients. But the
values returned from get_vlc2() are not directly used; instead
-(val - 128) (which is in the range -127..128) is. This transformation
is unnecessary as it can effectively be done when initializing the VLC
by modifying the symbols table used. There is just one minor
complication: The chroma table is incomplete and in order to distinguish
an error from get_vlc2() (due to an invalid code) the ordinary return
range is modified to 0..255. This is possible because the only caller of
this function is (on success) only interested in the return value modulo
256.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
 libavcodec/ituh263dec.c |  2 +-
 libavcodec/rv10.c       | 24 ++++++++++--------------
 2 files changed, 11 insertions(+), 15 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index c1005b0994..ced7fa52ee 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -467,7 +467,7 @@  static int h263_decode_block(MpegEncContext * s, int16_t * block,
             level = s->last_dc[component];
             if (s->rv10_first_dc_coded[component]) {
                 diff = ff_rv_decode_dc(s, n);
-                if (diff == 0xffff)
+                if (diff < 0)
                     return -1;
                 level += diff;
                 level = level & 0xff; /* handle wrap round */
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index eaabb99e69..4d4c2b0f2e 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -56,14 +56,14 @@  typedef struct RVDecContext {
 } RVDecContext;
 
 /* (run, length) encoded value for the symbols table. The actual symbols
- * are run..run + length (mod 256).
+ * are run..run - length (mod 256).
  * The last two entries in the following table apply to luma only.
  * The skip values are not included in this list. */
 static const uint8_t rv_sym_run_len[][2] = {
-    { 128,   0 }, { 127,   0 }, { 129,   0 }, { 125,   1 }, { 130,  1 },
-    { 121,   3 }, { 132,   3 }, { 113,   7 }, { 136,   7 }, {  97, 15 },
-    { 144,  15 }, {  65,  31 }, { 160,  31 }, {   1,  63 }, { 192, 63 },
-    { 129, 127 }, {   0, 127 }, {   1, 255 }, {   0, 255 },
+    {   0,   0 }, {   1,   0 }, { 255,   0 }, {   3,   1 }, { 254,  1 },
+    {   7,   3 }, { 252,   3 }, {  15,   7 }, { 248,   7 }, {  31, 15 },
+    { 240,  15 }, {  63,  31 }, { 224,  31 }, { 127,  63 }, { 192, 63 },
+    { 255, 127 }, { 128, 127 }, { 127, 255 }, { 128, 255 },
 };
 
 /* entry[i] of the following tables gives
@@ -87,9 +87,7 @@  int ff_rv_decode_dc(MpegEncContext *s, int n)
         if (code < 0) {
             /* Skip entry - no error. */
             skip_bits(&s->gb, 18);
-            code = 1;
-        } else {
-            code -= 128;
+            code = 255;
         }
     } else {
         code = get_vlc2(&s->gb, rv_dc_chrom.table, DC_VLC_BITS, 2);
@@ -97,16 +95,14 @@  int ff_rv_decode_dc(MpegEncContext *s, int n)
             if (show_bits(&s->gb, 9) == 0x1FE) {
                 /* Skip entry - no error. */
                 skip_bits(&s->gb, 18);
-                code = 1;
+                code = 255;
             } else {
                 av_log(s->avctx, AV_LOG_ERROR, "chroma dc error\n");
-                return 0xffff;
+                return -1;
             }
-        } else {
-            code -= 128;
         }
     }
-    return -code;
+    return code;
 }
 
 /* read RV 1.0 compatible frame header */
@@ -337,7 +333,7 @@  static av_cold void rv10_build_vlc(VLC *vlc, const uint16_t len_count[15],
     for (unsigned i = 0; i < sym_rl_elems; i++) {
         unsigned cur_sym = sym_rl[i][0];
         for (unsigned tmp = nb_syms + sym_rl[i][1]; nb_syms <= tmp; nb_syms++)
-            syms[nb_syms] = 0xFF & cur_sym++;
+            syms[nb_syms] = 0xFF & cur_sym--;
     }
 
     for (unsigned i = 0; i < 15; i++)