With real music and 256k bitrate encoding (the source was 44100, 16bit
stereo) I got:
Without Huffman: Best PSNR is  31.77 for shift 0
With: Best PSNR is  37.45 for shift 0

Current implementation of DCA encoder has minimal set of DTS features (no
ADPCM, no VQ, fixed amount of transmitted subbands, no transient control,
etc). So distortion is quite audible. Current set of patches introduces
Huffman encoding for quantized audio data which is equivalent of increasing
bitrate for 10-20%. Also bitstream allows to use Huffman for scale factor
indexes, and some other data. I am working on it too.

I have attached new split set of patches.

On Sat, Jan 7, 2017 at 11:50 PM, Carl Eugen Hoyos <ceffm...@gmail.com>
wrote:

> 2017-01-07 20:39 GMT+01:00 Rostislav Pehlivanov <atomnu...@gmail.com>:
> > On 7 January 2017 at 16:11, Carl Eugen Hoyos <ceffm...@gmail.com> wrote:
> >
> >> 2017-01-07 16:00 GMT+01:00 Даниил Чередник <dan.chered...@gmail.com>:
> >>
> >> > Currently I am working on improvement quality of DTS encoder.
> Following
> >> > patches introduce Huffman coding.
> >>
> >> Is the quality improvement so obvious that no further tests are
> necessary?
> >> (Does psnr improve measurably?)
> >>
> > PSNR is pretty much useless for audio.
>
> > The ear's the only metric which works.
>
> Not everybody's;-))
>
> > From the 2 samples he posted I can tell there's a big difference, and the
> > encoder isn't very good right now and the patch definitely helps.
>
> Thank you!
>
> Carl Eugen
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>



-- 
Daniil Cherednik
From d083e669765b81026130ed50b734f184e44e9424 Mon Sep 17 00:00:00 2001
From: Daniil Cherednik <dan.chered...@gmail.com>
Date: Fri, 6 Jan 2017 02:07:54 +0300
Subject: [PATCH 1/3] avcodec/dcaenc: Reverse data layout to prevent data
 copies during Huffman encoding introduction
To: ffmpeg-devel@ffmpeg.org

---
 libavcodec/dcaenc.c | 88 ++++++++++++++++++++++++++---------------------------
 1 file changed, 43 insertions(+), 45 deletions(-)

diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c
index 6bb7d29..3af2a35 100644
--- a/libavcodec/dcaenc.c
+++ b/libavcodec/dcaenc.c
@@ -61,15 +61,15 @@ typedef struct DCAEncContext {
     int32_t lfe_peak_cb;
     const int8_t *channel_order_tab;  ///< channel reordering table, lfe and non lfe
 
-    int32_t history[512][MAX_CHANNELS]; /* This is a circular buffer */
-    int32_t subband[SUBBAND_SAMPLES][DCAENC_SUBBANDS][MAX_CHANNELS];
-    int32_t quantized[SUBBAND_SAMPLES][DCAENC_SUBBANDS][MAX_CHANNELS];
-    int32_t peak_cb[DCAENC_SUBBANDS][MAX_CHANNELS];
+    int32_t history[MAX_CHANNELS][512]; /* This is a circular buffer */
+    int32_t subband[MAX_CHANNELS][DCAENC_SUBBANDS][SUBBAND_SAMPLES];
+    int32_t quantized[MAX_CHANNELS][DCAENC_SUBBANDS][SUBBAND_SAMPLES];
+    int32_t peak_cb[MAX_CHANNELS][DCAENC_SUBBANDS];
     int32_t downsampled_lfe[DCA_LFE_SAMPLES];
     int32_t masking_curve_cb[SUBSUBFRAMES][256];
-    int abits[DCAENC_SUBBANDS][MAX_CHANNELS];
-    int scale_factor[DCAENC_SUBBANDS][MAX_CHANNELS];
-    softfloat quant[DCAENC_SUBBANDS][MAX_CHANNELS];
+    int abits[MAX_CHANNELS][DCAENC_SUBBANDS];
+    int scale_factor[MAX_CHANNELS][DCAENC_SUBBANDS];
+    softfloat quant[MAX_CHANNELS][DCAENC_SUBBANDS];
     int32_t eff_masking_curve_cb[256];
     int32_t band_masking_cb[32];
     int32_t worst_quantization_noise;
@@ -259,8 +259,7 @@ static void subband_transform(DCAEncContext *c, const int32_t *input)
         int hist_start = 0;
         const int chi = c->channel_order_tab[ch];
 
-        for (i = 0; i < 512; i++)
-            hist[i] = c->history[i][ch];
+        memcpy(hist, &c->history[ch][0], 512 * sizeof(int32_t));
 
         for (subs = 0; subs < SUBBAND_SAMPLES; subs++) {
             int32_t accum[64];
@@ -268,8 +267,7 @@ static void subband_transform(DCAEncContext *c, const int32_t *input)
             int band;
 
             /* Calculate the convolutions at once */
-            for (i = 0; i < 64; i++)
-                accum[i] = 0;
+            memset(accum, 0, 64 * sizeof(int32_t));
 
             for (k = 0, i = hist_start, j = 0;
                     i < 512; k = (k + 1) & 63, i++, j++)
@@ -289,12 +287,13 @@ static void subband_transform(DCAEncContext *c, const int32_t *input)
                     resp += mul32(accum[i], cos_t(s << 3)) >> 3;
                 }
 
-                c->subband[subs][band][ch] = ((band + 1) & 2) ? -resp : resp;
+                c->subband[ch][band][subs] = ((band + 1) & 2) ? -resp : resp;
             }
 
             /* Copy in 32 new samples from input */
             for (i = 0; i < 32; i++)
                 hist[i + hist_start] = input[(subs * 32 + i) * c->channels + chi];
+
             hist_start = (hist_start + 32) & 511;
         }
     }
@@ -309,8 +308,7 @@ static void lfe_downsample(DCAEncContext *c, const int32_t *input)
     int32_t accum;
     int hist_start = 0;
 
-    for (i = 0; i < 512; i++)
-        hist[i] = c->history[i][c->channels - 1];
+    memcpy(hist, &c->history[c->channels - 1][0], 512 * sizeof(int32_t));
 
     for (lfes = 0; lfes < DCA_LFE_SAMPLES; lfes++) {
         /* Calculate the convolution */
@@ -516,7 +514,7 @@ static void calc_masking(DCAEncContext *c, const int32_t *input)
             const int chi = c->channel_order_tab[ch];
 
             for (i = 0, k = 128 + 256 * ssf; k < 512; i++, k++)
-                data[i] = c->history[k][ch];
+                data[i] = c->history[ch][k];
             for (k -= 512; i < 512; i++, k++)
                 data[i] = input[k * c->channels + chi];
             adjust_jnd(c->samplerate_index, data, c->masking_curve_cb[ssf]);
@@ -541,17 +539,17 @@ static void find_peaks(DCAEncContext *c)
 {
     int band, ch;
 
-    for (band = 0; band < 32; band++)
-        for (ch = 0; ch < c->fullband_channels; ch++) {
+    for (ch = 0; ch < c->fullband_channels; ch++)
+        for (band = 0; band < 32; band++) {
             int sample;
             int32_t m = 0;
 
             for (sample = 0; sample < SUBBAND_SAMPLES; sample++) {
-                int32_t s = abs(c->subband[sample][band][ch]);
+                int32_t s = abs(c->subband[ch][band][sample]);
                 if (m < s)
                     m = s;
             }
-            c->peak_cb[band][ch] = get_cb(m);
+            c->peak_cb[ch][band] = get_cb(m);
         }
 
     if (c->lfe_channel) {
@@ -581,27 +579,27 @@ static int init_quantization_noise(DCAEncContext *c, int noise)
     /* attempt to guess the bit distribution based on the prevoius frame */
     for (ch = 0; ch < c->fullband_channels; ch++) {
         for (band = 0; band < 32; band++) {
-            int snr_cb = c->peak_cb[band][ch] - c->band_masking_cb[band] - noise;
+            int snr_cb = c->peak_cb[ch][band] - c->band_masking_cb[band] - noise;
 
             if (snr_cb >= 1312) {
-                c->abits[band][ch] = 26;
+                c->abits[ch][band] = 26;
                 ret |= USED_26ABITS;
             } else if (snr_cb >= 222) {
-                c->abits[band][ch] = 8 + mul32(snr_cb - 222, 69000000);
+                c->abits[ch][band] = 8 + mul32(snr_cb - 222, 69000000);
                 ret |= USED_NABITS;
             } else if (snr_cb >= 0) {
-                c->abits[band][ch] = 2 + mul32(snr_cb, 106000000);
+                c->abits[ch][band] = 2 + mul32(snr_cb, 106000000);
                 ret |= USED_NABITS;
             } else {
-                c->abits[band][ch] = 1;
+                c->abits[ch][band] = 1;
                 ret |= USED_1ABITS;
             }
         }
     }
 
-    for (band = 0; band < 32; band++)
-        for (ch = 0; ch < c->fullband_channels; ch++) {
-            c->consumed_bits += bit_consumption[c->abits[band][ch]];
+    for (ch = 0; ch < c->fullband_channels; ch++)
+        for (band = 0; band < 32; band++) {
+            c->consumed_bits += bit_consumption[c->abits[ch][band]];
         }
 
     return ret;
@@ -653,7 +651,7 @@ static void shift_history(DCAEncContext *c, const int32_t *input)
         for (ch = 0; ch < c->channels; ch++) {
             const int chi = c->channel_order_tab[ch];
 
-            c->history[k][ch] = input[k * c->channels + chi];
+            c->history[ch][k] = input[k * c->channels + chi];
         }
 }
 
@@ -702,11 +700,11 @@ static void calc_scales(DCAEncContext *c)
 {
     int band, ch;
 
-    for (band = 0; band < 32; band++)
-        for (ch = 0; ch < c->fullband_channels; ch++)
-            c->scale_factor[band][ch] = calc_one_scale(c->peak_cb[band][ch],
-                                                       c->abits[band][ch],
-                                                       &c->quant[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);
@@ -716,10 +714,10 @@ static void quantize_all(DCAEncContext *c)
 {
     int sample, band, ch;
 
-    for (sample = 0; sample < SUBBAND_SAMPLES; sample++)
+    for (ch = 0; ch < c->fullband_channels; ch++)
         for (band = 0; band < 32; band++)
-            for (ch = 0; ch < c->fullband_channels; ch++)
-                c->quantized[sample][band][ch] = quantize_value(c->subband[sample][band][ch], c->quant[band][ch]);
+            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)
@@ -853,22 +851,22 @@ static void put_primary_audio_header(DCAEncContext *c)
 
 static void put_subframe_samples(DCAEncContext *c, int ss, int band, int ch)
 {
-    if (c->abits[band][ch] <= 7) {
+    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[band][ch]];
-                sum += c->quantized[ss * 8 + i + j][band][ch];
-                sum += (ff_dca_quant_levels[c->abits[band][ch]] - 1) / 2;
+                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[band][ch]] / 4, sum);
+            put_bits(&c->pb, bit_consumption[c->abits[ch][band]] / 4, sum);
         }
     } else {
         int i;
         for (i = 0; i < 8; i++) {
-            int bits = bit_consumption[c->abits[band][ch]] / 16;
-            put_sbits(&c->pb, bits, c->quantized[ss * 8 + i][band][ch]);
+            int bits = bit_consumption[c->abits[ch][band]] / 16;
+            put_sbits(&c->pb, bits, c->quantized[ch][band][ss * 8 + i]);
         }
     }
 }
@@ -892,7 +890,7 @@ static void put_subframe(DCAEncContext *c, int subframe)
     /* Bit allocation index */
     for (ch = 0; ch < c->fullband_channels; ch++)
         for (band = 0; band < DCAENC_SUBBANDS; band++)
-            put_bits(&c->pb, 5, c->abits[band][ch]);
+            put_bits(&c->pb, 5, c->abits[ch][band]);
 
     if (SUBSUBFRAMES > 1) {
         /* Transition mode: none for each channel and subband */
@@ -904,7 +902,7 @@ static void put_subframe(DCAEncContext *c, int subframe)
     /* Scale factors */
     for (ch = 0; ch < c->fullband_channels; ch++)
         for (band = 0; band < DCAENC_SUBBANDS; band++)
-            put_bits(&c->pb, 7, c->scale_factor[band][ch]);
+            put_bits(&c->pb, 7, c->scale_factor[ch][band]);
 
     /* Joint subband scale factor codebook select: not transmitted */
     /* Scale factors for joint subband coding: not transmitted */
-- 
2.1.4

From c8dc546852c411241e7717298d04c60d6833f185 Mon Sep 17 00:00:00 2001
From: Daniil Cherednik <dan.chered...@gmail.com>
Date: Sun, 8 Jan 2017 00:03:37 +0300
Subject: [PATCH 2/3] avcodec/dcaenc: Move some functions before
 init_quantization_noise()
To: ffmpeg-devel@ffmpeg.org

to be able to requantize values during bits distribution loop
---
 libavcodec/dcaenc.c | 102 ++++++++++++++++++++++++++--------------------------
 1 file changed, 51 insertions(+), 51 deletions(-)

diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c
index 3af2a35..e9c03ae 100644
--- a/libavcodec/dcaenc.c
+++ b/libavcodec/dcaenc.c
@@ -568,6 +568,57 @@ 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 int init_quantization_noise(DCAEncContext *c, int noise)
 {
     int ch, band, ret = 0;
@@ -655,47 +706,6 @@ 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)
 {
     int band, ch;
@@ -710,16 +720,6 @@ static void calc_scales(DCAEncContext *c)
         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 */
-- 
2.1.4

From e96c467499a26614bc7b5f79056ffb599ff616d7 Mon Sep 17 00:00:00 2001
From: Daniil Cherednik <dan.chered...@gmail.com>
Date: Sun, 8 Jan 2017 00:16:49 +0300
Subject: [PATCH 3/3] avcodec/dcaenc: Implementation of Huffman codes for DCA
 encoder
To: ffmpeg-devel@ffmpeg.org

---
 libavcodec/Makefile   |   2 +-
 libavcodec/dca_core.c |  16 ++---
 libavcodec/dcadata.c  |   8 +++
 libavcodec/dcadata.h  |   5 ++
 libavcodec/dcaenc.c   | 159 ++++++++++++++++++++++++++++++++++++++------------
 libavcodec/dcaenc.h   |   1 -
 libavcodec/dcahuff.c  |  22 +++++++
 libavcodec/dcahuff.h  |   3 +
 tests/fate/acodec.mak |   2 +-
 9 files changed, 166 insertions(+), 52 deletions(-)

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 58feb31..b81a275 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -234,7 +234,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
diff --git a/libavcodec/dca_core.c b/libavcodec/dca_core.c
index 46825ed..d5e628e 100644
--- a/libavcodec/dca_core.c
+++ b/libavcodec/dca_core.c
@@ -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
diff --git a/libavcodec/dcadata.c b/libavcodec/dcadata.c
index b2e0f6c..193247b 100644
--- a/libavcodec/dcadata.c
+++ b/libavcodec/dcadata.c
@@ -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 */
diff --git a/libavcodec/dcadata.h b/libavcodec/dcadata.h
index 17aa712..c838867 100644
--- a/libavcodec/dcadata.h
+++ b/libavcodec/dcadata.h
@@ -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];
diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c
index e9c03ae..ff7b0eb 100644
--- a/libavcodec/dcaenc.c
+++ b/libavcodec/dcaenc.c
@@ -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;
@@ -619,9 +626,58 @@ static void quantize_all(DCAEncContext *c)
                 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)
@@ -648,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;
 }
@@ -706,16 +788,8 @@ static void shift_history(DCAEncContext *c, const int32_t *input)
         }
 }
 
-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);
 }
@@ -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);
diff --git a/libavcodec/dcaenc.h b/libavcodec/dcaenc.h
index eccfb42..06816c2 100644
--- a/libavcodec/dcaenc.h
+++ b/libavcodec/dcaenc.h
@@ -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,
diff --git a/libavcodec/dcahuff.c b/libavcodec/dcahuff.c
index bea3530..9fb42a6 100644
--- a/libavcodec/dcahuff.c
+++ b/libavcodec/dcahuff.c
@@ -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]);
+    }
+}
diff --git a/libavcodec/dcahuff.h b/libavcodec/dcahuff.h
index b1d5735..c017622 100644
--- a/libavcodec/dcahuff.h
+++ b/libavcodec/dcahuff.h
@@ -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 */
diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak
index c7d4d26..5c3fea9 100644
--- a/tests/fate/acodec.mak
+++ b/tests/fate/acodec.mak
@@ -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
-- 
2.1.4

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to