[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