avcodec/dcaenc: Create encoder-adapted tables

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@outlook.com>
This commit is contained in:
Andreas Rheinhardt 2022-09-05 23:28:01 +02:00
parent 077880ad88
commit 2339f63eac
3 changed files with 96 additions and 66 deletions

View File

@ -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]);
}
}

View File

@ -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]);
}
}

View File

@ -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 */