[FFmpeg-soc] [soc]: r339 - in eac3: ac3.c ac3.h ac3tab.c ac3tab.h eac3.h eac3_parser.c eac3dec.c ffmpeg.patch

Justin Ruggles justinruggles at bellsouth.net
Sat Jul 7 19:24:22 CEST 2007


Overall, I think the code looks good.  There is a lot here, so I'll save 
some of my suggestions for later.

As a general comment, the bracket placement style seems inconsistant. 
You seem to be putting the opening bracket for if() statements on a new 
line most of the time, but occasionally you keep it on the same line.  I 
prefer the latter, but you can choose either way as long as it's consistant.

bwolowiec wrote:
> +typedef struct EAC3Context{
> +    // TODO erase unused variables
> +    // TODO add documentation
> +//Syncinfo
> +    int syncword;
> +
> +//BSI
> +    int strmtyp; // 2); ///< Stream type
> +    int substreamid; // 3); ///< Substream identification
> +    int frmsiz; // 11); ///< Frame size
> +    int fscod; // 2); ///< Sample rate code
> +    int fscod2; // 2); ///< Sample rate code 2
> +    int numblkscod; // 2); ///< Number of audio blocks
> +    int acmod; // 3); ///< Audio coding mode
> +    int lfeon; // 1); ///< Low frequency effect channel on
> +    int bsid; // 5); ///< Bit stream identification
> +    int dialnorm; // 5); ///<Dialogue normalization
> +    int compre; // 1); ///< Compression gain word exists
> +    int compr; // 8); ///< Compression gain word
> +    int dialnorm2; // 5); ///< Dialog normalization ch2
> +    int compr2e; // 1); ///< Compression gain word ch2 exists
> +    int compr2; // 8); ///< Compression gain word ch2
> +    int chanmape; // 1); ///< Custom channel map exists
> +    int chanmap; // 16); ///< Custom channel map
> +    int mixmdate; // 1); ///< Mixing meta-data exists
> +    int dmixmod; // 2); ///<
> +    int ltrtcmixlev; // 3);
> +    int lorocmixlev; // 3);
> +    int ltrtsurmixlev; // 3);
> +    int lorosurmixlev; // 3);
> +    int lfemixlevcode; // 1); ///< lfe mix level code exists
> +    int lfemixlevcod; // 5); ///< lfe mix level code
> +    int pgmscle; // 1); ///<  Program scale factor exists
> +    int pgmscl; // 6); ///< Program scale factor
> +    int pgmscl2e; // 1); ///< Program scale factor #2 exists
> +    int pgmscl2; // 6); ///< Program scale factor #2
> +    int extpgmscle; // 1); ///< External program scale factor exists
> +    int extpgmscl; // 6); ///< External program scale factor
> +    int mixdef; // 2); ///< Mix control type
> +    int mixdata; // 12); ///< Mixing parameter data
> +    int mixdeflen; // 5); ///< Length of mixing parameter data field
> +//    int *mixdata; // 8*(mixdeflen+2));
> +    int paninfoe; // 1); ///< Pan information exists
> +    int paninfo; // 14); ///< Pan information
> +    int paninfo2e; // 1); ///< Pan information 2 exists
> +    int paninfo2; // 14); ///< Pan information 2
> +    int frmmixcfginfoe; // 1); ///< Frame mixing configuration information exists
> +    int blkmixcfginfo0; // 5);
> +    int blkmixcfginfoe; // 1); ///< Block mixing configuration information exists
> +    int blkmixcfginfoblk; // 5); ///< Block mixing configuration information
> +    int infomdate; // 1); ///< Informational meta-data exists
> +    int bsmod; // 3); ///< Bit stream mode
> +    int copyrightb; // 1); ///< Copyright bit
> +    int origbs; // 1); ///< Original bit stream
> +    int dsurmod; // 2);
> +    int dheadphonmod; // 2);
> +    int dsurexmod; // 2);
> +    int audprodie; // 1);
> +    int mixlevel; // 5); ///< Mix level
> +    int roomtyp; // 2); ///< Room type
> +    int adconvtyp; // 1); ///< A/D converter type
> +    int audprodi2e; // 1); ///< Audio production information exists ch2
> +    int mixlevel2; // 5); ///< Mixing level ch2
> +    int roomtyp2; // 2); ///< room type ch2
> +    int adconvtyp2; // 1); ///< A/D converter type
> +    int sourcefscod; // 1); ///< Source sample rate code
> +    int convsync; // 1); ///< Converter synchronization flag
> +    int blkid; // 1); ///< Block identification
> +    int frmsizecod; // 6); ///< Frame size code
> +    int addbsie; // 1); ///< Additional bit stream information exists
> +    int addbsil; // 6); ///< Additional bit stream information length
> +    int addbsi[64]; // (addbsil+1)*8); ///< Additional bit stream information
> +
> +//Audfrm
> +    int expstre; // 1); ///< Exponent strategy syntax enabled
> +    int ahte; // 1); ///< Adaptive hybrid transform enabled
> +    int snroffststr; // 2); ///< SNR offset strategy
> +    int transproce; // 1); ///< Transient pre-noise processing enabled
> +    int blkswe; // 1); ///< Block switch syntax enabled
> +    int dithflage; // 1); ///< Dither flag syntax enabled
> +    int bamode; // 1); ///< Bit allocation model syntax enabled
> +    int frmfgaincode; // 1); ///< Fast gain codes enabled
> +    int dbaflde; // 1); ///< Delta bit allocation syntax enabled
> +    int skipflde; // 1); ///< Skip Filed syntax enabled
> +    int spxattene; // 1); ///< Spectral extension attenuation enabled
> +    int cplinu[MAX_BLOCKS]; // 1); ///< Coupling in use
> +    int cplstre[MAX_BLOCKS]; // 1); ///< Coupling strategy exists
> +    int cplexpstr[MAX_BLOCKS]; // 2); ///< Coupling exponents strategy
> +    int chexpstr[MAX_BLOCKS][MAX_CHANNELS]; // 2); ///< Channel exponent strategy
> +    int frmcplexpstr; // 5); ///< Frame based coupling exponent strategy
> +    int frmchexpstr[MAX_CHANNELS]; // 5); ///< frame based channel exponent strategy
> +    int lfeexpstr[MAX_BLOCKS]; // 1); ///< Lfe exponent strategy
> +    int convexpstre; // 1); ///< Converter exponent strategy exists
> +    int convexpstr[MAX_CHANNELS]; // 5); ///< Converter channel exponent strategy
> +    int cplahtinu; // 1); ///< Coupling channel AHT in use
> +    int chahtinu[MAX_CHANNELS]; // 1); ///< Channel AHT in use
> +    int lfeahtinu; // 1); ///< Lfe channel AHT in use
> +    int frmcsnroffst; // 6); ///< Frame coarse SNR offset
> +    int frmfsnroffst; // 4); ///< Frame fine SNR offset
> +    int chintransproc[MAX_CHANNELS]; // 1); ///< Channel in transient pre-noise processing
> +    int transprocloc[MAX_CHANNELS]; // 10); ///< Transient location relative to start of frame
> +    int transproclen[MAX_CHANNELS]; // 8); ///< Transient processing length
> +    int chinspxatten[MAX_CHANNELS]; // 1); ///< Channel in spectral extension attenuation process
> +    int spxattencod[MAX_CHANNELS]; // 5); ///< spectral extension attenuation code
> +    int blkstrtinfoe; // 1); ///< Block start information exists
> +    uint32_t blkstrtinfo; // nblkstrtbits); TODO  ///< Block start information
> +    int ncplblks;
> +
> +// EAC3Audblk
> +    int blksw[MAX_CHANNELS]; // 1); ///< Block switch flag
> +    int dithflag[MAX_CHANNELS]; // 1); ///< Dither flag
> +    int dynrnge; // 1); ///< Dynamic range gain word exists
> +    int dynrng; // 8); ///< Dynamic range gain word
> +    int dynrng2e; // 1); ///< Dynamic range gain word exists, ch2
> +    int dynrng2; // 8); ///< Dynamic range gain word
> +    int spxstre; // 1); ///< Spectral extension strategy exists
> +    int spxinu; // 1); ///< spectral extension in use
> +    int chinspx[MAX_CHANNELS]; // 1); ///< Channel in spectral extension
> +    int spxstrtf; // 2); ///< Spectral extension start copy frequency code
> +    int spxbegf; // 3); ///< Spectral extension begin frequency code
> +    int spxendf; // 3); ///< Spectral extension end frequency code
> +    int spxbndstrce; // 1); ///< Spectral extension band structure exists
> +    int spxbndstrc[MAX_SPX_CODES]; // 1); // [spxbegf...spxendf] ///< Spectral extension band structure
> +    int spxcoe[MAX_CHANNELS]; // 1); ///< Spectral extension coordinates exists
> +    int spxblnd[MAX_CHANNELS]; // 5); ///< Spectral extension blend
> +    int mstrspxco[MAX_CHANNELS]; // 2); ///< Master spectral extension coordinates
> +    int spxcoexp[MAX_CHANNELS][MAX_SPX_CODES]; // 4); ///< Spectral extension coordinate exponent
> +    int spxcomant[MAX_CHANNELS][MAX_SPX_CODES]; // 2); ///< Spectral extension coordinate mantissa
> +    int ecplinu; // 1); ///< Enhanced coupling in use
> +    int chincpl[MAX_CHANNELS]; // 1); ///< Channel in coupling
> +    int phsflginu; // 1); ///< Phase flag in use
> +    int cplbegf; // 4); ///< Coupling begin frequency code
> +    int cplendf; // 4); ///< Coupling end frequency code
> +    int cplbndstrce; // 1); ///< Coupling band structure exists
> +    int cplbndstrc[19]; // 1); ///< Coupling band structure
> +    int ecplbegf; // 4); ///< Enhanced coupling begin frequency code
> +    int ecplendf; // 4); ///< Enhanced coupling end frequency code
> +    int ecplbndstrce; // 1); ///< Enhanced coupling band structure exists
> +    int ecplbndstrc[TODO_SIZE]; // 1);  ///< Enhanced coupling band structure
> +    int cplcoe[MAX_CHANNELS]; // 1); ///< Coupling coordinates exists
> +    int mstrcplco[MAX_CHANNELS]; // 2); ///< Master coupling coordinates
> +    int cplcoexp[MAX_CHANNELS][TODO_SIZE]; // 4); ///< Coupling coordinate exponent
> +    int cplcomant[MAX_CHANNELS][TODO_SIZE]; // 4); ///< Coupling coordinate mantissa
> +    int phsflg[TODO_SIZE]; // 1); ///< Phase flag
> +    int ecplangleintrp; // 1); ///< Enhanced coupling angle interpolation flag
> +    int ecplparam1e[MAX_CHANNELS]; // 1); ///< Enhanced coupling parameters 1 exists
> +    int ecplparam2e[MAX_CHANNELS]; // 1); ///< Enhanced coupling parameters 2 exists
> +    int ecplamp[MAX_CHANNELS][TODO_SIZE]; // 5); ///< Enhanced coupling amplitude scaling
> +    int ecplangle[MAX_CHANNELS][TODO_SIZE]; // 6); ///< Enhanced coupling angle
> +    int ecplchaos[MAX_CHANNELS][TODO_SIZE]; // 3); ///< Enhanced coupling chaos
> +    int ecpltrans[MAX_CHANNELS]; // 1); ///< Enhanced coupling transient present
> +    int rematstr; // 1); ///< Rematrixing strategy
> +    int rematflg[TODO_SIZE]; // 1); ///< Rematrixing flag
> +    int chbwcod[MAX_CHANNELS]; // 6); ///< Rematrixing strategy
> +    int cplabsexp; // 4); ///< Coupling absolute exponent
> +    int cplexps[TODO_SIZE]; // 7); ///< Coupling exponent
> +
> +    int gainrng[MAX_CHANNELS]; // 2); ///< Channel Gain range code
> +//    int lfeexps[3]; // 7); // 0...nlfegrps = const 0...2
> +    int baie; // 1); ///< Bit allocation information exists
> +    int sdcycod; // 2); ///< Slow decay code
> +    int fdcycod; // 2); ///< Fast decay code
> +    int sgaincod; // 2); ///< Slow gain code
> +    int dbpbcod; // 2); ///< dB per bit code
> +    int floorcod; // 3); ///< Masking floor code
> +    int snroffste; // 1); ///< SNR offset exists
> +    int csnroffst; // 6); ///< Coarse SNR offset
> +    int blkfsnroffst; // 4); ///< Block fine SNR offset
> +    int cplfsnroffst; // 4); ///< Coupling fine SNR offset
> +    int fsnroffst[MAX_CHANNELS]; // 4); ///< Channel fine SNR offset
> +    int lfefsnroffst; // 4); ///< Lfe fine SNR offset
> +    int fgaincode; // 1); ///< Channel fast gain code enabled
> +    int cplfgaincod; // 3); ///< Coupling fast gain code code
> +    int fgaincod[MAX_CHANNELS]; // 3); ///< Channel fast gain code
> +    int lfefgaincod; // 3); ///< Lfe fast gain code
> +    int convsnroffste; // 1); ///< Converter SNR offset exists
> +    int convsnroffst; // 10); ///< Converter SNR offset
> +    int cplleake; // 1); ///< Coupling leak initialization exists
> +    int cplfleak; // 3); ///< Coupling fast leak initialization
> +    int cplsleak; // 3); ///< Coupling slow leak initialization
> +    int deltbaie; // 1); ///< Delta bit allocation information exists
> +    int cpldeltbae; // 2); ///< Coupling delta bit allocation exists
> +    uint8_t deltbae[MAX_CHANNELS]; // 2); ///< Delta bit allocation exists
> +    int cpldeltnseg; // 3); ///< Coupling delta bit allocation number of segments
> +    int cpldeltoffst[9]; // 5); 0..cpldeltnseg ///< Coupling bit allocation offset
> +    int cpldeltlen[9]; // 4); 0..cpldeltnseg ///< Coupling delta bit allocation length
> +    int cpldeltba[9]; // 3); 0..cpldeltnseg ///< Coupling delta bit allocation
> +    uint8_t deltnseg[MAX_CHANNELS]; // 3); ///< Channel delta bit allocation number of segments
> +    uint8_t deltoffst[MAX_CHANNELS][9]; // 5); 0..deltnseg[ch] ///< Channel delta bit allocation offset
> +    uint8_t deltlen[MAX_CHANNELS][9]; // 4); 0..deltnseg[ch] ///< Channel delta bit allocation length
> +    uint8_t deltba[MAX_CHANNELS][9]; // 3); 0..deltnseg[ch] ///< Channel delta bit allocation
> +    int skiple; // 1); ///< Skip length exists
> +    int skipl; // 9); ///< Skip length
> +    int skipfld; // TODO skipl * 8); ///< Skip field
> +
> +    int got_cplchan;
> +//    int chmant[MAX_CHANNELS][TODO_SIZE];
> +    int chgaqmod[MAX_CHANNELS]; ///< Channel gain adaptive quantization mode
> +    int chgaqgain[MAX_CHANNELS][TODO_SIZE]; // [ch][0..chgaqsections[ch]] ///< Channel gain adaptive quantization gain
> +    int pre_chmant[6][MAX_CHANNELS][TODO_SIZE]; // [][][nchmant[ch]] ///< Pre channel mantissas
> +    int cplmant[TODO_SIZE]; // cplmant ///< Coupling mantisass
> +    int cplgaqmod;  ///< Coupling channel gain adaptive quantization mode
> +    int cplgaqgain[TODO_SIZE]; // [cplgaqsections] ///< Coupling gain adaptive quantization gain
> +    int pre_cplmant[6][TODO_SIZE]; // [][ncplmant] ///< Pre coupling channel_mantissas
> +    int lfegaqmod; ///<  Lfe channel gain adaptive quantization mode
> +    int lfegaqgain[TODO_SIZE]; ///<  LFE channel gain adaptive quantization mode
> +    int pre_lfemant[6][TODO_SIZE]; ///< Pre lfe channel mantissas
> +
> +
> +
> +
> +    int firstspxcos[MAX_CHANNELS]; // TODO type ? ///< First spectral extension coordinates states
> +    int firstcplcos[MAX_CHANNELS]; // TODO type ? ///< First coupling coordinates states
> +    int firstcplleak; // TODO type ? ///< First coupling leak state
> +
> +
> +
> +    // TODO
> +    int lfegaqbin[TODO_SIZE];
> +    int lfegaqsections;
> +    int cplgaqbin[TODO_SIZE];
> +    int cplgaqsections;
> +    int chgaqbin[MAX_CHANNELS][TODO_SIZE]; // [][nchmant]
> +    int chgaqsections[MAX_CHANNELS];
> +    int nchmant[MAX_CHANNELS]; ///< Number of fbw channel mantissas
> +    int ncplsubnd; ///< Number of coupling sub-bands
> +    int ncplbnd; ///< Number of structured coupled bands
> +    int nrematbnds;
> +    int ncplgrps; ///< Number of coupled exponent groups
> +    int ncplmant; ///< Number of coupled mantissas
> +
> +    int nlfemant; ///< Number of lfe mantissas
> +    int nchgrps[MAX_CHANNELS]; ///< Number of fbw channel exponent groups
> +    uint8_t dexps[MAX_CHANNELS][AC3_MAX_COEFS]; ///< Differential exponents
> +
> +    int cplstrtmant;
> +    int cplendmant;
> +    int endmant[MAX_CHANNELS];
> +    int strtmant[MAX_CHANNELS];
> +    int firstchincpl;
> +    int ecpl_start_subbnd, ecpl_end_subbnd;
> +    int nlfegrps; ///< Number of lfe channel exponent groups
> +
> +    int necplbnd;
> +    int nspxbnds;
> +    int spxbndsztab[MAX_SPX_CODES]; // max_spxendf + 1 = 18 ?
> +    int nfchans; ///< Number of fbw channels
> +
> +    uint8_t bap[MAX_CHANNELS][AC3_MAX_COEFS]; ///< bit allocation pointers
> +    int16_t psd[MAX_CHANNELS][AC3_MAX_COEFS]; ///< scaled exponents
> +    int16_t bndpsd[MAX_CHANNELS][350]; ///< interpolated exponents FIXME in ac3dec [50] !?
> +    int16_t mask[MAX_CHANNELS][350]; ///< masking values
> +
> +
> +    DECLARE_ALIGNED_16(float, transform_coeffs[MAX_CHANNELS][AC3_MAX_COEFS]);
> +
> +    /// TODO move to AC3BitAllocParameters
> +    int sdecay;
> +    int fdecay;
> +    int sgain;
> +    int dbknee;
> +    int floor;
> +
> +    AC3BitAllocParameters bit_alloc_params;
> +
> +    AVRandomState dith_state;   ///< for dither generation
> +
> +
> +    int ntchans; ///< Total of all channels
> +    int lfe_channel;
> +
> +    GetBitContext *gbc;
> +
> +    MDCTContext imdct_512;      ///< for 512 sample imdct transform
> +    MDCTContext imdct_256;      ///< for 256 sample imdct transform
> +    DSPContext  dsp;            ///< for optimization
> +
> +    DECLARE_ALIGNED_16(float, delay[MAX_CHANNELS][AC3_BLOCK_SIZE]); ///< delay - added to the next block
> +    DECLARE_ALIGNED_16(float, window[AC3_BLOCK_SIZE]); ///< window coefficients
> +    DECLARE_ALIGNED_16(float, tmp_output[AC3_BLOCK_SIZE * 24]); ///< temp storage for output before windowing
> +    DECLARE_ALIGNED_16(float, tmp_imdct[AC3_BLOCK_SIZE * 24]); ///< temp storage for imdct transform
> +    DECLARE_ALIGNED_16(float, output[MAX_CHANNELS][AC3_BLOCK_SIZE]); ///< output after imdct transform and windowing
> +    DECLARE_ALIGNED_16(int16_t, int_output[MAX_CHANNELS][AC3_BLOCK_SIZE]);///< final 16-bit integer output
> +    float add_bias; ///< offset for float_to_int16 conversion
> +    float mul_bias; ///< scaling for float_to_int16 conversion
> +
> +    AC3ChannelMode  blkoutput;
> +}EAC3Context;

