MvH
Benjamin Larsson
>From 72e6371e0c98e344275173452cec98940a33ef39 Mon Sep 17 00:00:00 2001
From: Alexander E. Patrakov <patra...@gmail.com>
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
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to