From patchwork Sat Jan 7 15:00:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?0JTQsNC90LjQuNC7INCn0LXRgNC10LTQvdC40Lo=?= X-Patchwork-Id: 2093 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.89.21 with SMTP id n21csp6317978vsb; Sat, 7 Jan 2017 07:09:16 -0800 (PST) X-Received: by 10.194.57.180 with SMTP id j20mr62048946wjq.165.1483801756153; Sat, 07 Jan 2017 07:09:16 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id k129si5449193wmb.68.2017.01.07.07.09.15; Sat, 07 Jan 2017 07:09:16 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6849E68A49E; Sat, 7 Jan 2017 17:09:06 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-io0-f169.google.com (mail-io0-f169.google.com [209.85.223.169]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C9C7B68A221 for ; Sat, 7 Jan 2017 17:08:59 +0200 (EET) Received: by mail-io0-f169.google.com with SMTP id j18so6162928ioe.2 for ; Sat, 07 Jan 2017 07:09:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=43rByu++f8OOsipMMiVGYXoSFhQBV8IN4dmv5GTS+M0=; b=DnuzgAo3BfJl1O9n3Utj5p1i6paQ4hvOH/G6jUJ3U2hiWIeCjNULn6qHIt9BSUThne T8Fu1ayRA85xCPdzlyHe3pNG1x6Snu0NBY29ftD7Lb2RlCRlARnMgsMfLGalUh231ndA X/wfy9ANNzuqqvgvYTI/R/qxTYbbst1jXuZo0zOXL5zc3HEOTtC0+ardgfm5MGJBucNj i2nM+U/iDQgJE0ImWoVXCnSqaetEoo/qsjHdROin0VD4fcg4S0LCMeA7ULsNk+OMczLo H+1iglla52vDE+uPmHndi6G2kxtbWiQU+kdJckLcCSBEIbV1tkgnib7fx7qwvr+AXQCW kP0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=43rByu++f8OOsipMMiVGYXoSFhQBV8IN4dmv5GTS+M0=; b=WBICKOpEOvVLPN7Bc1LoUlm8t39tQSAuBKgJrD/0bwMBw6E+5Q3XSUKkn2Tl0CGhf3 9eqm7X3n/EtqH/hZaM9EhqzlekhLdayHNM6xOA6XfHsNL82BQqtCV04wEqTAVhXHKEYd 3NJmwM31PoJfib6fxyCaS+C9HpzYaOnaLB2aNbTaaGfuOjgp+lEWkLZ0x3ARJyOoT3n7 JxERpsdsBcx8xJKP6rgukxca9ab0OUeyu5QU5GuydS0p6DWsYVR7KLiocpUHxsy8keli VIxJLONg387k8BFuK/eaTDdAa3Da0o9XqayD3LLoZOuzteM9nRj+D7g7zvguL+n04lnp 2o0w== X-Gm-Message-State: AIkVDXLmbX78IHg/feEGZX4YgfluQZRYng96WT0Bxpx3C97PVHX48iuOgn8CSKPnRBuKr4tyUaerSiPrmBVtXw== X-Received: by 10.107.149.18 with SMTP id x18mr9686897iod.167.1483801251209; Sat, 07 Jan 2017 07:00:51 -0800 (PST) MIME-Version: 1.0 Received: by 10.107.14.132 with HTTP; Sat, 7 Jan 2017 07:00:50 -0800 (PST) From: =?UTF-8?B?0JTQsNC90LjQuNC7INCn0LXRgNC10LTQvdC40Lo=?= Date: Sat, 7 Jan 2017 18:00:50 +0300 Message-ID: To: FFmpeg development discussions and patches X-Content-Filtered-By: Mailman/MimeDel 2.1.20 Subject: [FFmpeg-devel] Implementation of Huffman codes for DCA encoder X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Hi!. Currently I am working on improvement quality of DTS encoder. Following patches introduce Huffman coding. First one - reverse data layout [SUBBAND_SAMPLES][DCAENC_SUBBANDS][MAX_CHANNELS] to [MAX_CHANNELS][DCAENC_SUBBANDS][SUBBAND_SAMPLES]. I need it to write more readable code, and reduce (a bit) speed penalty. Second one - Huffman coding for quantized audio data. Results: https://yadi.sk/d/rVtRuFZv37ZqYk - without huffman https://yadi.sk/d/grTuitcu37ZqSS - with huffman Speed degradation in my case approximately 20%. From 5acd40bc9e34f07e91aa7d7f5df9d414e8faa3ec Mon Sep 17 00:00:00 2001 From: Daniil Cherednik Date: Sat, 7 Jan 2017 15:18:32 +0300 Subject: [PATCH 2/2] 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 | 261 +++++++++++++++++++++++++++++++++----------------- libavcodec/dcaenc.h | 1 - libavcodec/dcahuff.c | 22 +++++ libavcodec/dcahuff.h | 3 + tests/fate/acodec.mak | 2 +- 9 files changed, 217 insertions(+), 103 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 +#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 3af2a35..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; @@ -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); 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