[FFmpeg-devel] [PATCH 06/13] avcodec/dcaenc: Create encoder-adapted tables

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Tue Sep 13 14:33:03 EEST 2022


Up until now, the encoder used the same tables that the decoder
uses to create its VLCs. These have the downside of requiring
the encoder to offset the tables at runtime as well as having
to read from separate tables for the length as well as the code
of the symbol to encode. The former are uint8_t, the latter uint16_t,
so using a joint table would require padding, but this doesn't
matter when these tables are generated at runtime, because they
live in the .bss segment.

Also move these init functions as well as the functions that
actually use them to dcaenc.c, because they are encoder-specific.
This also allows to remove an inclusion of PutBitContext from
dcahuff.h (and indirectly from all dca-decoder files).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
 libavcodec/dcaenc.c  | 82 ++++++++++++++++++++++++++++++++++++++++----
 libavcodec/dcahuff.c | 64 ++++++----------------------------
 libavcodec/dcahuff.h | 16 ++++++---
 3 files changed, 96 insertions(+), 66 deletions(-)

diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c
index d02602761b..4a02aa9d46 100644
--- a/libavcodec/dcaenc.c
+++ b/libavcodec/dcaenc.c
@@ -29,6 +29,7 @@
 #include "libavutil/ffmath.h"
 #include "libavutil/mem_internal.h"
 #include "libavutil/opt.h"
+#include "libavutil/thread.h"
 #include "avcodec.h"
 #include "codec_internal.h"
 #include "dca.h"
@@ -159,8 +160,41 @@ static void subband_bufer_free(DCAEncContext *c)
     }
 }
 
+static uint16_t bitalloc_12_table[DCA_BITALLOC_12_COUNT][12 + 1][2];
+
+static uint16_t bitalloc_table[DCA_NUM_BITALLOC_CODES][2];
+static const uint16_t (*bitalloc_tables[DCA_CODE_BOOKS][8])[2];
+
+static av_cold void create_enc_table(uint16_t dst[][2], unsigned count,
+                                     const uint8_t len[], const uint16_t codes[])
+{
+    for (unsigned i = 0; i < count; i++) {
+        dst[i][0] = codes[i];
+        dst[i][1] = len[i];
+    }
+}
+
+static av_cold void dcaenc_init_static_tables(void)
+{
+    uint16_t (*bitalloc_dst)[2] = bitalloc_table;
+
+    for (unsigned i = 0; i < DCA_CODE_BOOKS; i++) {
+        for (unsigned j = 0; ff_dca_bitalloc_codes[i][j]; j++) {
+            create_enc_table(bitalloc_dst, ff_dca_bitalloc_sizes[i],
+                             ff_dca_bitalloc_bits[i][j], ff_dca_bitalloc_codes[i][j]);
+            bitalloc_tables[i][j] = bitalloc_dst - ff_dca_bitalloc_offsets[i];
+            bitalloc_dst += ff_dca_bitalloc_sizes[i];
+        }
+    }
+
+    for (unsigned i = 0; i < DCA_BITALLOC_12_COUNT; i++)
+        create_enc_table(&bitalloc_12_table[i][1], 12,
+                         ff_dca_bitalloc_12_bits[i], ff_dca_bitalloc_12_codes[i]);
+}
+
 static int encode_init(AVCodecContext *avctx)
 {
+    static AVOnce init_static_once = AV_ONCE_INIT;
     DCAEncContext *c = avctx->priv_data;
     AVChannelLayout layout = avctx->ch_layout;
     int i, j, k, min_frame_bits;
@@ -307,6 +341,7 @@ static int encode_init(AVCodecContext *avctx)
         c->band_spectrum_tab[1][j] = (int32_t)(200 * log10(accum));
     }
 
+    ff_thread_once(&init_static_once, dcaenc_init_static_tables);
     return 0;
 }
 
@@ -400,6 +435,39 @@ static void lfe_downsample(DCAEncContext *c, const int32_t *input)
     }
 }
 
