[FFmpeg-devel] [ffmpeg-patch] DCA Encoder
Stefano Sabatini
stefano.sabatini-lala at poste.it
Mon Mar 21 19:20:03 CET 2011
On date Monday 2011-03-21 19:36:15 +0800, xiang wang encoded:
> Hi
>
> First patch is DCA Encoder,
>
> the second added 5.1 supports and code revision to DCA Enc. Thanks:)
> From 5370628e1b70f2d7c5525d8e8ef7de19770946f0 Mon Sep 17 00:00:00 2001
> From: Xiang <xiangwang.job at gmail.com>
> Date: Mon, 21 Mar 2011 19:14:42 +0800
> Subject: [PATCH 1/2] DCA Encoder
>
> ---
> libavcodec/Makefile | 1 +
> libavcodec/allcodecs.c | 1 +
> libavcodec/dcaenc.c | 569 ++++++++++++++++++++++++++++++++++++++++++++++++
> libavcodec/dcaenc.h | 569 ++++++++++++++++++++++++++++++++++++++++++++++++
Equals?
> 4 files changed, 1140 insertions(+), 0 deletions(-)
> create mode 100644 libavcodec/dcaenc.c
> create mode 100644 libavcodec/dcaenc.h
>
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index 04e35a1..a56f721 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -103,6 +103,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_DNXHD_DECODER) += dnxhddec.o dnxhddata.o
> OBJS-$(CONFIG_DNXHD_ENCODER) += dnxhdenc.o dnxhddata.o \
> mpegvideo_enc.o motion_est.o \
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index 8de6ad8..b2fac11 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -237,6 +237,7 @@ void avcodec_register_all(void)
> 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..1a6398a
> --- /dev/null
> +++ b/libavcodec/dcaenc.c
> @@ -0,0 +1,569 @@
> +/*
> + * DCA encoder
> + * Copyright (C) 2008 Alexander E. Patrakov
> + * FFmpeg port by Benjamin Larsson
> + * Add 5.1 support Xiang Wang
> + * 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
> + */
> +
> +#include "avcodec.h"
> +#include "put_bits.h"
> +#include "dcaenc.h"
> +#include "dcadata.h"
> +
> +#undef NDEBUG
> +#include <assert.h>
> +
> +#define MAX_CHANNELS (6)
> +#define DCA_SUBBANDS_32 (32)
> +#define DCA_MAX_FRAME_SIZE (16383)
Nit++: "()" are not required in this case
> +#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
> +
> +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];
> +
> + 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++){
Nit: please follow K&R style, here and below
void foo(...)
{
if (...) {
switch (c) {
...
}
} else {
...
}
for (i = 0; i < n; i++) {
...
}
...
}
> + c->history[channel][c->start[channel] + i] = in[i];
> + assert(c->start[channel] + i < 512);
> + }
> + c->start[channel] += count;
> + if (c->start[channel] == 512)
> + c->start[channel] = 0;
> + assert(c->start[channel] < 512);
av_assert
> +}
> +
> +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->prim_channels==2?2:9); //FIXME
> +
> + /* 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_channel?2:0);
> +
> + /* 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)
> +{
> + assert(sample < 1<<(bits-1));
> + assert(sample >= -(1<<(bits-1)));
av_assert
[...]
> +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;
> +
> +// if (buf_size < MAX_CHANNELS*2048*sizeof(int16_t))
> +// return -1;
Is the check necessary? If it is, please uncomment, otherwise remove
the comment.
> +
> + if(c->prim_channels==2)
> + {
> + for (i = 0; i < PCM_SAMPLES; i ++) /* i is the decimated sample number */
> + {
> + for (channel=0; channel<c->prim_channels; channel++)
> + {
Nit+: if_(...) {
for_(...) {
...
here and below.
> + /* 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 */
> + qmf_decompose(c, c->pcm, &c->subband[i][channel][0], 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->prim_channels-1] << 16;
> + }
> + c->lfe_data[i] = lfe_downsample(c, c->pcm);
> + }
> + }
> + else /***5.1 support, the wav order is not as the dts***/
> + {
> + 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;
> + }
> +
> + int real_channel;
> + if(channel==0)
> + {
> + real_channel = channel + 1;
> + qmf_decompose(c, c->pcm, &c->subband[i][real_channel][0], real_channel);
> + }
> + else if(channel==1)
> + {
> + real_channel = channel + 1;
> + qmf_decompose(c, c->pcm, &c->subband[i][real_channel][0], real_channel);
> + }
equals?
> + else if(channel==2)
> + {
> + real_channel = channel - 2;
> + qmf_decompose(c, c->pcm, &c->subband[i][real_channel][0], real_channel);
> + }
> + else if(channel>3)
> + {
> + real_channel = channel - 1;
> + /* Put subband samples into the proper place */
> + qmf_decompose(c, c->pcm, &c->subband[i][real_channel][0],real_channel);
> + }
Maybe
qmf_decompose(c, c->pcm, &c->subband[i][real_channel][0],real_channel);
can be factorized.
> + }
> + }
> +
> + 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) + 3] << 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);
> +
> + if(c->lfe_channel){
> + init_lfe_fir();
> + c->prim_channels--;
> + }
> +
> + if(c->prim_channels != 2 && c->prim_channels != 5) {
> + av_log(avctx, AV_LOG_ERROR, "Only stereo and 5.1 supported at the moment!\n");
> + return -1;
return AVERROR_PATCHWELCOME
[...]
> +AVCodec dca_encoder = {
> + "dca",
> + CODEC_TYPE_AUDIO,
AVMEDIA_TYPE_AUDIO
> + CODEC_ID_DCA,
> + sizeof(DCAContext),
> + DCA_encode_init,
> + DCA_encode_frame,
> + NULL,
> + NULL,
Nit: please use designated inits (.name = "dca", .codec_type = ...).
More readable and more robust.
> +};
> diff --git a/libavcodec/dcaenc.h b/libavcodec/dcaenc.h
Looks the same as dcaenc.c.
[...]
> From ac0422746c089762239afd262da588e65f6ac897 Mon Sep 17 00:00:00 2001
> From: Xiang <wangxiang68 at gmail.com>
> Date: Mon, 21 Mar 2011 19:17:26 +0800
> Subject: [PATCH 2/2] DCA Encoder Add 5.1 Support By Xiang Wang
>
> ---
> libavcodec/dcaenc.c | 205 ++++++++++++++++++++++++++++++---------------------
> 1 files changed, 121 insertions(+), 84 deletions(-)
>
> diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c
> index 1a6398a..554f81d 100644
> --- a/libavcodec/dcaenc.c
> +++ b/libavcodec/dcaenc.c
> @@ -2,7 +2,7 @@
> * DCA encoder
> * Copyright (C) 2008 Alexander E. Patrakov
> * FFmpeg port by Benjamin Larsson
> - * Add 5.1 support Xiang Wang
> + * Add 5.1 multichannel support by Xiang Wang
> * This file is part of FFmpeg.
> *
> * FFmpeg is free software; you can redistribute it and/or
> @@ -20,7 +20,9 @@
> * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> */
>
> +#include "../libavutil/common.h"
#include "libavutil/common.h"
> #include "avcodec.h"
> +#include "get_bits.h"
> #include "put_bits.h"
> #include "dcaenc.h"
> #include "dcadata.h"
> @@ -40,6 +42,52 @@
> #define PCM_SAMPLES (SUBFRAMES*SUBSUBFRAMES*8)
> #define LFE_BITS 8
> #define LFE_INTERPOLATION 64
> +#define LFE_PRESENT 2
> +#define LFE_MISSING 0
> +
> +
> +
Nit++: one empty line is enough.
[...]
> @@ -441,84 +494,37 @@ static int DCA_encode_frame(AVCodecContext *avctx,
> int i,k,channel;
> DCAContext *c = avctx->priv_data;
> int16_t *samples = data;
> -
> -// if (buf_size < MAX_CHANNELS*2048*sizeof(int16_t))
> -// return -1;
> -
> - if(c->prim_channels==2)
> +
> + for (i = 0; i < PCM_SAMPLES; i ++) /* i is the decimated sample number */
> {
> - for (i = 0; i < PCM_SAMPLES; i ++) /* i is the decimated sample number */
> + for (channel=0; channel<c->prim_channels+1; channel++)
> {
> - for (channel=0; channel<c->prim_channels; 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 */
> - qmf_decompose(c, c->pcm, &c->subband[i][channel][0], 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->prim_channels-1] << 16;
> - }
> - c->lfe_data[i] = lfe_downsample(c, c->pcm);
> - }
> - }
> - else /***5.1 support, the wav order is not as the dts***/
> - {
> - 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;
> - }
> -
> - int real_channel;
> - if(channel==0)
> - {
> - real_channel = channel + 1;
> - qmf_decompose(c, c->pcm, &c->subband[i][real_channel][0], real_channel);
> - }
> - else if(channel==1)
> - {
> - real_channel = channel + 1;
> - qmf_decompose(c, c->pcm, &c->subband[i][real_channel][0], real_channel);
> - }
> - else if(channel==2)
> - {
> - real_channel = channel - 2;
> - qmf_decompose(c, c->pcm, &c->subband[i][real_channel][0], real_channel);
> - }
> - else if(channel>3)
> - {
> - real_channel = channel - 1;
> - /* Put subband samples into the proper place */
> - qmf_decompose(c, c->pcm, &c->subband[i][real_channel][0],real_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 */
> + int realchannel = c->channel_order_tab[channel];
> + if(realchannel>=0)
> + {
> + qmf_decompose(c, c->pcm, &c->subband[i][realchannel][0], realchannel);
> + }
> }
> + }
>
> - 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) + 3] << 16;
> - }
> - c->lfe_data[i] = lfe_downsample(c, c->pcm);
> - }
> -
> + 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;
> @@ -531,14 +537,45 @@ static int DCA_encode_init(AVCodecContext *avctx) {
> c->prim_channels = avctx->channels;
> c->lfe_channel = (avctx->channels==3 || avctx->channels==6);
>
> - if(c->lfe_channel){
> + switch(avctx->channel_layout)
> + {
Nit: switch (avctx->channel_layout) {
> + case CH_LAYOUT_STEREO:
> + c->a_mode = 2;
> + c->num_channel = 2;
> + break;
> + case CH_LAYOUT_5POINT0:
> + c->a_mode = 9;
> + c->num_channel = 9;
> + break;
> + case CH_LAYOUT_5POINT1:
> + c->a_mode = 9;
> + c->num_channel = 9;
> + break;
> + case CH_LAYOUT_5POINT0_BACK:
> + c->a_mode = 9;
> + c->num_channel = 9;
> + break;
> + case CH_LAYOUT_5POINT1_BACK:
> + c->a_mode = 9;
> + c->num_channel = 9;
> + break;
Use AV_CH_LAYOUT_* (libavutil/audioconvert.h).
Nit: you can align this switch like:
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;
more compact and more readable.
> + default:
> + av_log(avctx, AV_LOG_ERROR, "Only stereo and 5.1,5.0,5.0back,5.0front supported at the moment!\n");
please use spaces : Only stereo, 5.1, 5.0, 5.0back, and 5.0front channel layouts supported at the moment!
> + return -1;
return AVERROR_PATCHWELCOME
> + }
> +
> + if (c->lfe_channel)
> + {
> init_lfe_fir();
> - c->prim_channels--;
> + 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];
Nit: weird indent.
[...]
--
FFmpeg = Fabulous and Fierce Mournful Power Empowered Genius
More information about the ffmpeg-devel
mailing list