Align your comments vertically.

> +
> +int eac3_parse_syncinfo(GetBitContext *gbc, EAC3Context *s);
> +int eac3_parse_bsi(GetBitContext *gbc, EAC3Context *s);
> +int eac3_parse_audfrm(GetBitContext *gbc, EAC3Context *s);
> +int eac3_parse_audblk(GetBitContext *gbc, EAC3Context *s, const int blk);
> +int eac3_parse_auxdata(GetBitContext *gbc, EAC3Context *s);
> +
> +#endif
> 
> Added: eac3/eac3_parser.c
> ==============================================================================
> --- (empty file)
> +++ eac3/eac3_parser.c	Sat Jul  7 16:04:27 2007
> @@ -0,0 +1,1271 @@
> +/*
> + * E-AC3 parser
> + * Copyright (c) 2007 Bartlomiej Wolowiec
> + *
> + * 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
> + */
> +
> +//#define DEBUG
> +
> +#include "avcodec.h"
> +#include "bitstream.h"
> +#include "ac3.h"
> +#include "random.h"
> +
> +#ifdef DEBUG
> +#define GET_BITS(a, gbc, n) a = get_bits(gbc, n); av_log(NULL, AV_LOG_INFO, "%s: %i\n", __STRING(a), a)
> +#else
> +#define GET_BITS(a, gbc, n) a = get_bits(gbc, n)
> +#ifdef assert
> +#undef assert
> +#endif //assert
> +#define assert(x) if(!(x)){av_log(NULL, AV_LOG_INFO, "Error: %s\n", #x); return 1;}
> +#endif //DEBUG