+static uint32_t dca_vlc_calc_alloc_bits(const int values[], uint8_t n, uint8_t sel)
+{
+    uint32_t sum = 0;
+    for (unsigned i = 0; i < n; i++)
+        sum += bitalloc_12_table[sel][values[i]][1];
+    return sum;
+}
+
+static void dca_vlc_enc_alloc(PutBitContext *pb, const int values[],
+                              uint8_t n, uint8_t sel)
+{
+    for (unsigned i = 0; i < n; i++)
+        put_bits(pb, bitalloc_12_table[sel][values[i]][1],
+                     bitalloc_12_table[sel][values[i]][0]);
+}
+
+static uint32_t dca_vlc_calc_quant_bits(const int values[], uint8_t n,
+                                        uint8_t sel, uint8_t table)
+{
+    uint32_t sum = 0;
+    for (unsigned i = 0; i < n; i++)
+        sum += bitalloc_tables[table][sel][values[i]][1];
+    return sum;
+}
+
+static void dca_vlc_enc_quant(PutBitContext *pb, const int values[],
+                              uint8_t n, uint8_t sel, uint8_t table)
+{
+    for (unsigned i = 0; i < n; i++)
+        put_bits(pb, bitalloc_tables[table][sel][values[i]][1],
+                     bitalloc_tables[table][sel][values[i]][0]);
+}
+
 static int32_t get_cb(DCAEncContext *c, int32_t in)
 {
     int i, res = 0;
@@ -695,8 +763,8 @@ static void accumulate_huff_bit_consumption(int abits, int32_t *quantized,
 {
     uint8_t sel, id = abits - 1;
     for (sel = 0; sel < ff_dca_quant_index_group_size[id]; sel++)
-        result[sel] += ff_dca_vlc_calc_quant_bits(quantized, SUBBAND_SAMPLES,
-                                                  sel, id);
+        result[sel] += dca_vlc_calc_quant_bits(quantized, SUBBAND_SAMPLES,
+                                               sel, id);
 }
 
 static uint32_t set_best_code(uint32_t vlc_bits[DCA_CODE_BOOKS][7],
@@ -757,7 +825,7 @@ static uint32_t set_best_abits_code(int abits[DCAENC_SUBBANDS], int bands,
     }
 
     for (i = 0; i < DCA_BITALLOC_12_COUNT; i++) {
-        t = ff_dca_vlc_calc_alloc_bits(abits, bands, i);
+        t = dca_vlc_calc_alloc_bits(abits, bands, i);
         if (t < best_bits) {
             best_bits = t;
             best_sel = i;
@@ -1081,8 +1149,8 @@ static void put_subframe_samples(DCAEncContext *c, int ss, int band, int ch)
         sel = c->quant_index_sel[ch][c->abits[ch][band] - 1];
         // Huffman codes
         if (sel < ff_dca_quant_index_group_size[c->abits[ch][band] - 1]) {
-            ff_dca_vlc_enc_quant(&c->pb, &c->quantized[ch][band][ss * 8], 8,
-                                 sel, c->abits[ch][band] - 1);
+            dca_vlc_enc_quant(&c->pb, &c->quantized[ch][band][ss * 8], 8,
+                              sel, c->abits[ch][band] - 1);
             return;
         }
 
@@ -1135,8 +1203,8 @@ static void put_subframe(DCAEncContext *c, int subframe)
                 put_bits(&c->pb, 5, c->abits[ch][band]);
             }
         } else {
-            ff_dca_vlc_enc_alloc(&c->pb, c->abits[ch], DCAENC_SUBBANDS,
-                                 c->bit_allocation_sel[ch]);
+            dca_vlc_enc_alloc(&c->pb, c->abits[ch], DCAENC_SUBBANDS,
+                              c->bit_allocation_sel[ch]);
         }
     }
 
diff --git a/libavcodec/dcahuff.c b/libavcodec/dcahuff.c
index 842b1401dd..d17b49a089 100644
--- a/libavcodec/dcahuff.c
+++ b/libavcodec/dcahuff.c
@@ -22,11 +22,9 @@
 
 #include <stddef.h>
 
-#include "libavutil/avassert.h"
 #include "libavutil/macros.h"
 
 #include "dcahuff.h"
-#include "put_bits.h"
 
 #define TMODE_COUNT 4
 static const uint16_t tmode_codes[TMODE_COUNT][4] = {
@@ -47,7 +45,7 @@ static const uint8_t bitalloc_12_vlc_bits[DCA_BITALLOC_12_COUNT] = {
     9, 7, 7, 9, 9
 };
 
-static const uint16_t bitalloc_12_codes[DCA_BITALLOC_12_COUNT][12] = {
+const uint16_t ff_dca_bitalloc_12_codes[DCA_BITALLOC_12_COUNT][12] = {
     { 0x0000, 0x0002, 0x0006, 0x000E, 0x001E, 0x003E, 0x00FF, 0x00FE,
       0x01FB, 0x01FA, 0x01F9, 0x01F8, },
     { 0x0001, 0x0000, 0x0002, 0x000F, 0x000C, 0x001D, 0x0039, 0x0038,
@@ -60,7 +58,7 @@ static const uint16_t bitalloc_12_codes[DCA_BITALLOC_12_COUNT][12] = {
       0x0079, 0x0078, 0x00FB, 0x00FA, }
 };
 
-static const uint8_t bitalloc_12_bits[DCA_BITALLOC_12_COUNT][12] = {
+const uint8_t ff_dca_bitalloc_12_bits[DCA_BITALLOC_12_COUNT][12] = {
     { 1, 2, 3, 4, 5, 6, 8, 8, 9, 9,  9,  9 },
     { 1, 2, 3, 5, 5, 6, 7, 7, 7, 7,  7,  7 },
     { 2, 3, 3, 3, 3, 4, 4, 4, 5, 6,  7,  7 },
@@ -980,11 +978,11 @@ static const uint8_t bitalloc_129_bits_g[129] = {
     13,
 };
 
-static const uint8_t bitalloc_sizes[DCA_CODE_BOOKS] = {
+const uint8_t ff_dca_bitalloc_sizes[DCA_CODE_BOOKS] = {
     3, 5, 7, 9, 13, 17, 25, 33, 65, 129
 };
 
-static const int8_t bitalloc_offsets[DCA_CODE_BOOKS] = {
+const int8_t ff_dca_bitalloc_offsets[DCA_CODE_BOOKS] = {
     -1, -2, -3, -4, -6, -8, -12, -16, -32, -64
 };
 
@@ -1001,7 +999,7 @@ static const uint8_t bitalloc_maxbits[DCA_CODE_BOOKS][7] = {
     { 9, 9, 9, 9, 9, 9, 9 }
 };
 
-static const uint16_t *const bitalloc_codes[DCA_CODE_BOOKS][8] = {
+const uint16_t *const ff_dca_bitalloc_codes[DCA_CODE_BOOKS][8] = {
     { bitalloc_3_codes,     NULL },
     { bitalloc_5_codes_a,   bitalloc_5_codes_b,   bitalloc_5_codes_c,   NULL },
     { bitalloc_7_codes_a,   bitalloc_7_codes_b,   bitalloc_7_codes_c,   NULL },
@@ -1019,7 +1017,7 @@ static const uint16_t *const bitalloc_codes[DCA_CODE_BOOKS][8] = {
       bitalloc_129_codes_e, bitalloc_129_codes_f, bitalloc_129_codes_g, NULL }
 };
 
-static const uint8_t *const bitalloc_bits[DCA_CODE_BOOKS][8] = {
+const uint8_t *const ff_dca_bitalloc_bits[DCA_CODE_BOOKS][8] = {
     { bitalloc_3_bits,     NULL },
     { bitalloc_5_bits_a,   bitalloc_5_bits_b,   bitalloc_5_bits_c,   NULL },
     { bitalloc_7_bits_a,   bitalloc_7_bits_b,   bitalloc_7_bits_c,   NULL },
@@ -1267,7 +1265,7 @@ av_cold void ff_dca_init_vlcs(void)
     ff_dca_vlc_bit_allocation.max_depth = 2;
     for (i = 0; i < 5; i++)
         DCA_INIT_VLC(ff_dca_vlc_bit_allocation.vlc[i], bitalloc_12_vlc_bits[i], 12,
-                     bitalloc_12_bits[i], bitalloc_12_codes[i]);
+                     ff_dca_bitalloc_12_bits[i], ff_dca_bitalloc_12_codes[i]);
 
     ff_dca_vlc_scale_factor.offset    = -64;
     ff_dca_vlc_scale_factor.max_depth = 2;
@@ -1280,11 +1278,11 @@ av_cold void ff_dca_init_vlcs(void)
                      tmode_bits[i], tmode_codes[i]);
 
     for (i = 0; i < DCA_CODE_BOOKS; i++) {
-        ff_dca_vlc_quant_index[i].offset    = bitalloc_offsets[i];
+        ff_dca_vlc_quant_index[i].offset    = ff_dca_bitalloc_offsets[i];
         ff_dca_vlc_quant_index[i].max_depth = 1 + (i > 4);
-        for (j = 0; bitalloc_codes[i][j]; j++)
+        for (j = 0; ff_dca_bitalloc_codes[i][j]; j++)
             DCA_INIT_VLC(ff_dca_vlc_quant_index[i].vlc[j], bitalloc_maxbits[i][j],
-                         bitalloc_sizes[i], bitalloc_bits[i][j], bitalloc_codes[i][j]);
+                         ff_dca_bitalloc_sizes[i], ff_dca_bitalloc_bits[i][j], ff_dca_bitalloc_codes[i][j]);
     }
 
 #define LBR_INIT_VLC(vlc, tab, nb_bits)                                 \
@@ -1316,45 +1314,3 @@ av_cold void ff_dca_init_vlcs(void)
     LBR_INIT_VLC(ff_dca_vlc_grid_3,      grid_3,      9);
     LBR_INIT_VLC(ff_dca_vlc_rsd,         rsd,         6);
 }
-
-uint32_t ff_dca_vlc_calc_quant_bits(int *values, uint8_t n, uint8_t sel, uint8_t table)
-{
-    uint8_t i, id;
-    uint32_t sum = 0;
-    for (i = 0; i < n; i++) {
-        id = values[i] - bitalloc_offsets[table];
-        av_assert0(id < bitalloc_sizes[table]);
-        sum += bitalloc_bits[table][sel][id];
-    }
-    return sum;
-}
-
-void ff_dca_vlc_enc_quant(PutBitContext *pb, int *values, uint8_t n, uint8_t sel, uint8_t table)
-{
-    uint8_t i, id;
-    for (i = 0; i < n; i++) {
-        id = values[i] - bitalloc_offsets[table];
-        av_assert0(id < bitalloc_sizes[table]);
-        put_bits(pb, bitalloc_bits[table][sel][id], bitalloc_codes[table][sel][id]);
-    }
-}
-
-uint32_t ff_dca_vlc_calc_alloc_bits(int *values, uint8_t n, uint8_t sel)
-{
-    uint8_t i, id;
-    uint32_t sum = 0;
-    for (i = 0; i < n; i++) {
-        id = values[i] - 1;
-        sum += bitalloc_12_bits[sel][id];
-    }
-    return sum;
-}
-
-void ff_dca_vlc_enc_alloc(PutBitContext *pb, int *values, uint8_t n, uint8_t sel)
-{
-    uint8_t i, id;
-    for (i = 0; i < n; i++) {
-        id = values[i] - 1;
-        put_bits(pb, bitalloc_12_bits[sel][id], bitalloc_12_codes[sel][id]);
-    }
-}
diff --git a/libavcodec/dcahuff.h b/libavcodec/dcahuff.h
index 1f13b6f443..68974d9965 100644
--- a/libavcodec/dcahuff.h
+++ b/libavcodec/dcahuff.h
@@ -27,11 +27,13 @@
 
 #include "libavutil/attributes.h"
 
-#include "put_bits.h"
 #include "vlc.h"
 
 #define DCA_CODE_BOOKS      10
 #define DCA_BITALLOC_12_COUNT    5
+#define DCA_NUM_BITALLOC_CODES (1 * 3 + \
+                                3 * (5 + 7 + 9 + 13) \
+                                + 7 * (17 + 25 + 33 + 65 + 129))
 
 typedef struct DCAVLC {
     int offset;         ///< Code values offset
@@ -58,10 +60,14 @@ extern VLC  ff_dca_vlc_grid_2;
 extern VLC  ff_dca_vlc_grid_3;
 extern VLC  ff_dca_vlc_rsd;
 
+extern const int8_t  ff_dca_bitalloc_offsets[DCA_CODE_BOOKS];
+extern const uint8_t ff_dca_bitalloc_sizes[DCA_CODE_BOOKS];
+extern const uint16_t *const ff_dca_bitalloc_codes[DCA_CODE_BOOKS][8];
+extern const uint8_t  *const ff_dca_bitalloc_bits[DCA_CODE_BOOKS][8];
+
+extern const uint8_t  ff_dca_bitalloc_12_bits[DCA_BITALLOC_12_COUNT][12];
+extern const uint16_t ff_dca_bitalloc_12_codes[DCA_BITALLOC_12_COUNT][12];
+
 av_cold void ff_dca_init_vlcs(void);
-uint32_t ff_dca_vlc_calc_quant_bits(int *values, uint8_t n, uint8_t sel, uint8_t abits);
-void ff_dca_vlc_enc_quant(PutBitContext *pb, int *values, uint8_t n, uint8_t sel, uint8_t abits);
-uint32_t ff_dca_vlc_calc_alloc_bits(int *values, uint8_t n, uint8_t sel);
-void ff_dca_vlc_enc_alloc(PutBitContext *pb, int *values, uint8_t n, uint8_t sel);
 
 #endif /* AVCODEC_DCAHUFF_H */
-- 
2.34.1



More information about the ffmpeg-devel mailing list