From patchwork Sat Jan 7 22:22:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?0JTQsNC90LjQuNC7INCn0LXRgNC10LTQvdC40Lo=?= X-Patchwork-Id: 2094 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.89.21 with SMTP id n21csp6446935vsb; Sat, 7 Jan 2017 14:22:49 -0800 (PST) X-Received: by 10.28.93.74 with SMTP id r71mr1697317wmb.67.1483827769099; Sat, 07 Jan 2017 14:22:49 -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 jv4si92796624wjb.64.2017.01.07.14.22.48; Sat, 07 Jan 2017 14:22:49 -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 E2A3B68A554; Sun, 8 Jan 2017 00:22:38 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-io0-f176.google.com (mail-io0-f176.google.com [209.85.223.176]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id F20EC68A548 for ; Sun, 8 Jan 2017 00:22:31 +0200 (EET) Received: by mail-io0-f176.google.com with SMTP id f103so59175852ioi.1 for ; Sat, 07 Jan 2017 14:22:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=FMzwsFH1rOSsAw9AUHt5m9xYxSQbl6ZVqdf0Xi+aRjA=; b=TyVdpjaOx2UaUDQay7ON+kcJaNzcGwVCf2J/kq2lXBBAy0IhMSQqoHJWddfhmGZUNF eJFVCOJQOGHvQigzxqMij0FRrQmCHkUhflrVfgBb7mxEL/0vjMW/xMUAXbKPa6iVEM98 MIw2BDypj6vnOK7C+ZeVZxLcb8doY1oMEI6YeP7dEoORmqr6SuVFiNCNYm2GSqafdLee 69+5LtcZNmyIsku/l0ZGqYqgaIwyldHQGi/pHLp6balhdWOiWuowv8xtcRCGbxMNNzrl x1o3Fa7IKd73BvbNaKKiKwh5vjBggWbVgsI+N+Gz/ph3/H96QR2QPhS7UmiqT2Sgxfip s//w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=FMzwsFH1rOSsAw9AUHt5m9xYxSQbl6ZVqdf0Xi+aRjA=; b=qOkefwgl/ZcZGkoQqxIi1cu3xhJi1y97Cp8E6xWwTI4abKlC8g1s041daDfdsZ8BMT 5qIq2pA3erWJKAdjK6aFV3IZVBuSzym7Qp4gp5XkdhTHobfn4ou6fswq6sqxtY4AtEEc wbCOP+/otdjyZzM7OvMKQFV+Fo9YWMqrAzyfnXklcFFwZ1pH9s1JjiUX7VU09Ug58ezF VUBRt701H4i6BWcaBFrUdhG4akj4sq1XpTLt8jp2Kf60ILGGQMS7qO5Mh90NLUcABCps +l2Cxo0ruPNCp+X/RJTxFrqLSj5YysjswMUmMxTt0bg3UiWeopZh5oYPA5aUWxmVVSYp aezA== X-Gm-Message-State: AIkVDXIrR0xHsFjk5OaoCuHyDmlZMNLg9k3+cNowa4zjhzqxlNyhmeJGqPH7fF67CBjRQdRDl7OYvHKr+kNwoA== X-Received: by 10.107.172.134 with SMTP id v128mr76351262ioe.49.1483827756708; Sat, 07 Jan 2017 14:22:36 -0800 (PST) MIME-Version: 1.0 Received: by 10.107.14.132 with HTTP; Sat, 7 Jan 2017 14:22:35 -0800 (PST) In-Reply-To: References: From: =?UTF-8?B?0JTQsNC90LjQuNC7INCn0LXRgNC10LTQvdC40Lo=?= Date: Sun, 8 Jan 2017 01:22:35 +0300 Message-ID: To: FFmpeg development discussions and patches X-Content-Filtered-By: Mailman/MimeDel 2.1.20 Subject: Re: [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" 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 wrote: > 2017-01-07 20:39 GMT+01:00 Rostislav Pehlivanov : > > On 7 January 2017 at 16:11, Carl Eugen Hoyos wrote: > > > >> 2017-01-07 16:00 GMT+01:00 Даниил Чередник : > >> > >> > 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 > From e96c467499a26614bc7b5f79056ffb599ff616d7 Mon Sep 17 00:00:00 2001 From: Daniil Cherednik 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 +#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