diff mbox series

[FFmpeg-devel,v2,016/162] avcodec/clearvideo: Avoid code duplication when initializing VLCs

Message ID 20201120072116.818090-17-andreas.rheinhardt@gmail.com
State Accepted
Commit e97081a62471c41522ddb2af534ed7ce9b3a6893
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

Commit Message

Andreas Rheinhardt Nov. 20, 2020, 7:18 a.m. UTC
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
 libavcodec/clearvideo.c     | 201 +++++++-----------------------------
 libavcodec/clearvideodata.h | 104 ++++++++++---------
 2 files changed, 89 insertions(+), 216 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/clearvideo.c b/libavcodec/clearvideo.c
index ef09b137c4..f1dcb03f0e 100644
--- a/libavcodec/clearvideo.c
+++ b/libavcodec/clearvideo.c
@@ -74,7 +74,7 @@  typedef struct CLVContext {
     int            tile_size;
     int            tile_shift;
     VLC            dc_vlc, ac_vlc;
-    LevelCodes     ylev[4], ulev[3], vlev[3];
+    LevelCodes     lev[4 + 3 + 3]; // 0..3: Y, 4..6: U, 7..9: V
     int            luma_dc_quant, chroma_dc_quant, ac_quant;
     DECLARE_ALIGNED(16, int16_t, block)[64];
     int            top_dc[3], left_dc[4];
@@ -594,7 +594,7 @@  static int clv_decode_frame(AVCodecContext *avctx, void *data,
                     TileInfo *tile;
                     MV mv, cmv;
 
-                    tile = decode_tile_info(&c->gb, c->ylev, 0);
+                    tile = decode_tile_info(&c->gb, &c->lev[0], 0); // Y
                     if (!tile)
                         return AVERROR(ENOMEM);
                     mv = mvi_predict(&c->mvi, i, j, tile->mv);
@@ -609,14 +609,14 @@  static int clv_decode_frame(AVCodecContext *avctx, void *data,
                     cmv.x /= 2;
                     cmv.y /= 2;
                     av_freep(&tile);
-                    tile = decode_tile_info(&c->gb, c->ulev, 0);
+                    tile = decode_tile_info(&c->gb, &c->lev[4], 0); // U
                     if (!tile)
                         return AVERROR(ENOMEM);
                     ret = restore_tree(avctx, c->pic, c->prev, 1, x, y, size, tile, cmv);
                     if (ret < 0)
                         mb_ret = ret;
                     av_freep(&tile);
-                    tile = decode_tile_info(&c->gb, c->vlev, 0);
+                    tile = decode_tile_info(&c->gb, &c->lev[7], 0); // V
                     if (!tile)
                         return AVERROR(ENOMEM);
                     ret = restore_tree(avctx, c->pic, c->prev, 2, x, y, size, tile, cmv);
@@ -704,162 +704,39 @@  static av_cold int clv_decode_init(AVCodecContext *avctx)
         return ret;
     }
 
-    ret = ff_init_vlc_from_lengths(&c->ylev[0].flags_cb, 9, FF_ARRAY_ELEMS(clv_flagsy_0_bits),
-                                   clv_flagsy_0_bits, 1,
-                                   clv_flagsy_0_syms, 1, 1, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ylev[1].flags_cb, 9, FF_ARRAY_ELEMS(clv_flagsy_1_bits),
-                                   clv_flagsy_1_bits, 1,
-                                   clv_flagsy_1_syms, 1, 1, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ylev[2].flags_cb, 9, FF_ARRAY_ELEMS(clv_flagsy_2_bits),
-                                   clv_flagsy_2_bits, 1,
-                                   clv_flagsy_2_syms, 1, 1, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ulev[0].flags_cb, 9, FF_ARRAY_ELEMS(clv_flagsu_0_bits),
-                                   clv_flagsu_0_bits, 1,
-                                   clv_flagsu_0_syms, 1, 1, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ulev[1].flags_cb, 9, FF_ARRAY_ELEMS(clv_flagsu_1_bits),
-                                   clv_flagsu_1_bits, 1,
-                                   clv_flagsu_1_syms, 1, 1, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->vlev[0].flags_cb, 9, FF_ARRAY_ELEMS(clv_flagsv_0_bits),
-                                   clv_flagsv_0_bits, 1,
-                                   clv_flagsv_0_syms, 1, 1, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->vlev[1].flags_cb, 9, FF_ARRAY_ELEMS(clv_flagsv_1_bits),
-                                   clv_flagsv_1_bits, 1,
-                                   clv_flagsv_1_syms, 1, 1, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ylev[0].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvy_0_bits),
-                                   clv_mvy_0_bits, 1,
-                                   clv_mvy_0_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ylev[1].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvy_1_bits),
-                                   clv_mvy_1_bits, 1,
-                                   clv_mvy_1_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ylev[2].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvy_2_bits),
-                                   clv_mvy_2_bits, 1,
-                                   clv_mvy_2_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ylev[3].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvy_3_bits),
-                                   clv_mvy_3_bits, 1,
-                                   clv_mvy_3_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ulev[1].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvu_1_bits),
-                                   clv_mvu_1_bits, 1,
-                                   clv_mvu_1_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ulev[2].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvu_2_bits),
-                                   clv_mvu_2_bits, 1,
-                                   clv_mvu_2_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->vlev[1].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvv_1_bits),
-                                   clv_mvv_1_bits, 1,
-                                   clv_mvv_1_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->vlev[2].mv_cb, 9, FF_ARRAY_ELEMS(clv_mvv_2_bits),
-                                   clv_mvv_2_bits, 1,
-                                   clv_mvv_2_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ylev[1].bias_cb, 9, FF_ARRAY_ELEMS(clv_biasy_1_bits),
-                                   clv_biasy_1_bits, 1,
-                                   clv_biasy_1_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ylev[2].bias_cb, 9, FF_ARRAY_ELEMS(clv_biasy_2_bits),
-                                   clv_biasy_2_bits, 1,
-                                   clv_biasy_2_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ylev[3].bias_cb, 9, FF_ARRAY_ELEMS(clv_biasy_3_bits),
-                                   clv_biasy_3_bits, 1,
-                                   clv_biasy_3_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ulev[1].bias_cb, 9, FF_ARRAY_ELEMS(clv_biasu_1_bits),
-                                   clv_biasu_1_bits, 1,
-                                   clv_biasu_1_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->ulev[2].bias_cb, 9, FF_ARRAY_ELEMS(clv_biasu_2_bits),
-                                   clv_biasu_2_bits, 1,
-                                   clv_biasu_2_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->vlev[1].bias_cb, 9, FF_ARRAY_ELEMS(clv_biasv_1_bits),
-                                   clv_biasv_1_bits, 1,
-                                   clv_biasv_1_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    ret = ff_init_vlc_from_lengths(&c->vlev[2].bias_cb, 9, FF_ARRAY_ELEMS(clv_biasv_2_bits),
-                                   clv_biasv_2_bits, 1,
-                                   clv_biasv_2_syms, 2, 2, 0, 0, avctx);
-    if (ret)
-        return ret;
-
-    c->ylev[0].mv_esc = 0x0909;
-    c->ylev[1].mv_esc = 0x0A0A;
-    c->ylev[2].mv_esc = 0x1010;
-    c->ylev[3].mv_esc = 0x1313;
-    c->ulev[1].mv_esc = 0x0808;
-    c->ulev[2].mv_esc = 0x0B0B;
-    c->vlev[1].mv_esc = 0x0808;
-    c->vlev[2].mv_esc = 0x0B0B;
-
-    c->ylev[1].bias_esc = 0x100;
-    c->ylev[2].bias_esc = 0x100;
-    c->ylev[3].bias_esc = 0x100;
-    c->ulev[1].bias_esc = 0x100;
-    c->ulev[2].bias_esc = 0x100;
-    c->vlev[1].bias_esc = 0x100;
-    c->vlev[2].bias_esc = 0x100;
-
+    for (int i = 0, j = 0;; i++) {
+        if (0x36F & (1 << i)) {
+            c->lev[i].mv_esc = clv_mv_escape[i];
+            ret = ff_init_vlc_from_lengths(&c->lev[i].mv_cb, 9, clv_mv_sizes[i],
+                                           clv_mv_bits[i], 1,
+                                           clv_mv_syms[i], 2, 2, 0, 0, avctx);
+            if (ret < 0)
+                return ret;
+        }
+        if (i == FF_ARRAY_ELEMS(c->lev) - 1)
+            break;
+        if (0x1B7 & (1 << i)) {
+            ret = ff_init_vlc_from_lengths(&c->lev[i].flags_cb, 9, 16,
+                                           clv_flags_bits[j], 1,
+                                           clv_flags_syms[j], 1, 1, 0, 0, avctx);
+            if (ret < 0)
+                return ret;
+
+            c->lev[i + 1].bias_esc = 0x100;
+            ret = ff_init_vlc_from_lengths(&c->lev[i + 1].bias_cb, 9, clv_bias_sizes[j],
+                                           clv_bias_bits[j], 1,
+                                           clv_bias_syms[j], 2, 2, 0, 0, avctx);
+            if (ret < 0)
+                return ret;
+            j++;
+        }
+    }
     return 0;
 }
 
 static av_cold int clv_decode_end(AVCodecContext *avctx)
 {
     CLVContext *const c = avctx->priv_data;
-    int i;
 
     av_frame_free(&c->prev);
     av_frame_free(&c->pic);
@@ -868,18 +745,10 @@  static av_cold int clv_decode_end(AVCodecContext *avctx)
 
     ff_free_vlc(&c->dc_vlc);
     ff_free_vlc(&c->ac_vlc);
-    for (i = 0; i < 4; i++) {
-        ff_free_vlc(&c->ylev[i].mv_cb);
-        ff_free_vlc(&c->ylev[i].flags_cb);
-        ff_free_vlc(&c->ylev[i].bias_cb);
-    }
-    for (i = 0; i < 3; i++) {
-        ff_free_vlc(&c->ulev[i].mv_cb);
-        ff_free_vlc(&c->ulev[i].flags_cb);
-        ff_free_vlc(&c->ulev[i].bias_cb);
-        ff_free_vlc(&c->vlev[i].mv_cb);
-        ff_free_vlc(&c->vlev[i].flags_cb);
-        ff_free_vlc(&c->vlev[i].bias_cb);
+    for (int i = 0; i < FF_ARRAY_ELEMS(c->lev); i++) {
+        ff_free_vlc(&c->lev[i].mv_cb);
+        ff_free_vlc(&c->lev[i].flags_cb);
+        ff_free_vlc(&c->lev[i].bias_cb);
     }
 
     return 0;
diff --git a/libavcodec/clearvideodata.h b/libavcodec/clearvideodata.h
index b4893b3bf7..fa0721cb0c 100644
--- a/libavcodec/clearvideodata.h
+++ b/libavcodec/clearvideodata.h
@@ -90,60 +90,28 @@  static const uint8_t clv_ac_bits[NUM_AC_CODES] = {
      6,  5,  5,  5,  4,  2,  3,  4,  4
 };
 
-static const uint8_t clv_flagsy_0_bits[] = {
-     2,  3,  4,  4,  4,  4,  4,  4,  4,  4,  5,  5,  5,  6,  7,  7
+static const uint8_t clv_flags_bits[][16] = {
+    { 2,  3,  4,  4,  4,  4,  4,  4,  4,  4,  5,  5,  5,  6,  7,  7 }, // Y_0
+    { 2,  3,  3,  4,  4,  4,  4,  4,  4,  4,  6,  6,  6,  7,  8,  8 }, // Y_1
+    { 1,  4,  4,  4,  4,  4,  4,  5,  5,  5,  6,  7,  8,  9, 10, 10 }, // Y_2
+    { 1,  4,  4,  4,  4,  4,  4,  5,  5,  5,  7,  7,  7,  8,  9,  9 }, // U_0
+    { 1,  4,  4,  4,  4,  4,  4,  4,  5,  6,  8,  8,  8,  9, 10, 10 }, // U_1
+    { 1,  3,  4,  4,  4,  5,  5,  5,  5,  5,  6,  7,  8,  9, 10, 10 }, // V_0
+    { 1,  3,  4,  4,  4,  4,  5,  5,  5,  6,  7,  8,  9, 10, 11, 11 }  // V_1
 };
 
-static const uint8_t clv_flagsy_0_syms[] = {
-    15,  0,  3,  5, 12,  1, 10,  2,  4,  8,  7, 11, 14,  6,  9, 13
+static const uint8_t clv_flags_syms[][16] = {
+    { 15,  0,  3,  5, 12,  1, 10,  2,  4,  8,  7, 11, 14,  6,  9, 13 }, // Y_0
+    {  0, 15,  3, 12,  5,  1,  4,  2,  8, 10, 11,  7,  9,  6, 13, 14 }, // Y_1
+    {  0,  3, 12,  4,  2,  1,  8,  5,  7, 10,  9,  6, 11, 13, 14, 15 }, // Y_2
+    {  0, 15,  3, 12,  1, 10,  2,  5,  4,  8, 11,  7, 14, 13,  9,  6 }, // U_0
+    {  0,  2, 12,  3,  4,  1,  8,  5, 10,  7,  9,  6, 11, 14, 13, 15 }, // U_1
+    {  0, 15,  1, 12,  3, 10,  2,  5,  8,  4, 11, 14,  6,  9,  7, 13 }, // V_0
+    {  0,  8,  3,  4,  2,  1, 12,  5, 10,  7,  9,  6, 14, 11, 13, 15 }  // V_1
 };
 
-static const uint8_t clv_flagsy_1_bits[] = {
-     2,  3,  3,  4,  4,  4,  4,  4,  4,  4,  6,  6,  6,  7,  8,  8
-};
-
-static const uint8_t clv_flagsy_1_syms[] = {
-     0, 15,  3, 12,  5,  1,  4,  2,  8, 10, 11,  7,  9,  6, 13, 14
-};
-
-static const uint8_t clv_flagsy_2_bits[] = {
-     1,  4,  4,  4,  4,  4,  4,  5,  5,  5,  6,  7,  8,  9, 10, 10
-};
-
-static const uint8_t clv_flagsy_2_syms[] = {
-     0,  3, 12,  4,  2,  1,  8,  5,  7, 10,  9,  6, 11, 13, 14, 15
-};
-
-static const uint8_t clv_flagsu_0_bits[] = {
-     1,  4,  4,  4,  4,  4,  4,  5,  5,  5,  7,  7,  7,  8,  9,  9
-};
-
-static const uint8_t clv_flagsu_0_syms[] = {
-     0, 15,  3, 12,  1, 10,  2,  5,  4,  8, 11,  7, 14, 13,  9,  6
-};
-
-static const uint8_t clv_flagsu_1_bits[] = {
-     1,  4,  4,  4,  4,  4,  4,  4,  5,  6,  8,  8,  8,  9, 10, 10
-};
-
-static const uint8_t clv_flagsu_1_syms[] = {
-     0,  2, 12,  3,  4,  1,  8,  5, 10,  7,  9,  6, 11, 14, 13, 15
-};
-
-static const uint8_t clv_flagsv_0_bits[] = {
-     1,  3,  4,  4,  4,  5,  5,  5,  5,  5,  6,  7,  8,  9, 10, 10
-};
-
-static const uint8_t clv_flagsv_0_syms[] = {
-     0, 15,  1, 12,  3, 10,  2,  5,  8,  4, 11, 14,  6,  9,  7, 13
-};
-
-static const uint8_t clv_flagsv_1_bits[] = {
-     1,  3,  4,  4,  4,  4,  5,  5,  5,  6,  7,  8,  9, 10, 11, 11
-};
-
-static const uint8_t clv_flagsv_1_syms[] = {
-     0,  8,  3,  4,  2,  1, 12,  5, 10,  7,  9,  6, 14, 11, 13, 15
+static const uint16_t clv_mv_escape[] = {
+    0x0909, 0x0A0A, 0x1010, 0x1313, 0, 0x0808, 0x0B0B, 0, 0x0808, 0x0B0B
 };
 
 static const uint8_t clv_mvy_0_bits[] = {
@@ -1034,4 +1002,40 @@  static const uint16_t clv_biasv_2_syms[] = {
     0x0048, 0xFFB4, 0x004C, 0x0100, 0xFFB0, 0x0054, 0xFFAC, 0x0050
 };
 
+static const uint8_t *const clv_bias_bits[] = {
+    clv_biasy_1_bits, clv_biasy_2_bits, clv_biasy_3_bits,
+    clv_biasu_1_bits, clv_biasu_2_bits,
+    clv_biasv_1_bits, clv_biasv_2_bits
+};
+
+static const uint16_t *const clv_bias_syms[] = {
+    clv_biasy_1_syms, clv_biasy_2_syms, clv_biasy_3_syms,
+    clv_biasu_1_syms, clv_biasu_2_syms,
+    clv_biasv_1_syms, clv_biasv_2_syms
+};
+
+static const int clv_bias_sizes[] = {
+    FF_ARRAY_ELEMS(clv_biasy_1_bits), FF_ARRAY_ELEMS(clv_biasy_2_bits), FF_ARRAY_ELEMS(clv_biasy_3_bits),
+    FF_ARRAY_ELEMS(clv_biasu_1_bits), FF_ARRAY_ELEMS(clv_biasu_2_bits),
+    FF_ARRAY_ELEMS(clv_biasv_1_bits), FF_ARRAY_ELEMS(clv_biasv_2_bits)
+};
+
+static const uint8_t *const clv_mv_bits[] = {
+    clv_mvy_0_bits, clv_mvy_1_bits, clv_mvy_2_bits, clv_mvy_3_bits,
+    NULL, clv_mvu_1_bits, clv_mvu_2_bits,
+    NULL, clv_mvv_1_bits, clv_mvv_2_bits
+};
+
+static const uint16_t *const clv_mv_syms[] = {
+    clv_mvy_0_syms, clv_mvy_1_syms, clv_mvy_2_syms, clv_mvy_3_syms,
+    NULL, clv_mvu_1_syms, clv_mvu_2_syms,
+    NULL, clv_mvv_1_syms, clv_mvv_2_syms
+};
+
+static const int clv_mv_sizes[] = {
+    FF_ARRAY_ELEMS(clv_mvy_0_bits), FF_ARRAY_ELEMS(clv_mvy_1_bits), FF_ARRAY_ELEMS(clv_mvy_2_bits), FF_ARRAY_ELEMS(clv_mvy_3_bits),
+    0, FF_ARRAY_ELEMS(clv_mvu_1_bits), FF_ARRAY_ELEMS(clv_mvu_2_bits),
+    0, FF_ARRAY_ELEMS(clv_mvv_1_bits), FF_ARRAY_ELEMS(clv_mvv_2_bits)
+};
+
 #endif /* AVCODEC_CLEARVIDEODATA_H */