The GET_BITS macro seems fine for testing purposes, but I really don't 
like redefining assert.  assert() is really not meant to be used the way 
  you're using it here.  I'd rather you just go ahead and put in the 
av_log and return -1 when unsupported features are encountered.

> +#include "eac3.h"
> +
> +int eac3_parse_syncinfo(GetBitContext *gbc, EAC3Context *s){
> +    GET_BITS(s->syncword, gbc, 16);
> +    return 0;
> +}

Why a separate function just to read the syncinfo?

> +int eac3_parse_bsi(GetBitContext *gbc, EAC3Context *s){
> +    int i, blk;
> +
> +    GET_BITS(s->strmtyp, gbc, 2);
> +    GET_BITS(s->substreamid, gbc, 3);
> +    GET_BITS(s->frmsiz, gbc, 11);
> +    GET_BITS(s->fscod, gbc, 2);
> +    if(s->fscod == 0x3)
> +    {
> +        assert(0 && "TODO");

should be av_log and return. comment out or #if 0 around unused code.

> +        GET_BITS(s->fscod2, gbc, 2);
> +        s->numblkscod = 0x3; /* six blocks per frame */
> +    }
> +    else
> +    {
> +        GET_BITS(s->numblkscod, gbc, 2);
> +    }
> +    GET_BITS(s->acmod, gbc, 3);
> +    GET_BITS(s->lfeon, gbc, 1);
> +
> +    //calc

not a very descriptive comment.  how about something like:
// calculate number of channels

> +    s->nfchans = ff_ac3_channels[s->acmod];
> +    s->ntchans = s->nfchans;
> +    if(s->lfeon){
> +        s->lfe_channel = s->ntchans+1;
> +
> +        s->nlfemant = 7;
> +        s->endmant[s->lfe_channel] = 7;
> +        s->nchgrps[s->lfe_channel] = 2;
> +
> +        s->ntchans ++ ;
> +    }
> +
> +    GET_BITS(s->bsid, gbc, 5);
> +    assert(s->bsid == 16);

This is wrong. Can legally be any value from 11 to 16.

> +    GET_BITS(s->dialnorm, gbc, 5);
> +    GET_BITS(s->compre, gbc, 1);
> +    if(s->compre) {
> +        GET_BITS(s->compr, gbc, 8);
> +    }
> +    if(s->acmod == 0x0) /* if 1+1 mode (dual mono, so some items need a second value) */
> +    {
> +        GET_BITS(s->dialnorm2, gbc, 5);
> +        GET_BITS(s->compr2e, gbc, 1);
> +        if(s->compr2e) {
> +            GET_BITS(s->compr2, gbc, 8);
> +        }
> +
> +    }
> +    if(s->strmtyp == 0x1) /* if dependent stream */
> +    {
> +        GET_BITS(s->chanmape, gbc, 1);
> +        if(s->chanmape) {
> +            GET_BITS(s->chanmap, gbc, 16);
> +        }
> +    }
> +    GET_BITS(s->mixmdate, gbc, 1);
> +    if(s->mixmdate) /* Mixing metadata */
> +    {
> +        if(s->acmod > 0x2) /* if more than 2 channels */ {
> +            GET_BITS(s->dmixmod, gbc, 2);
> +        }
> +        if((s->acmod & 0x1) && (s->acmod > 0x2)) /* if three front channels exist */
> +        {
> +            GET_BITS(s->ltrtcmixlev, gbc, 3);
> +            GET_BITS(s->lorocmixlev, gbc, 3);
> +        }
> +        if(s->acmod & 0x4) /* if a surround channel exists */
> +        {
> +
> +            GET_BITS(s->ltrtsurmixlev, gbc, 3);
> +            GET_BITS(s->lorosurmixlev, gbc, 3);
> +        }
> +        if(s->lfeon) /* if the LFE channel exists */
> +        {
> +            GET_BITS(s->lfemixlevcode, gbc, 1);
> +            if(s->lfemixlevcode) {
> +                GET_BITS(s->lfemixlevcod, gbc, 5);
> +            }
> +        }
> +        if(s->strmtyp == 0x0) /* if independent stream */
> +        {
> +            GET_BITS(s->pgmscle, gbc, 1);
> +            if(s->pgmscle) {
> +                GET_BITS(s->pgmscl, gbc, 6);
> +            }
> +            if(s->acmod == 0x0) /* if 1+1 mode (dual mono, so some items need a second value) */
> +            {
> +                GET_BITS(s->pgmscl2e, gbc, 1);
> +                if(s->pgmscl2e) {
> +                    GET_BITS(s->pgmscl2, gbc, 6);
> +                }
> +            }
> +            GET_BITS(s->extpgmscle, gbc, 1);
> +            if(s->extpgmscle) {
> +                GET_BITS(s->extpgmscl, gbc, 6);
> +            }
> +            GET_BITS(s->mixdef, gbc, 2);
> +            if(s->mixdef == 0x1) /* mixing option 2 */ {
> +                GET_BITS(s->mixdata, gbc, 5);
> +            }
> +            else if(s->mixdef == 0x2) /* mixing option 3 */ {
> +                GET_BITS(s->mixdata, gbc, 12);
> +            }
> +            else if(s->mixdef == 0x3) /* mixing option 4 */
> +            {
> +                GET_BITS(s->mixdeflen, gbc, 5);
> +                assert( 0 && "TODO");

av_log and return

> +//                GET_BITS(s->mixdata, gbc, 8*(mixdeflen+2));
> +            }
> +            if(s->acmod < 0x2) /* if mono or dual mono source */
> +            {
> +                GET_BITS(s->paninfoe, gbc, 1);
> +                if(s->paninfoe) {
> +                    GET_BITS(s->paninfo, gbc, 14);
> +                }
> +                if(s->acmod == 0x0) /* if 1+1 mode (dual mono, so some items need a second value) */
> +                {
> +                    GET_BITS(s->paninfo2e, gbc, 1);
> +                    if(s->paninfo2e) {
> +                        GET_BITS(s->paninfo2, gbc, 14);
> +                    }
> +                }
> +            }
> +            GET_BITS(s->frmmixcfginfoe, gbc, 1);
> +            if(s->frmmixcfginfoe) /* mixing configuration information */
> +            {
> +                if(s->numblkscod == 0x0) {
> +                    GET_BITS(s->blkmixcfginfo0, gbc, 5);
> +                }
> +                else
> +                {
> +                    for(blk = 0; blk < ff_eac3_blocks[s->numblkscod]; blk++)
> +                    {
> +                        GET_BITS(s->blkmixcfginfoe, gbc, 1);
> +                        if(s->blkmixcfginfoe){
> +                            GET_BITS(s->blkmixcfginfoblk, gbc, 5);
> +                        }
> +                    }
> +                }
> +            }
> +        }
> +    }
> +    GET_BITS(s->infomdate, gbc, 1);
> +    if(s->infomdate) /* Informational metadata */
> +    {
> +        GET_BITS(s->bsmod, gbc, 3);
> +
> +        GET_BITS(s->copyrightb, gbc, 1);
> +        GET_BITS(s->origbs, gbc, 1);
> +        if(s->acmod == 0x2) /* if in 2/0 mode */
> +        {
> +            GET_BITS(s->dsurmod, gbc, 2);
> +            GET_BITS(s->dheadphonmod, gbc, 2);
> +        }
> +        if(s->acmod >= 0x6) /* if both surround channels exist */ {
> +            GET_BITS(s->dsurexmod, gbc, 2);
> +        }
> +        GET_BITS(s->audprodie, gbc, 1);
> +        if(s->audprodie)
> +        {
> +            GET_BITS(s->mixlevel, gbc, 5);
> +            GET_BITS(s->roomtyp, gbc, 2);
> +            GET_BITS(s->adconvtyp, gbc, 1);
> +        }
> +        if(s->acmod == 0x0) /* if 1+1 mode (dual mono, so some items need a second value) */
> +        {
> +            GET_BITS(s->audprodi2e, gbc, 1);
> +            if(s->audprodi2e)
> +            {
> +                GET_BITS(s->mixlevel2, gbc, 5);
> +                GET_BITS(s->roomtyp2, gbc, 2);
> +                GET_BITS(s->adconvtyp2, gbc, 1);
> +            }
> +        }
> +        if(s->fscod < 0x3) /* if not half sample rate */ {
> +            GET_BITS(s->sourcefscod, gbc, 1); // TODO
> +        }
> +    }
> +    if((s->strmtyp == 0x0) && (s->numblkscod != 0x3) ) {
> +        GET_BITS(s->convsync, gbc, 1);
> +    }
> +    if(s->strmtyp == 0x2) /* if bit stream converted from AC-3 */
> +    {
> +        if(s->numblkscod == 0x3) /* 6 blocks per frame */ {
> +            s->blkid = 1;
> +        }
> +        else {
> +            GET_BITS(s->blkid, gbc, 1);
> +        }
> +        if(s->blkid) {
> +            GET_BITS(s->frmsizecod, gbc, 6);
> +        }
> +    }
> +    GET_BITS(s->addbsie, gbc, 1);
> +    if(s->addbsie)
> +    {
> +        GET_BITS(s->addbsil, gbc, 6);
> +        for(i=0; i<s->addbsil+1; i++){
> +            GET_BITS(s->addbsi[i], gbc, 8);
> +        }
> +    }
> +
> +    return 0;
> +} /* end of bsi */
> +
> +
> +int eac3_parse_audfrm(GetBitContext *gbc, EAC3Context *s){
> +    int blk, ch;
> +
> +    /* These fields for audio frame exist flags and strategy data */
> +    if(s->numblkscod == 0x3) /* six blocks per frame */
> +    {
> +        GET_BITS(s->expstre, gbc, 1);
> +        GET_BITS(s->ahte, gbc, 1);
> +    }
> +    else
> +    {
> +        s->expstre = 1;
> +        s->ahte = 0;
> +    }
> +    GET_BITS(s->snroffststr, gbc, 2);
> +    GET_BITS(s->transproce, gbc, 1);
> +    GET_BITS(s->blkswe, gbc, 1);
> +    GET_BITS(s->dithflage, gbc, 1);
> +    GET_BITS(s->bamode, gbc, 1);
> +    GET_BITS(s->frmfgaincode, gbc, 1);
> +    GET_BITS(s->dbaflde, gbc, 1);
> +    GET_BITS(s->skipflde, gbc, 1);
> +    GET_BITS(s->spxattene, gbc, 1);
> +    /* These fields for coupling data */
> +    if(s->acmod > 0x1)
> +    {
> +        s->cplstre[0] = 1;
> +        GET_BITS(s->cplinu[0], gbc, 1);
> +        for(blk = 1; blk < ff_eac3_blocks[s->numblkscod]; blk++)
> +        {
> +            GET_BITS(s->cplstre[blk], gbc, 1);
> +
> +            if(s->cplstre[blk] == 1) {
> +                GET_BITS(s->cplinu[blk], gbc, 1);
> +            }
> +            else {
> +                s->cplinu[blk] = s->cplinu[blk-1];
> +            }
> +        }
> +    }
> +    else
> +    {
> +        for(blk = 0; blk < ff_eac3_blocks[s->numblkscod]; blk++) {
> +            s->cplinu[blk] = 0;
> +        }
> +    }
> +
> +    // calc

// calculate number of coupling blocks

> +    s->ncplblks = 0;
> +    for(blk = 0; blk < ff_eac3_blocks[s->numblkscod]; blk++) {
> +        s->ncplblks += s->cplinu[blk];
> +    }
> +
> +    /* These fields for exponent strategy data */
> +    if(s->expstre)
> +    {
> +        for(blk = 0; blk < ff_eac3_blocks[s->numblkscod]; blk++)
> +        {
> +            if(s->cplinu[blk] == 1) {
> +                GET_BITS(s->cplexpstr[blk], gbc, 2);
> +            }
> +
> +            for(ch = 1; ch <= s->nfchans; ch++) {
> +                GET_BITS(s->chexpstr[blk][ch], gbc, 2); // TODO
> +            }
> +        }
> +    }
> +    else
> +    {
> +        if( (s->acmod > 0x1) && (s->ncplblks > 0) ) {
> +            GET_BITS(s->frmcplexpstr, gbc, 5);
> +        }
> +        for(ch = 1; ch <= s->nfchans; ch++) {
> +            GET_BITS(s->frmchexpstr[ch], gbc, 5);
> +        }
> +        /* cplexpstr[blk] and chexpstr[blk][ch] derived from table lookups ? see Table E2.14 */
> +        assert(0 && "TODO");

av_log and return.
Though there may not be any samples which utilize this, it should be 
fairly straightforward to go ahead and implement. Just add the table to 
ac3tab.c or create a separate eac3tab.c/h.  Actually, the latter might 
be preferable since in the future there will be some fairly large vector 
quantization tables.

> +    }
> +    if(s->lfeon)
> +    {
> +        for(blk = 0; blk < ff_eac3_blocks[s->numblkscod]; blk++) {
> +            GET_BITS(s->lfeexpstr[blk], gbc, 1);
> +            s->chexpstr[blk][s->lfe_channel] = s->lfeexpstr[blk];
> +        }
> +    }
> +    /* These fields for converter exponent strategy data */
> +    if(s->strmtyp == 0x0)
> +    {
> +        if(s->numblkscod != 0x3) {
> +            GET_BITS(s->convexpstre, gbc, 1);
> +        }
> +        else {
> +            s->convexpstre = 1;
> +        }
> +        if(s->convexpstre == 1)
> +        {
> +            for(ch = 1; ch <= s->nfchans; ch++) {
> +                GET_BITS(s->convexpstr[ch], gbc, 5);
> +            }
> +        }

same here, lookup exponent strategies in table E2.14

> +    }
> +    /* These fields for AHT data */
> +    if(s->ahte)
> +    {
> +        /* coupling can use AHT only when coupling in use for all blocks */
> +        /* ncplregs derived from cplstre and cplexpstr ? see Section E3.3.2 */
> +        assert( 0 && "TODO: AHT" );

av_log and return

> +        /*
> +        if( (s->ncplblks == 6) && (s->ncplregs ==1) ) {
> +            GET_BITS(s->cplahtinu, gbc, 1);
> +        }
> +        else {
> +            cplahtinu = 0
> +        }
> +
> +        for(ch = 1; ch <= s->nfchans; ch++)
> +        {
> +            // nchregs derived from chexpstr ? see Section E3.3.2
> +            if(s->nchregs[ch] == 1) {
> +                GET_BITS(s->chahtinu[ch], gbc, 1);
> +            }
> +            else {
> +                chahtinu[ch] = 0
> +            }
> +        }
> +        if(lfeon)
> +        {
> +            // nlferegs derived from lfeexpstr ? see Section E3.3.2
> +            if(nlferegs == 1) {
> +                GET_BITS(s->lfeahtinu, gbc, 1);
> +            }
> +            else {
> +                lfeahtinu = 0
> +            }
> +        }
> +        */
> +    }
> +    /* These fields for audio frame SNR offset data */
> +    if(s->snroffststr == 0x0)
> +    {
> +        GET_BITS(s->frmcsnroffst, gbc, 6);
> +        GET_BITS(s->frmfsnroffst, gbc, 4);
> +    }
> +    /* These fields for audio frame transient pre-noise processing data */
> +    if(s->transproce)
> +    {
> +        for(ch = 1; ch <= s->nfchans; ch++)
> +        {
> +            GET_BITS(s->chintransproc[ch], gbc, 1);
> +            if(s->chintransproc[ch])
> +            {
> +                GET_BITS(s->transprocloc[ch], gbc, 10);
> +                GET_BITS(s->transproclen[ch], gbc, 8);
> +            }
> +        }
> +    }
> +    /* These fields for spectral extension attenuation data */
> +    if(s->spxattene)
> +    {
> +        for(ch = 1; ch <= s->nfchans; ch++)
> +        {
> +            GET_BITS(s->chinspxatten[ch], gbc, 1);
> +            if(s->chinspxatten[ch])
> +            {
> +                GET_BITS(s->spxattencod[ch], gbc, 5);
> +            }
> +        }
> +    }
> +    /* These fields for block start information */
> +    if (s->numblkscod != 0x0) {
> +        GET_BITS(s->blkstrtinfoe, gbc, 1);
> +    }
> +    else {
> +        s->blkstrtinfoe = 0;
> +    }
> +    if(s->blkstrtinfoe)
> +    {
> +        /* nblkstrtbits determined from frmsiz (see Section E2.3.2.27) */
> +        // nblkstrtbits = (numblks - 1) * (4 + ceiling (log2 (words_per_frame)))
> +        // where numblks is derived from the numblkscod in Table E2.15 <- TODO ???
> +        // words_per_frame = frmsiz + 1
> +        int nblkstrtbits = (ff_eac3_blocks[s->numblkscod]-1) * (4 + (av_log2(s->frmsiz-1)+1) );
> +        av_log(NULL, AV_LOG_INFO, "nblkstrtbits = %i\n", nblkstrtbits);
> +        GET_BITS(s->blkstrtinfo, gbc, nblkstrtbits);
> +    }
> +    /* These fields for syntax state initialization */
> +    for(ch = 1; ch <= s->nfchans; ch++)
> +    {
> +        s->firstspxcos[ch] = 1;
> +        s->firstcplcos[ch] = 1;
> +    }
> +    s->firstcplleak = 1;
> +
> +    return 0;
> +} /* end of audfrm */
> +
> +int eac3_parse_audblk(GetBitContext *gbc, EAC3Context *s, const int blk){
> +    int ch, grp, seg;
> +    int bnd, sbnd, i, n, bin;
> +    /* These fields for block switch and dither flags */
> +    if(s->blkswe)
> +    {
> +        for(ch = 1; ch <= s->nfchans; ch++) {
> +            GET_BITS(s->blksw[ch], gbc, 1);
> +        }
> +    }
> +    else
> +    {
> +        for(ch = 1; ch <= s->nfchans; ch++) {
> +            s->blksw[ch] = 0;
> +        }
> +    }
> +    if(s->dithflage)
> +    {
> +        for(ch = 1; ch <= s->nfchans; ch++) {
> +            GET_BITS(s->dithflag[ch], gbc, 1);
> +        }
> +    }
> +    else
> +    {
> +        for(ch = 1; ch <= s->nfchans; ch++) {
> +            s->dithflag[ch] = 1; /* dither on */
> +        }
> +    }
> +    /* These fields for dynamic range control */
> +    GET_BITS(s->dynrnge, gbc, 1);
> +    if(s->dynrnge) {
> +        GET_BITS(s->dynrng, gbc, 8);
> +    }
> +    if(s->acmod == 0x0) /* if 1+1 mode */
> +    {
> +        GET_BITS(s->dynrng2e, gbc, 1);
> +        if(s->dynrng2e) {
> +            GET_BITS(s->dynrng2, gbc, 8);
> +        }
> +    }
> +    /* These fields for spectral extension strategy information */
> +    if(blk == 0) {
> +        s->spxstre = 1;
> +    }
> +    else {
> +        GET_BITS(s->spxstre, gbc, 1);
> +    }
> +    assert(blk || s->spxstre);
> +    if(s->spxstre)
> +    {
> +        GET_BITS(s->spxinu, gbc, 1);
> +        if(s->spxinu)
> +        {
> +            if(s->acmod == 0x1)
> +            {
> +                s->chinspx[0] = 1;
> +            }
> +            else
> +            {
> +                for(ch = 1; ch <= s->nfchans; ch++) {
> +                    GET_BITS(s->chinspx[ch], gbc, 1);
> +                }
> +            }
> +            GET_BITS(s->spxstrtf, gbc, 2);
> +            GET_BITS(s->spxbegf, gbc, 3);
> +            GET_BITS(s->spxendf, gbc, 3);
> +            if(s->spxbegf < 6) {
> +                s->spxbegf += 2;
> +            }
> +            else {
> +                s->spxbegf = s->spxbegf * 2 - 3;
> +            }
> +            if(s->spxendf < 3) {
> +                s->spxendf += 5;
> +            }
> +            else {
> +                s->spxendf = s->spxendf * 2 + 3;
> +            }
> +            GET_BITS(s->spxbndstrce, gbc, 1);
> +
> +            assert(blk || s->spxbndstrce); // TODO default values..

av_log and return

> +            if(s->spxbndstrce)
> +            {
> +                for(bnd = s->spxbegf+1; bnd < s->spxendf; bnd++) {
> +                    GET_BITS(s->spxbndstrc[bnd], gbc, 1);
> +                }
> +            }
> +            //calc

// calculate number of spectral extension bands

> +            s->nspxbnds = 1;
> +            s->spxbndsztab[0] = 12;
> +            for (bnd = s->spxbegf+1; bnd < s->spxendf; bnd ++)
> +            {
> +                if (s->spxbndstrc[bnd] == 0)
> +                {
> +                    s->spxbndsztab[s->nspxbnds] = 12;
> +                    s->nspxbnds++;
> +                }
> +                else
> +                {
> +                    s->spxbndsztab[s->nspxbnds - 1] += 12;
> +                }
> +            }
> +            assert(s->nspxbnds < MAX_SPX_CODES);
> +        }
> +        else /* !spxinu */
> +        {
> +            for(ch = 1; ch <= s->nfchans; ch++)
> +            {
> +                s->chinspx[ch] = 0;
> +                s->firstspxcos[ch] = 1;
> +            }
> +        }
> +    }
> +
> +
> +    /* These fields for spectral extension coordinates */
> +    if(s->spxinu)
> +    {
> +        for(ch = 1; ch <= s->nfchans; ch++)
> +        {
> +            if(s->chinspx[ch])
> +            {
> +                if(s->firstspxcos[ch])
> +                {
> +                    s->spxcoe[ch] = 1;
> +                    s->firstspxcos[ch] = 0;
> +                }
> +                else /* !firstspxcos[ch] */ {
> +                    GET_BITS(s->spxcoe[ch], gbc, 1);
> +                }
> +                assert(blk || s->spxcoe[ch]);
> +                if(s->spxcoe[ch])
> +                {
> +                    GET_BITS(s->spxblnd[ch], gbc, 5);
> +                    GET_BITS(s->mstrspxco[ch], gbc, 2);
> +                    /* nspxbnds determined from spxbegf, spxendf, and spxbndstrc[ ] */
> +                    assert(s->nspxbnds < MAX_SPX_CODES);
> +                    for(bnd = 0; bnd < s->nspxbnds; bnd++)
> +                    {
> +                        GET_BITS(s->spxcoexp[ch][bnd], gbc, 4);
> +                        GET_BITS(s->spxcomant[ch][bnd], gbc, 2);
> +                    }
> +                }
> +            }
> +            else /* !chinspx[ch] */
> +            {
> +                s->firstspxcos[ch] = 1;
> +            }
> +        }
> +    }
> +    /* These fields for coupling strategy and enhanced coupling strategy information */
> +    if(s->cplstre[blk])
> +    {
> +        if (s->cplinu[blk])
> +        {
> +            GET_BITS(s->ecplinu, gbc, 1);
> +            assert(!s->ecplinu && "TODO");
> +            if (s->acmod == 0x2)
> +            {
> +                s->chincpl[0] = 1;
> +                s->chincpl[1] = 1;
> +            }
> +            else
> +            {
> +                for(ch = 1; ch <= s->nfchans; ch++) {
> +                    GET_BITS(s->chincpl[ch], gbc, 1);
> +                }
> +            }
> +            if (s->ecplinu == 0) /* standard coupling in use */
> +            {
> +                if(s->acmod == 0x2) /* if in 2/0 mode */ {
> +                    GET_BITS(s->phsflginu, gbc, 1);
> +                }
> +                GET_BITS(s->cplbegf, gbc, 4);
> +                if (s->spxinu == 0) /* if SPX not in use */
> +                {
> +                    GET_BITS(s->cplendf, gbc, 4);
> +                    s->cplendf = s->cplendf + 3;
> +                }
> +                else /* SPX in use */
> +                {
> +                    s->cplendf = s->spxbegf - 1;
> +                }
> +
> +                // calc
> +                s->cplstrtmant = 37 + (12 * s->cplbegf);
> +                s->cplendmant = 37 + (12 * (s->cplendf + 3));
> +
> +                GET_BITS(s->cplbndstrce, gbc, 1);
> +                if(s->cplbndstrce)
> +                {
> +                    for(bnd = s->cplbegf+1; bnd < s->cplendf; bnd++) {
> +                        GET_BITS(s->cplbndstrc[bnd], gbc, 1);
> +                    }
> +                }
> +                //TODO calc ncplsubnd ?
> +                s->ncplsubnd =  s->cplendf - s->spxbegf + 1;
> +                s->ncplbnd = s->ncplsubnd;
> +                for(bnd = 1; bnd < s->cplendf; bnd++){
> +                    s->ncplbnd -= s->cplbndstrc[bnd];
> +                }
> +
> +            }

Somehow I don't think this part is correct.  But we don't have any 
samples which use spectral extension, so it should work okay for now.

> +            else /* enhanced coupling in use */
> +            {
> +                assert(0 && "TODO enhanced coupling");

av_log and return

> +                GET_BITS(s->ecplbegf, gbc, 4);
> +                if(s->ecplbegf < 3) {
> +                    s->ecpl_start_subbnd = s->ecplbegf * 2;
> +                }
> +                else if(s->ecplbegf < 13) {
> +                    s->ecpl_start_subbnd = s->ecplbegf + 2;
> +                }
> +                else {
> +                    s->ecpl_start_subbnd = s->ecplbegf * 2 - 10;
> +                }
> +                if (s->spxinu == 0) /* if SPX not in use */
> +                {
> +                    GET_BITS(s->ecplendf, gbc, 4);
> +                    s->ecpl_end_subbnd = s->ecplendf + 7;
> +                }
> +                else /* SPX in use */
> +                {
> +                    if(s->spxbegf < 6) {
> +                        s->ecpl_end_subbnd = s->spxbegf + 5;
> +                    }
> +                    else {
> +                        s->ecpl_end_subbnd = s->spxbegf * 2;
> +                    }
> +                }
> +                GET_BITS(s->ecplbndstrce, gbc, 1);
> +                if (s->ecplbndstrce)
> +                {
> +                    for(sbnd = FFMAX(9, s->ecpl_start_subbnd+1);
> +                            sbnd < s->ecpl_end_subbnd; sbnd++)
> +                    {
> +                        GET_BITS(s->ecplbndstrc[sbnd], gbc, 1);
> +                    }
> +                }
> +                //necplbnd = ecpl_end_subbnd - ecpl_start_subbnd;
> +                //necplbnd -= ecplbndstrc[ecpl_start_subbnd] + ... + ecplbndstrc[ecpl_end_subbnd -1]
> +                // CALC
> +                s->necplbnd = s->ecpl_end_subbnd - s->ecpl_start_subbnd;
> +                for(bnd=s->ecpl_start_subbnd; bnd<s->ecpl_end_subbnd; bnd++){
> +                    s->necplbnd -= s->ecplbndstrc[bnd];
> +                }
> +
> +            } /* ecplinu[blk] */
> +        }
> +        else /* !cplinu[blk] */
> +        {
> +            for(ch = 1; ch <= s->nfchans; ch++)
> +            {
> +                s->chincpl[ch] = 0;
> +                s->firstcplcos[ch] = 1;
> +            }
> +            s->firstcplleak = 1;
> +            s->phsflginu = 0;
> +            s->ecplinu = 0;
> +        }
> +    } /* cplstre[blk] */
> +    /* These fields for coupling coordinates */
> +    if(s->cplinu[blk])
> +    {
> +        assert(0 && "NOT TESTED");

Not needed.  Just put in a comment for now and use av_log and return in 
the enhanced coupling section.  Standard coupling should be okay.

> +        if(s->ecplinu == 0) /* standard coupling in use */
> +        {
> +            for(ch = 1; ch <= s->nfchans; ch++)
> +            {
> +                if(s->chincpl[ch])
> +                {
> +                    if (s->firstcplcos[ch])
> +                    {
> +                        s->cplcoe[ch] = 1;
> +                        s->firstcplcos[ch] = 0;
> +                    }
> +                    else /* !firstcplcos[ch] */ {
> +                        GET_BITS(s->cplcoe[ch], gbc, 1);
> +                    }
> +                    if(s->cplcoe[ch])
> +                    {
> +                        GET_BITS(s->mstrcplco[ch], gbc, 2);
> +                        /* ncplbnd derived from cplbegf, cplendf, and cplbndstrc */
> +                        for(bnd = 0; bnd < s->ncplbnd; bnd++)
> +                        {
> +                            GET_BITS(s->cplcoexp[ch][bnd], gbc, 4);
> +                            GET_BITS(s->cplcomant[ch][bnd], gbc, 4);
> +                        }
> +                    } /* cplcoe[ch] */
> +                }
> +                else /* ! chincpl[ch] */
> +                {
> +                    s->firstcplcos[ch] = 1;
> +                }
> +            } /* ch */
> +            if((s->acmod == 0x2) && s->phsflginu && (s->cplcoe[0] || s->cplcoe[1]))
> +            {
> +                for(bnd = 0; bnd < s->ncplbnd; bnd++) {
> +                    GET_BITS(s->phsflg[bnd], gbc, 1);
> +                }
> +            }
> +        }
> +        else /* enhanced coupling in use */
> +        {
> +            s->firstchincpl = -1;
> +            GET_BITS(s->ecplangleintrp, gbc, 1);
> +            for(ch = 1; ch <= s->nfchans; ch++)
> +            {
> +                if(s->chincpl[ch])
> +                {
> +                    if(s->firstchincpl == -1) {
> +                        s->firstchincpl = ch;
> +                    }
> +                    if(s->firstcplcos[ch])
> +                    {
> +                        s->ecplparam1e[ch] = 1;
> +                        if (ch > s->firstchincpl) {
> +                            s->ecplparam2e[ch] = 1;
> +                        }
> +                        else {
> +                            s->ecplparam2e[ch] = 0;
> +                        }
> +                        s->firstcplcos[ch] = 0;
> +                    }
> +                    else /* !firstcplcos[ch] */
> +                    {
> +                        GET_BITS(s->ecplparam1e[ch], gbc, 1);
> +                        if(ch > s->firstchincpl) {
> +                            GET_BITS(s->ecplparam2e[ch], gbc, 1);
> +                        }
> +                        else {
> +                            s->ecplparam2e[ch] = 0;
> +                        }
> +                    }
> +                    if(s->ecplparam1e[ch])
> +                    {
> +                        /* necplbnd derived from ecpl_start_subbnd, ecpl_end_subbnd, and ecplbndstrc */
> +                        for(bnd = 0; bnd < s->necplbnd; bnd++) {
> +                            GET_BITS(s->ecplamp[ch][bnd], gbc, 5);
> +                        }
> +                    }
> +                    if(s->ecplparam2e[ch])
> +                    {
> +                        /* necplbnd derived from ecpl_start_subbnd, ecpl_end_subbnd, and ecplbndstrc */
> +                        for(bnd = 0; bnd < s->necplbnd; bnd++)
> +                        {
> +                            GET_BITS(s->ecplangle[ch][bnd], gbc, 6);
> +                            GET_BITS(s->ecplchaos[ch][bnd], gbc, 3);
> +                        }
> +                    }
> +                    if(ch > s->firstchincpl) {
> +                        GET_BITS(s->ecpltrans[ch], gbc, 1);
> +                    }
> +                }
> +                else /* !chincpl[ch] */
> +                {
> +                    s->firstcplcos[ch] = 1;
> +                }
> +            } /* ch */
> +        } /* ecplinu[blk] */
> +    } /* cplinu[blk] */
> +    /* These fields for rematrixing operation in the 2/0 mode */
> +    if(s->acmod == 0x2) /* if in 2/0 mode */
> +    {
> +        if (blk == 0) {
> +            s->rematstr = 1;
> +        }
> +        else {
> +            GET_BITS(s->rematstr, gbc, 1);
> +        }
> +        if(s->rematstr)
> +        {
> +            /* nrematbnds determined from cplinu, ecplinu, spxinu, cplbegf, ecplbegf and spxbegf
> +             * TODO: how ? */
> +            assert( 0 && "TODO");

For now, assume enhanced coupling and spectral extension are not used. 
Just base it on standard coupling...but comment it of course so we'll 
know to look here when adding those features later.

> +            for(bnd = 0; bnd < s->nrematbnds; bnd++) {
> +                GET_BITS(s->rematflg[bnd], gbc, 1);
> +            }
> +        }
> +    }
> +    /* This field for channel bandwidth code */
> +    for(ch = 1; ch <= s->nfchans; ch++)
> +    {
> +        assert(blk || s->chexpstr[blk][ch]!=EXP_REUSE);
> +        if(s->chexpstr[blk][ch] != EXP_REUSE)
> +        {
> +            if((!s->chincpl[ch]) && (!s->chinspx[ch])) {
> +                GET_BITS(s->chbwcod[ch], gbc, 6);
> +              if(s->chbwcod[ch] > 60)
> +                  return 1;
> +            }
> +        }
> +    }
> +
> +    // calc
> +    for(ch = 1; ch<=s->nfchans; ch++){
> +        int grpsize = 3 << (s->chexpstr[blk][ch] - 1);
> +
> +        if(s->chincpl[ch])
> +            s->endmant[ch] = s->cplstrtmant; /* channel is coupled */
> +        else
> +            s->endmant[ch] = ((s->chbwcod[ch] + 12) * 3) + 37; /* (ch is not coupled) */
> +
> +        s->nchgrps[ch] = (s->endmant[ch] + grpsize - 4) / grpsize;
> +        assert(s->nchgrps[ch]<AC3_MAX_COEFS);
> +    }
> +
> +    /* These fields for exponents */
> +    if(s->cplinu[blk]) /* exponents for the coupling channel */
> +    {
> +        if(s->cplexpstr[blk] != EXP_REUSE)
> +        {
> +            GET_BITS(s->cplabsexp, gbc, 4);
> +            /* ncplgrps derived from cplbegf, ecplbegf, cplendf, ecplendf, and cplexpstr */
> +            /* how... ? */
> +            assert(0 && "TODO");
> +            for(grp = 0; grp< s->ncplgrps; grp++) {
> +                GET_BITS(s->cplexps[grp], gbc, 7);
> +            }
> +        }
> +    }
> +    for(ch = 1; ch <= s->nfchans; ch++) /* exponents for full bandwidth channels */
> +    {
> +        assert(blk || s->chexpstr[blk][ch] != EXP_REUSE);
> +        if(s->chexpstr[blk][ch] != EXP_REUSE)
> +        {
> +            GET_BITS(s->dexps[ch][0], gbc, 4);
> +
> +            ff_ac3_decode_exponents(gbc, s->chexpstr[blk][ch], s->nchgrps[ch], s->dexps[ch][0],
> +                    s->dexps[ch] + 1);
> +
> +
> +            GET_BITS(s->gainrng[ch], gbc, 2);
> +        }
> +    }
> +    if(s->lfeon) /* exponents for the low frequency effects channel */
> +    {
> +        if(s->lfeexpstr[blk] != EXP_REUSE)
> +        {
> +            ch = s->lfe_channel;
> +            GET_BITS(s->dexps[ch][0], gbc, 4);
> +            s->nlfegrps = 2;
> +            ff_ac3_decode_exponents(gbc, s->lfeexpstr[blk], s->nlfegrps, s->dexps[ch][0],
> +                    s->dexps[ch] + 1);
> +        }
> +    }
> +    /* These fields for bit-allocation parametric information */
> +    if(s->bamode)
> +    {
> +        GET_BITS(s->baie, gbc, 1);
> +        assert(s->baie || blk);
> +        if(s->baie)
> +        {
> +            GET_BITS(s->sdcycod, gbc, 2);
> +            GET_BITS(s->fdcycod, gbc, 2);
> +            GET_BITS(s->sgaincod, gbc, 2);
> +            GET_BITS(s->dbpbcod, gbc, 2);
> +            GET_BITS(s->floorcod, gbc, 3);
> +        }
> +    }
> +    else
> +    {
> +        s->sdcycod = 0x2;
> +        s->fdcycod = 0x1;
> +        s->sgaincod = 0x1;
> +        s->dbpbcod = 0x2;
> +        s->floorcod = 0x7;
> +    }
> +
> +    s->sdecay = ff_sdecaytab[s->sdcycod]; /* Table 7.6 */
> +    s->fdecay = ff_fdecaytab[s->fdcycod];   /* Table 7.7 */
> +    s->sgain = ff_sgaintab[s->sgaincod];  /* Table 7.8 */
> +    s->dbknee = ff_dbkneetab[s->dbpbcod];   /* Table 7.9 */
> +    s->floor = ff_floortab[s->floorcod];  /* Table 7.10 */

align comments

> +
> +    if(s->snroffststr == 0x0)
> +    {
> +        if(s->cplinu[blk]) {
> +            s->cplfsnroffst = s->frmfsnroffst;
> +        }
> +        s->csnroffst = s->frmcsnroffst;
> +        for(ch = 1; ch <= s->nfchans; ch++) {
> +            s->fsnroffst[ch] = s->frmfsnroffst;
> +        }
> +        if(s->lfeon) {
> +            s->lfefsnroffst = s->frmfsnroffst;
> +        }
> +    }
> +    else
> +    {
> +        assert(0 && "NOT TESTED");

Looks simple enough to let it pass with just a comment that this section 
is untested.

> +        if(blk == 0) {
> +            s->snroffste = 1;
> +        }
> +        else {
> +            GET_BITS(s->snroffste, gbc, 1);
> +        }
> +        if(s->snroffste)
> +        {
> +            GET_BITS(s->csnroffst, gbc, 6);
> +            if(s->snroffststr == 0x1)
> +            {
> +                GET_BITS(s->blkfsnroffst, gbc, 4);
> +                s->cplfsnroffst = s->blkfsnroffst;
> +                for(ch = 1; ch <= s->nfchans; ch++) {
> +                    s->fsnroffst[ch] = s->blkfsnroffst;
> +                }
> +                s->lfefsnroffst = s->blkfsnroffst;
> +            }
> +            else if(s->snroffststr == 0x2)
> +            {
> +                if(s->cplinu[blk]) {
> +                    GET_BITS(s->cplfsnroffst, gbc, 4);
> +                }
> +                for(ch = 1; ch <= s->nfchans; ch++) {
> +                    GET_BITS(s->fsnroffst[ch], gbc, 4);
> +                }
> +                if(s->lfeon) {
> +                    GET_BITS(s->lfefsnroffst, gbc, 4);
> +                }
> +            }
> +        }
> +    }
> +
> +    if(s->lfeon){
> +        s->fsnroffst[s->lfe_channel] = s->lfefsnroffst;
> +    }
> +
> +    if(s->frmfgaincode) {
> +        GET_BITS(s->fgaincode, gbc, 1);
> +    }
> +    else {
> +        s->fgaincode = 0;
> +    }
> +    if(s->fgaincode)
> +    {
> +        if(s->cplinu[blk]) {
> +            GET_BITS(s->cplfgaincod, gbc, 3);
> +        }
> +        for(ch = 1; ch <= s->nfchans; ch++) {
> +            GET_BITS(s->fgaincod[ch], gbc, 3);
> +        }
> +        if(s->lfeon) {
> +            GET_BITS(s->lfefgaincod, gbc, 3);
> +        }
> +    }
> +    else
> +    {
> +        if(s->cplinu[blk]) {
> +            s->cplfgaincod = 0x4;
> +        }
> +        for(ch = 1; ch <= s->nfchans; ch++) {
> +            s->fgaincod[ch] = 0x4;
> +        }
> +        if(s->lfeon) {
> +            s->lfefgaincod = 0x4;
> +        }
> +    }
> +    if(s->lfeon){
> +        s->fgaincod[s->lfe_channel] = s->lfefgaincod;
> +    }
> +    if(s->strmtyp == 0x0)
> +    {
> +        GET_BITS(s->convsnroffste, gbc, 1);
> +        if(s->convsnroffste) {
> +            GET_BITS(s->convsnroffst, gbc, 10);
> +        }
> +    }
> +    if(s->cplinu[blk])
> +    {
> +        if (s->firstcplleak)
> +        {
> +            s->cplleake = 1;
> +            s->firstcplleak = 0;
> +        }
> +        else /* !firstcplleak */
> +        {
> +            GET_BITS(s->cplleake, gbc, 1);
> +        }
> +        if(s->cplleake)
> +        {
> +            GET_BITS(s->cplfleak, gbc, 3);
> +            GET_BITS(s->cplsleak, gbc, 3);
> +        }
> +    }
> +    /* These fields for delta bit allocation information */
> +    if(s->dbaflde)
> +    {
> +        assert(0 && "NOT TESTED");

Also simple enough to let it pass with just a comment.

> +        GET_BITS(s->deltbaie, gbc, 1);
> +        if(s->deltbaie)
> +        {
> +            if(s->cplinu[blk]) {
> +                GET_BITS(s->cpldeltbae, gbc, 2);
> +            }
> +            for(ch = 1; ch <= s->nfchans; ch++) {
> +                GET_BITS(s->deltbae[ch], gbc, 2);
> +            }
> +            if(s->cplinu[blk])
> +            {
> +                //TODO
> +                if(s->cpldeltbae==DBA_NEW)
> +                {
> +                    GET_BITS(s->cpldeltnseg, gbc, 3);
> +                    for(seg = 0; seg <= s->cpldeltnseg; seg++)
> +                    {
> +                        GET_BITS(s->cpldeltoffst[seg], gbc, 5);
> +                        GET_BITS(s->cpldeltlen[seg], gbc, 4);
> +                        GET_BITS(s->cpldeltba[seg], gbc, 3);
> +                    }
> +                }
> +            }
> +            for(ch = 1; ch <= s->nfchans; ch++)
> +            {
> +                if(s->deltbae[ch]==DBA_NEW)
> +                {
> +                    GET_BITS(s->deltnseg[ch], gbc, 3);
> +                    for(seg = 0; seg <= s->deltnseg[ch]; seg++)
> +                    {
> +                        GET_BITS(s->deltoffst[ch][seg], gbc, 5);
> +                        GET_BITS(s->deltlen[ch][seg], gbc, 4);
> +                        GET_BITS(s->deltba[ch][seg], gbc, 3);
> +                    }
> +                }
> +            }
> +        } /* if(s->deltbaie) */
> +    }/* if(s->dbaflde) */
> +
> +
> +    /* These fields for inclusion of unused dummy data */
> +    if(s->skipflde)
> +    {
> +        GET_BITS(s->skiple, gbc, 1);
> +        if(s->skiple)
> +        {
> +            GET_BITS(s->skipl, gbc, 9);
> +            // TODO skip :)
> +            for(i=0; i<s->skipl; i++)
> +                GET_BITS(s->skipfld, gbc, 8);
> +        }
> +    }

Just go ahead and skip it, and remove the field from the context.

> +
> +    /* run bit allocation */
> +    if(s->cplinu[blk]) {
> +        assert(0 && "TODO");
> +    }

av_log and return

> +
> +    for(ch = 1; ch<=s->nfchans+s->lfeon; ch++) {
> +        int start=0, end=0;
> +        end = s->endmant[ch];
> +
> +        ff_ac3_bit_alloc_calc_psd((int8_t *)s->dexps[ch], start, end,
> +                s->psd[ch], s->bndpsd[ch]);
> +
> +
> +        // TODO hmm... :)
> +        s->bit_alloc_params.fscod = s->fscod;
> +        s->bit_alloc_params.halfratecod = 0; // TODO
> +        s->bit_alloc_params.sdecay = s->sdecay;
> +        s->bit_alloc_params.fdecay = s->fdecay;
> +        s->bit_alloc_params.sgain = s->sgain;
> +        s->bit_alloc_params.dbknee = s->dbknee;
> +        s->bit_alloc_params.floor = s->floor;
> +        s->bit_alloc_params.cplfleak = s->cplfleak;
> +        s->bit_alloc_params.cplsleak = s->cplsleak;

You should go ahead and read directly to the bit_alloc_params in the 
context and get rid of the copying.  Also, halfratecod is not used in 
E-AC3, so you can take out the TODO comment.  It's a RealAudio extension 
that only applies to regular AC-3.  E-AC3 does allow for lower sample 
rates, but the specs don't indicate that the bit allocation routines are 
altered in any way.

> +
> +        {
> +            int fgain = ff_fgaintab[s->fgaincod[ch]];
> +            if(ch == s->lfe_channel){
> +                s->deltbae[ch] = DBA_NONE;
> +            }
> +            ff_ac3_bit_alloc_calc_mask(&s->bit_alloc_params,
> +                    s->bndpsd[ch], start, end, fgain,
> +                    (ch == s->lfe_channel),
> +                    s->deltbae[ch], s->deltnseg[ch],
> +                    s->deltoffst[ch], s->deltlen[ch],
> +                    s->deltba[ch], s->mask[ch]);
> +        }
> +
> +        {
> +            int snroffst = (((s->csnroffst - 15) << 4) + s->fsnroffst[ch]) << 2;
> +            //av_log(NULL, AV_LOG_INFO, "s->csnroffst=%i s->fsnroffst=%i snroffst = %i\n",
> +             //       s->csnroffst, s->fsnroffst[ch], snroffst);
> +            ff_ac3_bit_alloc_calc_bap(s->mask[ch], s->psd[ch], start, end,
> +                    snroffst, s->bit_alloc_params.floor,
> +                    s->bap[ch]);
> +        }
> +
> +
> +    }

It seems you're not utilizing the speed advantage of the split up bit 
allocation.  So in the meantime, you could simplify the code by using 
ac3_parametric_bit_allocation() instead, and just add a TODO comment 
about speeding up decoding by using the individual bit allocation 
functions only when needed.

> +
> +
> +    /* These fields for quantized mantissa values */

"These fields for" is getting redundant and seems unnecessary.

> +    s->got_cplchan = 0;

should be local variable

> +    ff_ac3_get_transform_coeffs(gbc, s->bap, s->dexps, s->nfchans+s->lfeon, s->chincpl, s->dithflag, s->transform_coeffs, s->strtmant, s->endmant, &s->dith_state);
> +
> +    for(ch = 1; ch <= s->nfchans; ch++)
> +    {
> +        if(s->chahtinu[ch] == 0)
> +        {
> +            // ff_ac3_get_transform
> +        }
> +        else if(s->chahtinu[ch] == 1)
> +        {
> +            assert(0 && "TODO: AHT");

av_log and return

> +            GET_BITS(s->chgaqmod[ch], gbc, 2);
> +            if((s->chgaqmod[ch] > 0x0) && (s->chgaqmod[ch] < 0x3) )
> +            {
> +                for(n = 0; n < s->chgaqsections[ch]; n++) { // TODO chgaqsections ?
> +                    GET_BITS(s->chgaqgain[ch][n], gbc, 1);
> +                }
> +            }
> +            else if(s->chgaqmod[ch] == 0x3)
> +            {
> +                for(n = 0; n < s->chgaqsections[ch]; n++) { //TODO chgaqsections ?
> +                    GET_BITS(s->chgaqgain[ch][n], gbc, 5);
> +                }
> +            }
> +            for(bin = 0; bin < s->nchmant[ch]; bin++) // TODO nchmant ?
> +            {
> +                if(s->chgaqbin[ch][bin]) // TODO chgaqbin ?
> +                {
> +                    for(n = 0; n < 6; n++) {
> +                        GET_BITS(s->pre_chmant[n][ch][bin], gbc, (0-16)); // TODO 0-16 :]
> +                    }
> +                }
> +                else {
> +                    GET_BITS(s->pre_chmant[0][ch][bin], gbc, (0-9)); //  TODO 0-9 :]
> +                }
> +            }
> +            s->chahtinu[ch] = -1; /* AHT info for this frame has been read ? do not read again */
> +        }
> +        if(s->cplinu[blk] && s->chincpl[ch] && !s->got_cplchan)
> +        {
> +            assert(0 && "TODO: CPL");

av_log and return

> +            if(s->cplahtinu == 0)
> +            {
> +                for(bin = 0; bin < s->ncplmant; bin++) { // TODO ncplmant ?
> +                    GET_BITS(s->cplmant[bin], gbc, (0-16)); // TODO 0-16 :]
> +                }
> +                s->got_cplchan = 1;
> +            }
> +            else if(s->cplahtinu == 1)
> +            {
> +                GET_BITS(s->cplgaqmod, gbc, 2);
> +                if((s->cplgaqmod > 0x0) && (s->cplgaqmod < 0x3) )
> +                {
> +                    for(n = 0; n < s->cplgaqsections; n++) { // TODO cplgaqsections?
> +                        GET_BITS(s->cplgaqgain[n], gbc, 1);
> +                    }
> +                }
> +                else if(s->cplgaqmod == 0x3)
> +                {
> +                    for(n = 0; n < s->cplgaqsections; n++) {
> +                        GET_BITS(s->cplgaqgain[n], gbc, 5);
> +                    }
> +                }
> +                for(bin = 0; bin < s->ncplmant; bin++) // TODO ncplmant?
> +                {
> +                    if(s->cplgaqbin[bin])
> +                    {
> +                        for(n = 0; n < 6; n++) {
> +                            GET_BITS(s->pre_cplmant[n][bin], gbc, (0-16)); // TODO 0-16 :]
> +                        }
> +                    }
> +                    else {
> +                        GET_BITS(s->pre_cplmant[0][bin], gbc, (0-9));
> +                    }
> +                }
> +                s->got_cplchan = 1;
> +                s->cplahtinu = -1; /* AHT info for this frame has been read ? do not read again */
> +            }
> +            else {
> +                s->got_cplchan = 1;
> +            }
> +        }
> +    }
> +    if(s->lfeon) /* mantissas of low frequency effects channel */
> +    {
> +        if(s->lfeahtinu == 0)
> +        {
> +            //ff_ac3_get_transform
> +        }
> +        else if(s->lfeahtinu == 1)
> +        {
> +            assert(0 && "TODO: AHT");
> +            GET_BITS(s->lfegaqmod, gbc, 2);
> +            if( (s->lfegaqmod > 0x0) && (s->lfegaqmod < 0x3) )
> +            {
> +                for(n = 0; n < s->lfegaqsections; n++) { // TODO  lfegaqsections?
> +                    GET_BITS(s->lfegaqgain[n], gbc, 1);
> +                }
> +            }
> +            else if(s->lfegaqmod == 0x3)
> +            {
> +                for(n = 0; n < s->lfegaqsections; n++) { // TODO
> +                    GET_BITS(s->lfegaqgain[n], gbc, 5);
> +                }
> +            }
> +            for(bin = 0; bin < s->nlfemant; bin++)
> +            {
> +                if(s->lfegaqbin[bin])
> +                {
> +                    for(n = 0; n < 6; n++) {
> +                        GET_BITS(s->pre_lfemant[n][bin], gbc, (0-16)); // TODO 0-16 :]
> +                    }
> +                }
> +                else {
> +                    GET_BITS(s->pre_lfemant[0][bin], gbc, (0-9)); // TODO 0-9 :]
> +                }
> +            }
> +            s->lfeahtinu = -1; /* AHT info for this frame has been read ? do not read again */
> +        }
> +    }
> +    return 0;
> +}
> +
> +int eac3_parse_auxdata(GetBitContext *gbc, EAC3Context *s){
> +    // TODO
> +    return 0;
> +}

