MvH
Benjamin Larsson
>From 72e6371e0c98e344275173452cec98940a33ef39 Mon Sep 17 00:00:00 2001
From: Alexander E. Patrakov <[email protected]>
Date: Fri, 8 Apr 2011 01:33:21 +0200
Subject: [PATCH] Experimental DCA encoder
---
libavcodec/Makefile | 1 +
libavcodec/allcodecs.c | 2 +-
libavcodec/dcaenc.c | 581 ++++++++++++++++++++++++++++++++++++++++++++++++
libavcodec/dcaenc.h | 544 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 1127 insertions(+), 1 deletions(-)
create mode 100644 libavcodec/dcaenc.c
create mode 100644 libavcodec/dcaenc.h
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 837f7e2..195469d 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -104,6 +104,7 @@ OBJS-$(CONFIG_COOK_DECODER) += cook.o
OBJS-$(CONFIG_CSCD_DECODER) += cscd.o
OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o
OBJS-$(CONFIG_DCA_DECODER) += dca.o synth_filter.o dcadsp.o
+OBJS-$(CONFIG_DCA_ENCODER) += dcaenc.o
OBJS-$(CONFIG_DFA_DECODER) += dfa.o
OBJS-$(CONFIG_DNXHD_DECODER) += dnxhddec.o dnxhddata.o
OBJS-$(CONFIG_DNXHD_ENCODER) += dnxhdenc.o dnxhddata.o \
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 7636392..9530358 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -238,7 +238,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (BINKAUDIO_DCT, binkaudio_dct);
REGISTER_DECODER (BINKAUDIO_RDFT, binkaudio_rdft);
REGISTER_DECODER (COOK, cook);
- REGISTER_DECODER (DCA, dca);
+ REGISTER_ENCDEC (DCA, dca);
REGISTER_DECODER (DSICINAUDIO, dsicinaudio);
REGISTER_DECODER (EAC3, eac3);
REGISTER_ENCDEC (FLAC, flac);
diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c
new file mode 100644
index 0000000..0362485
--- /dev/null
+++ b/libavcodec/dcaenc.c
@@ -0,0 +1,581 @@
+/*
+ * DCA encoder
+ * Copyright (C) 2008 Alexander E. Patrakov
+ * 2010 Benjamin Larsson
+ * 2011 Xiang Wang
+ * This file is part of Libav.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/common.h"
+#include "libavutil/avassert.h"
+#include "libavutil/audioconvert.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "put_bits.h"
+#include "dcaenc.h"
+#include "dcadata.h"
+
+#undef NDEBUG
+
+#define MAX_CHANNELS 6
+#define DCA_SUBBANDS_32 32
+#define DCA_MAX_FRAME_SIZE 16383
+#define DCA_HEADER_SIZE 13
+
+#define DCA_SUBBANDS 32 ///< Subband activity count
+#define QUANTIZER_BITS 16
+#define SUBFRAMES 1
+#define SUBSUBFRAMES 4
+#define PCM_SAMPLES (SUBFRAMES*SUBSUBFRAMES*8)
+#define LFE_BITS 8
+#define LFE_INTERPOLATION 64
+#define LFE_PRESENT 2
+#define LFE_MISSING 0
+
+static const int8_t dca_lfe_index[] = {
+ 1,2,2,2,2,3,2,3,2,3,2,3,1,3,2,3
+};
+
+static const int8_t dca_channel_reorder_lfe[][9] = {
+ { 0, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 2, 0, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, 2, -1, -1, -1, -1, -1},
+ { 1, 2, 0, -1, 3, -1, -1, -1, -1},
+ { 0, 1, -1, 2, 3, -1, -1, -1, -1},
+ { 1, 2, 0, -1, 3, 4, -1, -1, -1},
+ { 2, 3, -1, 0, 1, 4, 5, -1, -1},
+ { 1, 2, 0, -1, 3, 4, 5, -1, -1},
+ { 0, -1, 4, 5, 2, 3, 1, -1, -1},
+ { 3, 4, 1, -1, 0, 2, 5, 6, -1},
+ { 2, 3, -1, 5, 7, 0, 1, 4, 6},
+ { 3, 4, 1, -1, 0, 2, 5, 7, 6},
+};
+
+static const int8_t dca_channel_reorder_nolfe[][9] = {
+ { 0, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 2, 0, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 2, -1, -1, -1, -1, -1, -1},
+ { 1, 2, 0, 3, -1, -1, -1, -1, -1},
+ { 0, 1, 2, 3, -1, -1, -1, -1, -1},
+ { 1, 2, 0, 3, 4, -1, -1, -1, -1},
+ { 2, 3, 0, 1, 4, 5, -1, -1, -1},
+ { 1, 2, 0, 3, 4, 5, -1, -1, -1},
+ { 0, 4, 5, 2, 3, 1, -1, -1, -1},
+ { 3, 4, 1, 0, 2, 5, 6, -1, -1},
+ { 2, 3, 5, 7, 0, 1, 4, 6, -1},
+ { 3, 4, 1, 0, 2, 5, 7, 6, -1},
+};
+
+typedef struct {
+ PutBitContext pb;
+ int32_t history[MAX_CHANNELS][512]; /* This is a circular buffer */
+ int start[MAX_CHANNELS];
+ int frame_size;
+ int prim_channels;
+ int lfe_channel;
+ int sample_rate_code;
+ int scale_factor[MAX_CHANNELS][DCA_SUBBANDS_32];
+ int lfe_scale_factor;
+ int lfe_data[SUBFRAMES*SUBSUBFRAMES*4];
+
+ int a_mode; ///< audio channels arrangement
+ int num_channel;
+ int lfe_state;
+ int lfe_offset;
+ const int8_t* channel_order_tab; ///< channel reordering table, lfe and non lfe
+
+ int32_t pcm[FFMAX(LFE_INTERPOLATION, DCA_SUBBANDS_32)];
+ int32_t subband[PCM_SAMPLES][MAX_CHANNELS][DCA_SUBBANDS_32]; /* [sample][channel][subband] */
+} DCAContext;
+
+static int32_t cos_table[128];
+
+static inline int32_t mul32(int32_t a, int32_t b)
+{
+ /* on >=i686, gcc compiles this into a single "imull" instruction */
+ int64_t r = (int64_t)a * b;
+ /* round the result before truncating - improves accuracy */
+ return (r + 0x80000000) >> 32;
+}
+
+/* Integer version of the cosine modulated Pseudo QMF */
+
+static void qmf_init(void)
+{
+ int i;
+ int32_t c[17], s[17];
+ s[0] = 0; /* sin(index * PI / 64) * 0x7fffffff */
+ c[0] = 0x7fffffff; /* cos(index * PI / 64) * 0x7fffffff */
+
+ for (i = 1; i <= 16; i++) {
+ s[i] = 2 * (mul32(c[i-1], 105372028) + mul32(s[i-1], 2144896908));
+ c[i] = 2 * (mul32(c[i-1], 2144896908) - mul32(s[i-1], 105372028));
+ }
+
+ for (i = 0; i < 16; i++) {
+ cos_table[i] = c[i] >> 3; /* so that the output doesn't overflow */
+ cos_table[i+16] = s[16-i] >> 3;
+ cos_table[i+32] = -s[i] >> 3;
+ cos_table[i+48] = -c[16-i] >> 3;
+ cos_table[i+64] = -c[i] >> 3;
+ cos_table[i+80] = -s[16-i] >> 3;
+ cos_table[i+96] = s[i] >> 3;
+ cos_table[i+112] = c[16-i] >> 3;
+ }
+}
+
+static int32_t band_delta_factor(int band, int sample_num)
+{
+ int index = band * (2 * sample_num + 1);
+ if (band == 0)
+ return 0x07ffffff;
+ else
+ return cos_table[index & 127];
+}
+
+static void add_new_samples(DCAContext *c, const int32_t *in, int count, int channel){
+ int i;
+
+ /* Place new samples into the history buffer */
+ for (i = 0; i < count; i++){
+ c->history[channel][c->start[channel] + i] = in[i];
+ av_assert0(c->start[channel] + i < 512);
+ }
+ c->start[channel] += count;
+ if (c->start[channel] == 512)
+ c->start[channel] = 0;
+ av_assert0(c->start[channel] < 512);
+}
+
+static void qmf_decompose(DCAContext *c, int32_t in[32], int32_t out[32], int channel)
+{
+ int band, i, j, k;
+ int32_t resp;
+ int32_t accum[DCA_SUBBANDS_32];
+
+ add_new_samples(c, in, DCA_SUBBANDS_32, channel);
+
+ /* Calculate the dot product of the signal with the (possibly inverted)
+ reference decoder's response to this vector:
+ (0.0, 0.0, ..., 0.0, -1.0, 1.0, 0.0, ..., 0.0)
+ so that -1.0 cancels 1.0 from the previous step */
+
+ memset(accum,0,sizeof(accum));
+
+ for (k = 48, j = 0, i = c->start[channel]; i < 512; k++, j++, i++)
+ accum[(k & 32) ? (31 - (k & 31)) : (k & 31)] += mul32(c->history[channel][i], UnQMF[j]);
+ for (i = 0; i < c->start[channel]; k++, j++, i++)
+ accum[(k & 32) ? (31 - (k & 31)) : (k & 31)] += mul32(c->history[channel][i], UnQMF[j]);
+
+ resp = 0;
+ /* TODO: implement FFT instead of this naive calculation */
+ for (band = 0; band < DCA_SUBBANDS_32; band++) {
+ for (j = 0; j < 32; j++)
+ resp += mul32(accum[j], band_delta_factor(band, j));
+
+ out[band] = (band & 2) ? (-resp) : resp;
+ }
+}
+
+static int32_t lfe_fir_64i[512];
+static int lfe_downsample(DCAContext *c, int32_t in[LFE_INTERPOLATION]){
+ int i, j;
+ int channel = c->prim_channels;
+ int32_t accum = 0;
+
+ add_new_samples(c, in, LFE_INTERPOLATION, channel);
+ for (i = c->start[channel], j = 0; i < 512; i++, j++)
+ accum += mul32(c->history[channel][i], lfe_fir_64i[j]);
+ for (i = 0; i < c->start[channel]; i++, j++)
+ accum += mul32(c->history[channel][i], lfe_fir_64i[j]);
+ return accum;
+}
+
+static void init_lfe_fir(void){
+ static int initialized;
+ int i;
+ if(initialized)
+ return;
+ for(i=0; i<512; i++)
+ lfe_fir_64i[i] = lfe_fir_64[i] * (1<<25); //float -> int32_t
+ initialized = 1;
+}
+
+static void put_frame_header(DCAContext *c)
+{
+ /* SYNC */
+ put_bits(&c->pb, 16, 0x7ffe);
+ put_bits(&c->pb, 16, 0x8001);
+
+ /* Frame type: normal */
+ put_bits(&c->pb, 1, 1);
+
+ /* Deficit sample count: none */
+ put_bits(&c->pb, 5, 31);
+
+ /* CRC is not present */
+ put_bits(&c->pb, 1, 0);
+
+ /* Number of PCM sample blocks */
+ put_bits(&c->pb, 7, PCM_SAMPLES-1);
+
+ /* Primary frame byte size */
+ put_bits(&c->pb, 14, c->frame_size-1);
+
+ /* Audio channel arrangement: L + R (stereo) */
+ put_bits(&c->pb, 6, c->num_channel);
+
+ /* Core audio sampling frequency */
+ put_bits(&c->pb, 4, c->sample_rate_code);
+
+ /* Transmission bit rate: 1411.2 kbps */ //FIXME
+ put_bits(&c->pb, 5, 0x16);
+
+ /* Embedded down mix: disabled */
+ put_bits(&c->pb, 1, 0);
+
+ /* Embedded dynamic range flag: not present */
+ put_bits(&c->pb, 1, 0);
+
+ /* Embedded time stamp flag: not present */
+ put_bits(&c->pb, 1, 0);
+
+ /* Auxiliary data flag: not present */
+ put_bits(&c->pb, 1, 0);
+
+ /* HDCD source: no */
+ put_bits(&c->pb, 1, 0);
+
+ /* Extension audio ID: N/A */
+ put_bits(&c->pb, 3, 0);
+
+ /* Extended audio data: not present */
+ put_bits(&c->pb, 1, 0);
+
+ /* Audio sync word insertion flag: after each sub-frame */
+ put_bits(&c->pb, 1, 0);
+
+ /* Low frequency effects flag: not present or interpolation factor=64 */
+ put_bits(&c->pb, 2, c->lfe_state);
+
+ /* Predictor history switch flag: on */
+ put_bits(&c->pb, 1, 1);
+
+ /* No CRC */
+ /* Multirate interpolator switch: non-perfect reconstruction */
+ put_bits(&c->pb, 1, 0);
+
+ /* Encoder software revision: 7 */
+ put_bits(&c->pb, 4, 7);
+
+ /* Copy history: 0 */
+ put_bits(&c->pb, 2, 0);
+
+ /* Source PCM resolution: 16 bits, not DTS ES */
+ put_bits(&c->pb, 3, 0);
+
+ /* Front sum/difference coding: no */
+ put_bits(&c->pb, 1, 0);
+
+ /* Surrounds sum/difference coding: no */
+ put_bits(&c->pb, 1, 0);
+
+ /* Dialog normalization: 0 dB */
+ put_bits(&c->pb, 4, 0);
+}
+
+static void put_primary_audio_header(DCAContext *c)
+{
+ /* From dca.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);
+
+ /* Number of primary audio channels */
+ put_bits(&c->pb, 3, c->prim_channels-1);
+
+ /* Subband activity count */
+ for (ch=0; ch<c->prim_channels; ch++) {
+ put_bits(&c->pb, 5, DCA_SUBBANDS-2);
+ }
+
+ /* High frequency VQ start subband */
+ for (ch=0; ch<c->prim_channels; ch++) {
+ put_bits(&c->pb, 5, DCA_SUBBANDS-1);
+ }
+
+ /* Joint intensity coding index: 0, 0 */
+ for (ch=0; ch<c->prim_channels; ch++) {
+ put_bits(&c->pb, 3, 0);
+ }
+
+ /* Transient mode codebook: A4, A4 (arbitrary) */
+ for (ch=0; ch<c->prim_channels; ch++) {
+ put_bits(&c->pb, 2, 0);
+ }
+
+ /* Scale factor code book: 7 bit linear, 7-bit sqrt table (for each channel) */
+ for (ch=0; ch<c->prim_channels; ch++) {
+ put_bits(&c->pb, 3, 6);
+ }
+
+ /* Bit allocation quantizer select: linear 5-bit */
+ for (ch=0; ch<c->prim_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++) {
+ for (ch=0; ch<c->prim_channels; ch++) {
+ put_bits(&c->pb, bitlen[i], thr[i]);
+ }
+ }
+
+ /* Scale factor adjustment index: not transmitted */
+}
+
+/**
+ * 8-23 bits quantization
+ * @param sample
+ * @param bits
+ */
+static inline uint32_t quantize(int32_t sample, int bits)
+{
+ av_assert0(sample < 1<<(bits-1));
+ av_assert0(sample >= -(1<<(bits-1)));
+ sample &= sample & ((1<<bits)-1);
+ return sample;
+}
+
+static inline int find_scale_factor7(int64_t max_value, int bits){
+ int i=0, j=128, q;
+ max_value = ((max_value << 15) / lossy_quant[bits+3]) >> (bits-1);
+ while(i<j){
+ q=(i+j)>>1;
+ if(max_value < scale_factor_quant7[q]) j=q;
+ else i=q+1;
+ }
+ av_assert1(i<128);
+ return i;
+}
+
+static inline void put_sample7(DCAContext *c, int64_t sample, int bits, int scale_factor){
+ sample = (sample << 15) / ((int64_t) lossy_quant[bits+3] * scale_factor_quant7[scale_factor]);
+ put_bits(&c->pb, bits, quantize((int)sample, bits));
+}
+
+static void put_subframe(DCAContext *c, int32_t subband_data[8*SUBSUBFRAMES][MAX_CHANNELS][32], int subframe)
+{
+ int i, sub, ss, ch, max_value;
+ int32_t *lfe_data = c->lfe_data + 4*SUBSUBFRAMES*subframe;
+
+ /* Subsubframes count */
+ put_bits(&c->pb, 2, SUBSUBFRAMES -1);
+
+ /* Partial subsubframe sample count: dummy */
+ put_bits(&c->pb, 3, 0);
+
+ /* Prediction mode: no ADPCM, in each channel and subband */
+ for (ch = 0; ch < c->prim_channels; ch++)
+ for (sub = 0; sub < DCA_SUBBANDS; sub++)
+ put_bits(&c->pb, 1, 0);
+
+ /* Prediction VQ addres: not transmitted */
+ /* Bit allocation index */
+ for (ch = 0; ch < c->prim_channels; ch++)
+ for (sub = 0; sub < DCA_SUBBANDS; sub++)
+ put_bits(&c->pb, 5, QUANTIZER_BITS+3);
+
+ if(SUBSUBFRAMES>1){
+ /* Transition mode: none for each channel and subband */
+ for (ch = 0; ch < c->prim_channels; ch++)
+ for (sub = 0; sub < DCA_SUBBANDS; sub++)
+ put_bits(&c->pb, 1, 0); /* according to Huffman codebook A4 */
+ }
+
+ /* Determine scale_factor */
+ for (ch=0; ch<c->prim_channels; ch++)
+ for (sub=0; sub<DCA_SUBBANDS; sub++) {
+ max_value = 0;
+ for (i=0; i<8*SUBSUBFRAMES; i++)
+ max_value = FFMAX(max_value, FFABS(subband_data[i][ch][sub]));
+ c->scale_factor[ch][sub] = find_scale_factor7(max_value, QUANTIZER_BITS);
+ }
+
+ if (c->lfe_channel) {
+ max_value = 0;
+ for(i=0; i<4*SUBSUBFRAMES; i++)
+ max_value = FFMAX(max_value, FFABS(lfe_data[i]));
+ c->lfe_scale_factor = find_scale_factor7(max_value, LFE_BITS);
+ }
+
+ /* Scale factors: the same for each channel and subband,
+ encoded according to Table D.1.2 */
+ for (ch = 0; ch < c->prim_channels; ch++)
+ for (sub = 0; sub < DCA_SUBBANDS; sub++)
+ put_bits(&c->pb, 7, c->scale_factor[ch][sub]);
+
+ /* Joint subband scale factor codebook select: not transmitted */
+ /* Scale factors for joint subband coding: not transmitted */
+ /* Stereo down-mix coefficients: not transmitted */
+ /* Dynamic range coefficient: not transmitted */
+ /* Stde information CRC check word: not transmitted */
+ /* VQ encoded high frequency subbands: not transmitted */
+
+ /* LFE data */
+ if(c->lfe_channel){
+ for(i=0; i<4*SUBSUBFRAMES; i++)
+ put_sample7(c, lfe_data[i], LFE_BITS, c->lfe_scale_factor);
+
+ put_bits(&c->pb, 8, c->lfe_scale_factor);
+ }
+
+ /* Audio data (subsubframes) */
+
+ for (ss = 0; ss < SUBSUBFRAMES ; ss++)
+ for (ch = 0; ch < c->prim_channels; ch++)
+ for (sub = 0; sub < DCA_SUBBANDS; sub++)
+ for (i = 0; i < 8; i++)
+ put_sample7(c, subband_data[ss*8+i][ch][sub], QUANTIZER_BITS, c->scale_factor[ch][sub]);
+
+ /* DSYNC */
+ put_bits(&c->pb, 16, 0xffff);
+}
+
+static void put_frame(DCAContext *c, int32_t subband_data[PCM_SAMPLES][MAX_CHANNELS][32], uint8_t *frame)
+{
+ int i;
+ init_put_bits(&c->pb, frame + DCA_HEADER_SIZE, DCA_MAX_FRAME_SIZE-DCA_HEADER_SIZE);
+
+ put_primary_audio_header(c);
+ for(i=0; i<SUBFRAMES; i++)
+ put_subframe(c, &subband_data[SUBSUBFRAMES * 8 * i], i);
+
+ flush_put_bits(&c->pb);
+ c->frame_size = (put_bits_count(&c->pb)>>3) + DCA_HEADER_SIZE;
+
+ init_put_bits(&c->pb, frame, DCA_HEADER_SIZE);
+ put_frame_header(c);
+ flush_put_bits(&c->pb);
+}
+
+static int DCA_encode_frame(AVCodecContext *avctx,
+ uint8_t *frame, int buf_size, void *data)
+{
+ int i,k,channel;
+ DCAContext *c = avctx->priv_data;
+ int16_t *samples = data;
+ int real_channel=0;
+
+ for (i = 0; i < PCM_SAMPLES; i ++) { /* i is the decimated sample number */
+ for (channel=0; channel<c->prim_channels+1; channel++) {
+ /* Get 32 PCM samples */
+ for (k = 0; k < 32; k++) { /* k is the sample number in a 32-sample block */
+ c->pcm[k] = samples[avctx->channels * (32*i+k) + channel] << 16;
+ }
+ /* Put subband samples into the proper place */
+ real_channel = c->channel_order_tab[channel];
+ if (real_channel>=0) {
+ qmf_decompose(c, c->pcm, &c->subband[i][real_channel][0], real_channel);
+ }
+ }
+ }
+
+ if (c->lfe_channel) {
+ for (i = 0; i < PCM_SAMPLES/2; i++) {
+ for (k = 0; k < LFE_INTERPOLATION; k++) { /* k is the sample number in a 32-sample block */
+ c->pcm[k] = samples[avctx->channels * (LFE_INTERPOLATION*i+k) + c->lfe_offset] << 16;
+ }
+ c->lfe_data[i] = lfe_downsample(c, c->pcm);
+ }
+ }
+
+ put_frame(c, c->subband, frame);
+
+ return c->frame_size;
+}
+
+static int DCA_encode_init(AVCodecContext *avctx) {
+ DCAContext *c = avctx->priv_data;
+ int i;
+
+ c->prim_channels = avctx->channels;
+ c->lfe_channel = (avctx->channels==3 || avctx->channels==6);
+
+ switch(avctx->channel_layout) {
+ case AV_CH_LAYOUT_STEREO: c->a_mode = 2; c->num_channel = 2; break;
+ case AV_CH_LAYOUT_5POINT0: c->a_mode = 9; c->num_channel = 9; break;
+ case AV_CH_LAYOUT_5POINT1: c->a_mode = 9; c->num_channel = 9; break;
+ case AV_CH_LAYOUT_5POINT0_BACK: c->a_mode = 9; c->num_channel = 9; break;
+ case AV_CH_LAYOUT_5POINT1_BACK: c->a_mode = 9; c->num_channel = 9; break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Only stereo, 5.1, 5.0, 5.0back and 5.0front channel layouts supported at the moment!\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if (c->lfe_channel) {
+ init_lfe_fir();
+ c->prim_channels--;
+ c->channel_order_tab = dca_channel_reorder_lfe[c->a_mode];
+ c->lfe_state = LFE_PRESENT;
+ c->lfe_offset = dca_lfe_index[c->a_mode];
+ } else {
+ c->channel_order_tab = dca_channel_reorder_nolfe[c->a_mode];
+ c->lfe_state = LFE_MISSING;
+ }
+
+ for(i=0; i<16; i++){
+ if(dca_sample_rates[i] == avctx->sample_rate)
+ break;
+ }
+ if(i==16){
+ av_log(avctx, AV_LOG_ERROR, "Sample rate %iHz not supported\n", avctx->sample_rate);
+ return -1;
+ }
+ c->sample_rate_code = i;
+
+ avctx->frame_size = 32 * PCM_SAMPLES;
+
+ qmf_init();
+ return 0;
+}
+
+AVCodec ff_dca_encoder = {
+ .name = "dca",
+ .type = CODEC_TYPE_AUDIO,
+ .id = CODEC_ID_DTS,
+ .priv_data_size = sizeof(DCAContext),
+ .init = DCA_encode_init,
+ .encode = DCA_encode_frame,
+ .capabilities = CODEC_CAP_EXPERIMENTAL,
+ .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
+ NULL,
+ NULL,
+};
diff --git a/libavcodec/dcaenc.h b/libavcodec/dcaenc.h
new file mode 100644
index 0000000..bd5f4d6
--- /dev/null
+++ b/libavcodec/dcaenc.h
@@ -0,0 +1,544 @@
+/*
+ * DCA encoder tables
+ * Copyright (C) 2008 Alexander E. Patrakov
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_DCAENC_H
+#define AVCODEC_DCAENC_H
+
+/* This is a scaled version of the response of the reference decoder to
+ this vector of subband samples: ( 1.0 0.0 0.0 ... 0.0 )
+ */
+
+static const int32_t UnQMF[512] = {
+7,
+4,
+-961,
+-2844,
+-8024,
+-18978,
+-32081,
+-15635,
+-16582,
+-18359,
+-17180,
+-14868,
+-11664,
+-8051,
+-4477,
+-1327,
+-1670,
+-6019,
+-11590,
+-18030,
+-24762,
+-30965,
+-35947,
+-36145,
+-37223,
+-86311,
+-57024,
+-27215,
+-11274,
+-4684,
+42,
+108,
+188,
+250,
+-1007,
+-596,
+-2289,
+-12218,
+-27191,
+-124367,
+-184256,
+-250538,
+-323499,
+-397784,
+-468855,
+-532072,
+-583000,
+-618041,
+-777916,
+-783868,
+-765968,
+-724740,
+-662468,
+-583058,
+-490548,
+-401623,
+-296090,
+-73154,
+-36711,
+-7766,
+-2363,
+-4905,
+2388,
+2681,
+5651,
+4086,
+71110,
+139742,
+188067,
+151237,
+101355,
+309917,
+343690,
+358839,
+357555,
+334606,
+289625,
+224152,
+142063,
+48725,
+74996,
+238425,
+411666,
+584160,
+744276,
+880730,
+983272,
+1041933,
+1054396,
+789531,
+851022,
+864032,
+675431,
+418134,
+35762,
+66911,
+103502,
+136403,
+-55147,
+-245269,
+-499595,
+-808470,
+-1136858,
+-2010912,
+-2581654,
+-3151901,
+-3696328,
+-4196599,
+-4633761,
+-4993229,
+-5262495,
+-5436311,
+-477650,
+-901314,
+-1308090,
+-1677468,
+-1985525,
+-2212848,
+-2341196,
+-2373915,
+-2269552,
+-2620489,
+-2173858,
+-1629954,
+-946595,
+-193499,
+1119459,
+1138657,
+1335311,
+1126544,
+2765033,
+3139603,
+3414913,
+3599213,
+3676363,
+3448981,
+3328726,
+3111551,
+2810887,
+2428657,
+1973684,
+1457278,
+893848,
+300995,
+-292521,
+-867621,
+-1404936,
+-1871278,
+-2229831,
+-2440932,
+-2462684,
+-2255006,
+-1768898,
+-1079574,
+82115,
+1660302,
+3660715,
+6123610,
+8329598,
+11888744,
+15722147,
+19737089,
+25647773,
+31039399,
+36868007,
+43124253,
+49737161,
+56495958,
+63668945,
+71039511,
+78540240,
+86089058,
+93600041,
+100981151,
+108136061,
+114970055,
+121718321,
+127566038,
+132774642,
+137247294,
+140894737,
+143635018,
+145395599,
+146114032,
+145742999,
+144211606,
+141594341,
+137808404,
+132914122,
+126912246,
+120243281,
+112155281,
+103338368,
+93904953,
+83439152,
+72921548,
+62192990,
+51434918,
+40894003,
+30786726,
+21384955,
+12939112,
+5718193,
+-5790,
+-3959261,
+-5870978,
+-5475538,
+-2517061,
+3247310,
+12042937,
+24076729,
+39531397,
+58562863,
+81297002,
+107826748,
+138209187,
+172464115,
+210569037,
+252468018,
+298045453,
+347168648,
+399634888,
+455137189,
+513586535,
+574537650,
+637645129,
+702597163,
+768856566,
+836022040,
+903618096,
+971159680,
+1038137214,
+1103987353,
+1168195035,
+1230223053,
+1289539180,
+1345620373,
+1397957958,
+1446063657,
+1489474689,
+1527740502,
+1560502307,
+1587383079,
+1608071145,
+1622301248,
+1629859340,
+1630584888,
+1624373875,
+1611178348,
+1591018893,
+1563948667,
+1530105004,
+1489673227,
+1442904075,
+1390107674,
+1331590427,
+1267779478,
+1199115126,
+1126053392,
+1049146257,
+968928307,
+885965976,
+800851610,
+714186243,
+626590147,
+538672486,
+451042824,
+364299927,
+279026812,
+195785029,
+115109565,
+37503924,
+-36564551,
+-106668063,
+-172421668,
+-233487283,
+-289575706,
+-340448569,
+-385919511,
+-425854915,
+-460174578,
+-488840702,
+-511893328,
+-529405118,
+-541489888,
+-548312207,
+-550036471,
+-547005316,
+-539436808,
+-527630488,
+-512084785,
+-492941605,
+-470665204,
+-445668379,
+-418328829,
+-389072810,
+-358293846,
+-326396227,
+-293769619,
+-260792276,
+-227825056,
+-195208961,
+-163262121,
+-132280748,
+-102533727,
+-74230062,
+-47600637,
+-22817785,
+-25786,
+20662895,
+39167253,
+55438413,
+69453741,
+81242430,
+90795329,
+98213465,
+103540643,
+106917392,
+108861938,
+108539682,
+106780704,
+103722568,
+99043289,
+93608686,
+87266209,
+80212203,
+72590022,
+64603428,
+56362402,
+48032218,
+39749162,
+31638971,
+23814664,
+16376190,
+9409836,
+2988017,
+-2822356,
+-7976595,
+-12454837,
+-16241147,
+-19331944,
+-21735011,
+-23468284,
+-24559822,
+-25042936,
+-25035583,
+-24429587,
+-23346408,
+-21860411,
+-20015718,
+-17025330,
+-14968728,
+-12487138,
+-9656319,
+-7846681,
+-5197816,
+-2621904,
+-144953,
+2144746,
+3990570,
+5845884,
+7454650,
+8820394,
+9929891,
+10784445,
+11390921,
+11762056,
+11916017,
+12261189,
+12117604,
+11815303,
+11374622,
+10815301,
+10157241,
+9418799,
+8629399,
+7780776,
+7303680,
+6353499,
+5392738,
+4457895,
+3543062,
+1305978,
+1402521,
+1084092,
+965652,
+-151008,
+-666667,
+-1032157,
+-1231475,
+-1319043,
+-1006023,
+-915720,
+-773426,
+-612377,
+-445864,
+-291068,
+-161337,
+-66484,
+-11725,
+133453,
+388184,
+615856,
+804033,
+942377,
+1022911,
+1041247,
+995854,
+891376,
+572246,
+457992,
+316365,
+172738,
+43037,
+-117662,
+-98542,
+-70279,
+-41458,
+-535790,
+-959038,
+-1364456,
+-1502265,
+-1568530,
+-2378681,
+-2701111,
+-2976407,
+-3182552,
+-3314415,
+-3366600,
+-3337701,
+-3232252,
+-3054999,
+1984841,
+1925903,
+1817377,
+1669153,
+1490069,
+1292040,
+1086223,
+890983,
+699163,
+201358,
+266971,
+296990,
+198419,
+91119,
+4737,
+5936,
+2553,
+2060,
+-3828,
+-1664,
+-4917,
+-20796,
+-36822,
+-131247,
+-154923,
+-162055,
+-161354,
+-148762,
+-125754,
+-94473,
+-57821,
+-19096,
+15172,
+43004,
+65624,
+81354,
+89325,
+89524,
+82766,
+71075,
+55128,
+13686,
+6921,
+1449,
+420,
+785,
+-215,
+-179,
+-113,
+-49,
+6002,
+16007,
+42978,
+100662,
+171472,
+83975,
+93702,
+108813,
+111893,
+110272,
+103914,
+93973,
+81606,
+68041,
+-54058,
+-60695,
+-65277,
+-67224,
+-66213,
+-62082,
+-55574,
+-42988,
+-35272,
+-63735,
+-33501,
+-12671,
+-4038,
+-1232,
+5,
+7
+};
+
+#endif /* AVCODEC_DCAENC_H */
--
1.7.0.4
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel