dcaenc: Implementation of Huffman codes for DCA encoder
authorDaniil Cherednik <dan.cherednik@gmail.com>
Sat, 7 Jan 2017 12:18:32 +0000 (15:18 +0300)
committerRostislav Pehlivanov <atomnuker@gmail.com>
Sun, 15 Jan 2017 18:17:12 +0000 (18:17 +0000)
Reviewed-by: Rostislav Pehlivanov <atomnuker@gmail.com>
libavcodec/Makefile
libavcodec/dca_core.c
libavcodec/dcadata.c
libavcodec/dcadata.h
libavcodec/dcaenc.c
libavcodec/dcaenc.h
libavcodec/dcahuff.c
libavcodec/dcahuff.h
tests/fate/acodec.mak

index 4494f26..7094722 100644 (file)
@@ -235,7 +235,7 @@ OBJS-$(CONFIG_CYUV_DECODER)            += cyuv.o
 OBJS-$(CONFIG_DCA_DECODER)             += dcadec.o dca.o dcadata.o dcahuff.o \
                                           dca_core.o dca_exss.o dca_xll.o dca_lbr.o \
                                           dcadsp.o dcadct.o synth_filter.o
-OBJS-$(CONFIG_DCA_ENCODER)             += dcaenc.o dca.o dcadata.o
+OBJS-$(CONFIG_DCA_ENCODER)             += dcaenc.o dca.o dcadata.o dcahuff.o
 OBJS-$(CONFIG_DDS_DECODER)             += dds.o
 OBJS-$(CONFIG_DIRAC_DECODER)           += diracdec.o dirac.o diracdsp.o diractab.o \
                                           dirac_arith.o dirac_dwt.o dirac_vlc.o
index 46825ed..d5e628e 100644 (file)
@@ -92,14 +92,6 @@ static const uint8_t block_code_nbits[7] = {
     7, 10, 12, 13, 15, 17, 19
 };
 
-static const uint8_t quant_index_sel_nbits[DCA_CODE_BOOKS] = {
-    1, 2, 2, 2, 2, 3, 3, 3, 3, 3
-};
-
-static const uint8_t quant_index_group_size[DCA_CODE_BOOKS] = {
-    1, 3, 3, 3, 3, 7, 7, 7, 7, 7
-};
-
 static int dca_get_vlc(GetBitContext *s, DCAVLC *v, int i)
 {
     return get_vlc2(s, v->vlc[i].table, v->vlc[i].bits, v->max_depth) + v->offset;
@@ -400,12 +392,12 @@ static int parse_coding_header(DCACoreDecoder *s, enum HeaderType header, int xc
     // Quantization index codebook select
     for (n = 0; n < DCA_CODE_BOOKS; n++)
         for (ch = xch_base; ch < s->nchannels; ch++)
-            s->quant_index_sel[ch][n] = get_bits(&s->gb, quant_index_sel_nbits[n]);
+            s->quant_index_sel[ch][n] = get_bits(&s->gb, ff_dca_quant_index_sel_nbits[n]);
 
     // Scale factor adjustment index
     for (n = 0; n < DCA_CODE_BOOKS; n++)
         for (ch = xch_base; ch < s->nchannels; ch++)
-            if (s->quant_index_sel[ch][n] < quant_index_group_size[n])
+            if (s->quant_index_sel[ch][n] < ff_dca_quant_index_group_size[n])
                 s->scale_factor_adj[ch][n] = ff_dca_scale_factor_adj[get_bits(&s->gb, 2)];
 
     if (header == HEADER_XXCH) {
@@ -663,7 +655,7 @@ static inline int extract_audio(DCACoreDecoder *s, int32_t *audio, int abits, in
 
     if (abits <= DCA_CODE_BOOKS) {
         int sel = s->quant_index_sel[ch][abits - 1];
-        if (sel < quant_index_group_size[abits - 1]) {
+        if (sel < ff_dca_quant_index_group_size[abits - 1]) {
             // Huffman codes
             return parse_huffman_codes(s, audio, abits, sel);
         }
@@ -1562,7 +1554,7 @@ static int parse_x96_coding_header(DCACoreDecoder *s, int exss, int xch_base)
     // Quantization index codebook select
     for (n = 0; n < 6 + 4 * s->x96_high_res; n++)
         for (ch = xch_base; ch < s->x96_nchannels; ch++)
-            s->quant_index_sel[ch][n] = get_bits(&s->gb, quant_index_sel_nbits[n]);
+            s->quant_index_sel[ch][n] = get_bits(&s->gb, ff_dca_quant_index_sel_nbits[n]);
 
     if (exss) {
         // Reserved
index b2e0f6c..193247b 100644 (file)
@@ -50,6 +50,14 @@ const uint8_t ff_dca_dmix_primary_nch[8] = {
     1, 2, 2, 3, 3, 4, 4, 0
 };
 
+const uint8_t ff_dca_quant_index_sel_nbits[DCA_CODE_BOOKS] = {
+    1, 2, 2, 2, 2, 3, 3, 3, 3, 3
+};
+
+const uint8_t ff_dca_quant_index_group_size[DCA_CODE_BOOKS] = {
+    1, 3, 3, 3, 3, 7, 7, 7, 7, 7
+};
+
 /* ADPCM data */
 
 /* 16 bits signed fractional Q13 binary codes */
index 17aa712..c838867 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <stdint.h>
 
+#include "dcahuff.h"
+
 extern const uint32_t ff_dca_bit_rates[32];
 
 extern const uint8_t ff_dca_channels[16];
@@ -31,6 +33,9 @@ extern const uint8_t ff_dca_bits_per_sample[8];
 
 extern const uint8_t ff_dca_dmix_primary_nch[8];
 
+extern const uint8_t ff_dca_quant_index_sel_nbits[DCA_CODE_BOOKS];
+extern const uint8_t ff_dca_quant_index_group_size[DCA_CODE_BOOKS];
+
 extern const int16_t ff_dca_adpcm_vb[4096][4];
 
 extern const uint32_t ff_dca_scale_factor_quant6[64];
index 3af2a35..ff7b0eb 100644 (file)
@@ -70,6 +70,7 @@ typedef struct DCAEncContext {
     int abits[MAX_CHANNELS][DCAENC_SUBBANDS];
     int scale_factor[MAX_CHANNELS][DCAENC_SUBBANDS];
     softfloat quant[MAX_CHANNELS][DCAENC_SUBBANDS];
+    int32_t quant_index_sel[MAX_CHANNELS][DCA_CODE_BOOKS];
     int32_t eff_masking_curve_cb[256];
     int32_t band_masking_cb[32];
     int32_t worst_quantization_noise;
@@ -109,7 +110,7 @@ static int encode_init(AVCodecContext *avctx)
 {
     DCAEncContext *c = avctx->priv_data;
     uint64_t layout = avctx->channel_layout;
-    int i, min_frame_bits;
+    int i, j, min_frame_bits;
 
     c->fullband_channels = c->channels = avctx->channels;
     c->lfe_channel = (avctx->channels == 3 || avctx->channels == 6);
@@ -142,6 +143,12 @@ static int encode_init(AVCodecContext *avctx)
         c->channel_order_tab = channel_reorder_nolfe[c->channel_config];
     }
 
+    for (i = 0; i < MAX_CHANNELS; i++) {
+        for (j = 0; j < DCA_CODE_BOOKS; j++) {
+            c->quant_index_sel[i][j] = ff_dca_quant_index_group_size[j];
+        }
+    }
+
     for (i = 0; i < 9; i++) {
         if (sample_rates[i] == avctx->sample_rate)
             break;
@@ -568,9 +575,109 @@ static const int snr_fudge = 128;
 #define USED_NABITS 2
 #define USED_26ABITS 4
 
+static int32_t quantize_value(int32_t value, softfloat quant)
+{
+    int32_t offset = 1 << (quant.e - 1);
+
+    value = mul32(value, quant.m) + offset;
+    value = value >> quant.e;
+    return value;
+}
+
+static int calc_one_scale(int32_t peak_cb, int abits, softfloat *quant)
+{
+    int32_t peak;
+    int our_nscale, try_remove;
+    softfloat our_quant;
+
+    av_assert0(peak_cb <= 0);
+    av_assert0(peak_cb >= -2047);
+
+    our_nscale = 127;
+    peak = cb_to_level[-peak_cb];
+
+    for (try_remove = 64; try_remove > 0; try_remove >>= 1) {
+        if (scalefactor_inv[our_nscale - try_remove].e + stepsize_inv[abits].e <= 17)
+            continue;
+        our_quant.m = mul32(scalefactor_inv[our_nscale - try_remove].m, stepsize_inv[abits].m);
+        our_quant.e = scalefactor_inv[our_nscale - try_remove].e + stepsize_inv[abits].e - 17;
+        if ((ff_dca_quant_levels[abits] - 1) / 2 < quantize_value(peak, our_quant))
+            continue;
+        our_nscale -= try_remove;
+    }
+
+    if (our_nscale >= 125)
+        our_nscale = 124;
+
+    quant->m = mul32(scalefactor_inv[our_nscale].m, stepsize_inv[abits].m);
+    quant->e = scalefactor_inv[our_nscale].e + stepsize_inv[abits].e - 17;
+    av_assert0((ff_dca_quant_levels[abits] - 1) / 2 >= quantize_value(peak, *quant));
+
+    return our_nscale;
+}
+
+static void quantize_all(DCAEncContext *c)
+{
+    int sample, band, ch;
+
+    for (ch = 0; ch < c->fullband_channels; ch++)
+        for (band = 0; band < 32; band++)
+            for (sample = 0; sample < SUBBAND_SAMPLES; sample++)
+                c->quantized[ch][band][sample] = quantize_value(c->subband[ch][band][sample], c->quant[ch][band]);
+}
+
+static void accumulate_huff_bit_consumption(int abits, int32_t *quantized, uint32_t *result)
+{
+    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);
+}
+
+static uint32_t set_best_code(uint32_t vlc_bits[DCA_CODE_BOOKS][7], uint32_t clc_bits[DCA_CODE_BOOKS], int32_t res[DCA_CODE_BOOKS])
+{
+    uint8_t i, sel;
+    uint32_t best_sel_bits[DCA_CODE_BOOKS];
+    int32_t best_sel_id[DCA_CODE_BOOKS];
+    uint32_t t, bits = 0;
+
+    for (i = 0; i < DCA_CODE_BOOKS; i++) {
+
+        av_assert0(!((!!vlc_bits[i][0]) ^ (!!clc_bits[i])));
+        if (vlc_bits[i][0] == 0) {
+            /* do not transmit adjustment index for empty codebooks */
+            res[i] = ff_dca_quant_index_group_size[i];
+            /* and skip it */
+            continue;
+        }
+
+        best_sel_bits[i] = vlc_bits[i][0];
+        best_sel_id[i] = 0;
+        for (sel = 0; sel < ff_dca_quant_index_group_size[i]; sel++) {
+            if (best_sel_bits[i] > vlc_bits[i][sel] && vlc_bits[i][sel]) {
+                best_sel_bits[i] = vlc_bits[i][sel];
+                best_sel_id[i] = sel;
+            }
+        }
+
+        /* 2 bits to transmit scale factor adjustment index */
+        t = best_sel_bits[i] + 2;
+        if (t < clc_bits[i]) {
+            res[i] = best_sel_id[i];
+            bits += t;
+        } else {
+            res[i] = ff_dca_quant_index_group_size[i];
+            bits += clc_bits[i];
+        }
+    }
+    return bits;
+}
+
 static int init_quantization_noise(DCAEncContext *c, int noise)
 {
     int ch, band, ret = 0;
+    uint32_t huff_bit_count_accum[MAX_CHANNELS][DCA_CODE_BOOKS][7];
+    uint32_t clc_bit_count_accum[MAX_CHANNELS][DCA_CODE_BOOKS];
+    uint32_t bits_counter = 0;
 
     c->consumed_bits = 132 + 493 * c->fullband_channels;
     if (c->lfe_channel)
@@ -597,10 +704,36 @@ static int init_quantization_noise(DCAEncContext *c, int noise)
         }
     }
 
-    for (ch = 0; ch < c->fullband_channels; ch++)
+    /* Recalc scale_factor each time to get bits consumption in case of Huffman coding.
+       It is suboptimal solution */
+    /* TODO: May be cache scaled values */
+    for (ch = 0; ch < c->fullband_channels; ch++) {
+        for (band = 0; band < 32; band++) {
+            c->scale_factor[ch][band] = calc_one_scale(c->peak_cb[ch][band],
+                                                       c->abits[ch][band],
+                                                       &c->quant[ch][band]);
+        }
+    }
+    quantize_all(c);
+
+    memset(huff_bit_count_accum, 0, MAX_CHANNELS * DCA_CODE_BOOKS * 7 * sizeof(uint32_t));
+    memset(clc_bit_count_accum, 0, MAX_CHANNELS * DCA_CODE_BOOKS * sizeof(uint32_t));
+    for (ch = 0; ch < c->fullband_channels; ch++) {
         for (band = 0; band < 32; band++) {
-            c->consumed_bits += bit_consumption[c->abits[ch][band]];
+            if (c->abits[ch][band] && c->abits[ch][band] <= DCA_CODE_BOOKS) {
+                accumulate_huff_bit_consumption(c->abits[ch][band], c->quantized[ch][band], huff_bit_count_accum[ch][c->abits[ch][band] - 1]);
+                clc_bit_count_accum[ch][c->abits[ch][band] - 1] += bit_consumption[c->abits[ch][band]];
+            } else {
+                bits_counter += bit_consumption[c->abits[ch][band]];
+            }
         }
+    }
+
+    for (ch = 0; ch < c->fullband_channels; ch++) {
+        bits_counter += set_best_code(huff_bit_count_accum[ch], clc_bit_count_accum[ch], c->quant_index_sel[ch]);
+    }
+
+    c->consumed_bits += bits_counter;
 
     return ret;
 }
@@ -655,71 +788,12 @@ static void shift_history(DCAEncContext *c, const int32_t *input)
         }
 }
 
-static int32_t quantize_value(int32_t value, softfloat quant)
-{
-    int32_t offset = 1 << (quant.e - 1);
-
-    value = mul32(value, quant.m) + offset;
-    value = value >> quant.e;
-    return value;
-}
-
-static int calc_one_scale(int32_t peak_cb, int abits, softfloat *quant)
-{
-    int32_t peak;
-    int our_nscale, try_remove;
-    softfloat our_quant;
-
-    av_assert0(peak_cb <= 0);
-    av_assert0(peak_cb >= -2047);
-
-    our_nscale = 127;
-    peak = cb_to_level[-peak_cb];
-
-    for (try_remove = 64; try_remove > 0; try_remove >>= 1) {
-        if (scalefactor_inv[our_nscale - try_remove].e + stepsize_inv[abits].e <= 17)
-            continue;
-        our_quant.m = mul32(scalefactor_inv[our_nscale - try_remove].m, stepsize_inv[abits].m);
-        our_quant.e = scalefactor_inv[our_nscale - try_remove].e + stepsize_inv[abits].e - 17;
-        if ((ff_dca_quant_levels[abits] - 1) / 2 < quantize_value(peak, our_quant))
-            continue;
-        our_nscale -= try_remove;
-    }
-
-    if (our_nscale >= 125)
-        our_nscale = 124;
-
-    quant->m = mul32(scalefactor_inv[our_nscale].m, stepsize_inv[abits].m);
-    quant->e = scalefactor_inv[our_nscale].e + stepsize_inv[abits].e - 17;
-    av_assert0((ff_dca_quant_levels[abits] - 1) / 2 >= quantize_value(peak, *quant));
-
-    return our_nscale;
-}
-
-static void calc_scales(DCAEncContext *c)
+static void calc_lfe_scales(DCAEncContext *c)
 {
-    int band, ch;
-
-    for (ch = 0; ch < c->fullband_channels; ch++)
-        for (band = 0; band < 32; band++)
-            c->scale_factor[ch][band] = calc_one_scale(c->peak_cb[ch][band],
-                                                       c->abits[ch][band],
-                                                       &c->quant[ch][band]);
-
     if (c->lfe_channel)
         c->lfe_scale_factor = calc_one_scale(c->lfe_peak_cb, 11, &c->lfe_quant);
 }
 
-static void quantize_all(DCAEncContext *c)
-{
-    int sample, band, ch;
-
-    for (ch = 0; ch < c->fullband_channels; ch++)
-        for (band = 0; band < 32; band++)
-            for (sample = 0; sample < SUBBAND_SAMPLES; sample++)
-                c->quantized[ch][band][sample] = quantize_value(c->subband[ch][band][sample], c->quant[ch][band]);
-}
-
 static void put_frame_header(DCAEncContext *c)
 {
     /* SYNC */
@@ -805,9 +879,6 @@ static void put_frame_header(DCAEncContext *c)
 
 static void put_primary_audio_header(DCAEncContext *c)
 {
-    static const int bitlen[11] = { 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 };
-    static const int thr[11]    = { 0, 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 };
-
     int ch, i;
     /* Number of subframes */
     put_bits(&c->pb, 4, SUBFRAMES - 1);
@@ -839,36 +910,51 @@ static void put_primary_audio_header(DCAEncContext *c)
     for (ch = 0; ch < c->fullband_channels; ch++)
         put_bits(&c->pb, 3, 6);
 
-    /* Quantization index codebook select: dummy data
-       to avoid transmission of scale factor adjustment */
-    for (i = 1; i < 11; i++)
+    /* Quantization index codebook select */
+    for (i = 0; i < DCA_CODE_BOOKS; i++)
         for (ch = 0; ch < c->fullband_channels; ch++)
-            put_bits(&c->pb, bitlen[i], thr[i]);
+            put_bits(&c->pb, ff_dca_quant_index_sel_nbits[i], c->quant_index_sel[ch][i]);
+
+    /* Scale factor adjustment index: transmitted in case of Huffman coding */
+    for (i = 0; i < DCA_CODE_BOOKS; i++)
+        for (ch = 0; ch < c->fullband_channels; ch++)
+            if (c->quant_index_sel[ch][i] < ff_dca_quant_index_group_size[i])
+                put_bits(&c->pb, 2, 0);
 
-    /* Scale factor adjustment index: not transmitted */
     /* Audio header CRC check word: not transmitted */
 }
 
 static void put_subframe_samples(DCAEncContext *c, int ss, int band, int ch)
 {
-    if (c->abits[ch][band] <= 7) {
-        int sum, i, j;
-        for (i = 0; i < 8; i += 4) {
-            sum = 0;
-            for (j = 3; j >= 0; j--) {
-                sum *= ff_dca_quant_levels[c->abits[ch][band]];
-                sum += c->quantized[ch][band][ss * 8 + i + j];
-                sum += (ff_dca_quant_levels[c->abits[ch][band]] - 1) / 2;
-            }
-            put_bits(&c->pb, bit_consumption[c->abits[ch][band]] / 4, sum);
+    int i, j, sum, bits, sel;
+    if (c->abits[ch][band] <= DCA_CODE_BOOKS) {
+        av_assert0(c->abits[ch][band] > 0);
+        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);
+            return;
         }
-    } else {
-        int i;
-        for (i = 0; i < 8; i++) {
-            int bits = bit_consumption[c->abits[ch][band]] / 16;
-            put_sbits(&c->pb, bits, c->quantized[ch][band][ss * 8 + i]);
+
+        // Block codes
+        if (c->abits[ch][band] <= 7) {
+            for (i = 0; i < 8; i += 4) {
+                sum = 0;
+                for (j = 3; j >= 0; j--) {
+                    sum *= ff_dca_quant_levels[c->abits[ch][band]];
+                    sum += c->quantized[ch][band][ss * 8 + i + j];
+                    sum += (ff_dca_quant_levels[c->abits[ch][band]] - 1) / 2;
+                }
+                put_bits(&c->pb, bit_consumption[c->abits[ch][band]] / 4, sum);
+            }
+            return;
         }
     }
+
+    for (i = 0; i < 8; i++) {
+        bits = bit_consumption[c->abits[ch][band]] / 16;
+        put_sbits(&c->pb, bits, c->quantized[ch][band][ss * 8 + i]);
+    }
 }
 
 static void put_subframe(DCAEncContext *c, int subframe)
@@ -947,8 +1033,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
     calc_masking(c, samples);
     find_peaks(c);
     assign_bits(c);
-    calc_scales(c);
-    quantize_all(c);
+    calc_lfe_scales(c);
     shift_history(c, samples);
 
     init_put_bits(&c->pb, avpkt->data, avpkt->size);
index eccfb42..06816c2 100644 (file)
@@ -95,7 +95,6 @@ static const softfloat scalefactor_inv[128] = {
 
 /* manually derived from
  * Table B.5: Selection of quantization levels and codebooks
- * FIXME: will become invalid when Huffman codes are introduced.
  */
 static const int bit_consumption[27] = {
     -8, 28, 40, 48, 52, 60, 68, 76, 80, 96,
index bea3530..9fb42a6 100644 (file)
@@ -1335,3 +1335,25 @@ av_cold void ff_dca_init_vlcs(void)
 
     vlcs_initialized = 1;
 }
+
+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]);
+    }
+}
index b1d5735..c017622 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "avcodec.h"
 #include "get_bits.h"
+#include "put_bits.h"
 
 #define DCA_CODE_BOOKS      10
 
@@ -55,5 +56,7 @@ extern VLC  ff_dca_vlc_grid_3;
 extern VLC  ff_dca_vlc_rsd;
 
 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);
 
 #endif /* AVCODEC_DCAHUFF_H */
index c7d4d26..5c3fea9 100644 (file)
@@ -104,7 +104,7 @@ fate-acodec-dca: tests/data/asynth-44100-2.wav
 fate-acodec-dca: SRC = tests/data/asynth-44100-2.wav
 fate-acodec-dca: CMD = md5 -i $(TARGET_PATH)/$(SRC) -c:a dca -strict -2 -f dts -flags +bitexact
 fate-acodec-dca: CMP = oneline
-fate-acodec-dca: REF = 7ffdefdf47069289990755c79387cc90
+fate-acodec-dca: REF = 7cd79a3717943a06b217f1130223a86f
 
 FATE_ACODEC-$(call ENCDEC, DCA, WAV) += fate-acodec-dca2
 fate-acodec-dca2: CMD = enc_dec_pcm dts wav s16le $(SRC) -c:a dca -strict -2 -flags +bitexact