This isn't really needed.  I can't see why we would ever need to parse 
the auxdata.

> Added: eac3/eac3dec.c
> ==============================================================================
> +static void do_imdct_256(EAC3Context *ctx, int ch)
> +{
> +    int k;
> +    float x[128];
> +    FFTComplex z[2][64];
> +    float *o_ptr = ctx->tmp_output;
> +    int i;
> +
> +    for(i=0; i<2; i++) {
> +        /* de-interleave coefficients */
> +        for(k=0; k<128; k++) {
> +            x[k] = ctx->transform_coeffs[ch][2*k+i];
> +        }
> +
> +        /* run standard IMDCT */
> +        ctx->imdct_256.fft.imdct_calc(&ctx->imdct_256, o_ptr, x, ctx->tmp_imdct);
> +
> +        /* reverse the post-rotation & reordering from standard IMDCT */
> +        for(k=0; k<32; k++) {
> +            z[i][32+k].re = -o_ptr[128+2*k];
> +            z[i][32+k].im = -o_ptr[2*k];
> +            z[i][31-k].re =  o_ptr[2*k+1];
> +            z[i][31-k].im =  o_ptr[128+2*k+1];
> +        }
> +    }
> +
> +    /* apply AC-3 post-rotation & reordering */
> +    for(k=0; k<64; k++) {
> +        o_ptr[    2*k  ] = -z[0][   k].im;
> +        o_ptr[    2*k+1] =  z[0][63-k].re;
> +        o_ptr[128+2*k  ] = -z[0][   k].re;
> +        o_ptr[128+2*k+1] =  z[0][63-k].im;
> +        o_ptr[256+2*k  ] = -z[1][   k].re;
> +        o_ptr[256+2*k+1] =  z[1][63-k].im;
> +        o_ptr[384+2*k  ] =  z[1][   k].im;
> +        o_ptr[384+2*k+1] = -z[1][63-k].re;
> +    }
> +}
> +
> +/**
> + * Performs Inverse MDCT transform
> + */
> +void ff_eac3_do_imdct(EAC3Context *ctx)
> +{
> +    int ch;
> +
> +    for(ch=1; ch<=ctx->nfchans+ctx->lfeon; ch++) {
> +        if(ctx->blksw[ch]) {
> +            /* 256-point IMDCT */
> +            do_imdct_256(ctx, ch);
> +        } else {
> +            /* 512-point IMDCT */
> +            ctx->imdct_512.fft.imdct_calc(&ctx->imdct_512, ctx->tmp_output,
> +                                          ctx->transform_coeffs[ch],
> +                                          ctx->tmp_imdct);
> +        }
> +        /* apply window function, overlap/add output, save delay */
> +        ctx->dsp.vector_fmul_add_add(ctx->output[ch], ctx->tmp_output,
> +                                     ctx->window, ctx->delay[ch], 0,
> +                                     AC3_BLOCK_SIZE, 1);
> +        ctx->dsp.vector_fmul_reverse(ctx->delay[ch], ctx->tmp_output+256,
> +                                     ctx->window, AC3_BLOCK_SIZE);
> +    }
> +}

I think the IMDCT functions could be abstracted enough to include them 
in ac3.c/h.  Just pass in the necessary values from the context.

> +
> +static int eac3_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
> +                                            uint8_t *buf, int buf_size){
> +    int16_t *out_samples = (int16_t *)data;
> +    EAC3Context *c = (EAC3Context *)avctx->priv_data;
> +    int k, i, blk, ch;
> +    GetBitContext gbc;
> +
> +    c->gbc = &gbc;
> +    c->syncword = 0;
> +    c->csnroffst  = -1;

Why do you have to initialize c->csnroffst?

> +
> +    init_get_bits(&gbc, buf, buf_size*8);
> +    eac3_parse_syncinfo(&gbc, c);
> +
> +    if(c->syncword != 0x0B77)
> +        return -1;
> +
> +    if(eac3_parse_bsi(&gbc, c) || eac3_parse_audfrm(&gbc, c))
> +        return -1;
> +
> +    if(c->fscod == 3){
> +        assert(c->fscod != 3);

should be:
assert(c->fscod2 != 3);

and actually, I'd rather it be:
if(c->fscod2 != 3)
     return -1

> +        avctx->sample_rate = ff_ac3_freqs[c->fscod2] / 2;
> +    }else{
> +        avctx->sample_rate = ff_ac3_freqs[c->fscod];
> +    }
> +
> +
> +    avctx->bit_rate = (c->frmsiz * (avctx->sample_rate) * 16 / ( ff_eac3_blocks[c->numblkscod] * 256)) / 1000;

break line at 80 chars

> +#ifdef DEBUG
> +    av_log(NULL, AV_LOG_INFO, "bitrate = %i\n", avctx->bit_rate);
> +#endif

AV_LOG_DEBUG instead of #ifdef DEBUG + AV_LOG_INFO



More information about the FFmpeg-soc mailing list