diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2007-08-04 19:19:48 +0000 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2007-08-04 19:19:48 +0000 |
commit | 7b4076a777e7db6c67ae3a0a0213176be159fd5c (patch) | |
tree | 9306a891de0e94538fa5deaf33a97b51055c4845 | |
parent | 365515ac7f04a31afb1bbb7f9e1a7292bacb7605 (diff) | |
download | ffmpeg-7b4076a777e7db6c67ae3a0a0213176be159fd5c.tar.gz |
consolidate decoding of lfe and coupling channels with decoding of full-bandwidth channels.
Originally committed as revision 9910 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/ac3dec.c | 342 |
1 files changed, 138 insertions, 204 deletions
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 63dbbd38cb..be3da8f644 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -85,6 +85,11 @@ static const float clevs[4] = { LEVEL_MINUS_3DB, LEVEL_MINUS_4POINT5DB, static const float slevs[4] = { LEVEL_MINUS_3DB, LEVEL_MINUS_6DB, LEVEL_ZERO, LEVEL_MINUS_6DB }; +/* override ac3.h to include coupling channel */ +#undef AC3_MAX_CHANNELS +#define AC3_MAX_CHANNELS 7 +#define CPL_CH 0 + #define AC3_OUTPUT_LFEON 8 typedef struct { @@ -103,25 +108,14 @@ typedef struct { int rematstr; int nrematbnd; int rematflg[4]; - int cplexpstr; - int lfeexpstr; - int chexpstr[5]; - int cplsnroffst; - int cplfgain; - int snroffst[5]; - int fgain[5]; - int lfesnroffst; - int lfefgain; - int cpldeltbae; - int deltbae[5]; - int cpldeltnseg; - uint8_t cpldeltoffst[8]; - uint8_t cpldeltlen[8]; - uint8_t cpldeltba[8]; - int deltnseg[5]; - uint8_t deltoffst[5][8]; - uint8_t deltlen[5][8]; - uint8_t deltba[5][8]; + int expstr[AC3_MAX_CHANNELS]; + int snroffst[AC3_MAX_CHANNELS]; + int fgain[AC3_MAX_CHANNELS]; + int deltbae[AC3_MAX_CHANNELS]; + int deltnseg[AC3_MAX_CHANNELS]; + uint8_t deltoffst[AC3_MAX_CHANNELS][8]; + uint8_t deltlen[AC3_MAX_CHANNELS][8]; + uint8_t deltba[AC3_MAX_CHANNELS][8]; /* Derived Attributes. */ int sampling_rate; @@ -131,27 +125,25 @@ typedef struct { int nchans; //number of total channels int nfchans; //number of full-bandwidth channels int lfeon; //lfe channel in use + int lfe_ch; ///< index of LFE channel int output_mode; ///< output channel configuration int out_channels; ///< number of output channels float dynrng; //dynamic range gain float dynrng2; //dynamic range gain for 1+1 mode - float cplco[5][18]; //coupling coordinates + float cplco[AC3_MAX_CHANNELS][18]; //coupling coordinates int ncplbnd; //number of coupling bands int ncplsubnd; //number of coupling sub bands - int cplstrtmant; //coupling start mantissa - int cplendmant; //coupling end mantissa - int endmant[5]; //channel end mantissas + int startmant[AC3_MAX_CHANNELS]; ///< start frequency bin + int endmant[AC3_MAX_CHANNELS]; //channel end mantissas AC3BitAllocParameters bit_alloc_params; ///< bit allocation parameters - int8_t dcplexps[256]; //decoded coupling exponents - int8_t dexps[5][256]; //decoded fbw channel exponents - int8_t dlfeexps[256]; //decoded lfe channel exponents - uint8_t cplbap[256]; //coupling bit allocation pointers - uint8_t bap[5][256]; //fbw channel bit allocation pointers - uint8_t lfebap[256]; //lfe channel bit allocation pointers + int8_t dexps[AC3_MAX_CHANNELS][256]; ///< decoded exponents + uint8_t bap[AC3_MAX_CHANNELS][256]; ///< bit allocation pointers + int16_t psd[AC3_MAX_CHANNELS][256]; ///< scaled exponents + int16_t bndpsd[AC3_MAX_CHANNELS][50]; ///< interpolated exponents + int16_t mask[AC3_MAX_CHANNELS][50]; ///< masking curve values - float transform_coeffs_cpl[256]; DECLARE_ALIGNED_16(float, transform_coeffs[AC3_MAX_CHANNELS][256]); //transform coefficients /* For IMDCT. */ @@ -159,8 +151,8 @@ typedef struct { MDCTContext imdct_256; //for 256 sample imdct transform DSPContext dsp; //for optimization - DECLARE_ALIGNED_16(float, output[AC3_MAX_CHANNELS][256]); //output after imdct transform and windowing - DECLARE_ALIGNED_16(float, delay[AC3_MAX_CHANNELS][256]); //delay - added to the next block + DECLARE_ALIGNED_16(float, output[AC3_MAX_CHANNELS-1][256]); //output after imdct transform and windowing + DECLARE_ALIGNED_16(float, delay[AC3_MAX_CHANNELS-1][256]); //delay - added to the next block DECLARE_ALIGNED_16(float, tmp_imdct[256]); //temporary storage for imdct transform DECLARE_ALIGNED_16(float, tmp_output[512]); //temporary storage for output before windowing DECLARE_ALIGNED_16(float, window[256]); //window coefficients @@ -301,6 +293,7 @@ static int ac3_parse_header(AC3DecodeContext *ctx) ctx->bit_rate = hdr.bit_rate; ctx->nchans = hdr.channels; ctx->nfchans = ctx->nchans - ctx->lfeon; + ctx->lfe_ch = ctx->nfchans + 1; ctx->frame_size = hdr.frame_size; /* set default output to all source channels */ @@ -401,14 +394,14 @@ static void uncouple_channels(AC3DecodeContext *ctx) int i, j, ch, bnd, subbnd; subbnd = -1; - i = ctx->cplstrtmant; + i = ctx->startmant[CPL_CH]; for(bnd=0; bnd<ctx->ncplbnd; bnd++) { do { subbnd++; for(j=0; j<12; j++) { for(ch=1; ch<=ctx->nfchans; ch++) { - if(ctx->chincpl[ch-1]) - ctx->transform_coeffs[ch][i] = ctx->transform_coeffs_cpl[i] * ctx->cplco[ch-1][bnd] * 8.0f; + if(ctx->chincpl[ch]) + ctx->transform_coeffs[ch][i] = ctx->transform_coeffs[CPL_CH][i] * ctx->cplco[ch][bnd] * 8.0f; } i++; } @@ -434,25 +427,11 @@ static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_gro uint8_t *bap; float *coeffs; - if (ch_index >= 0) { /* fbw channels */ exps = ctx->dexps[ch_index]; bap = ctx->bap[ch_index]; - coeffs = ctx->transform_coeffs[ch_index + 1]; - start = 0; + coeffs = ctx->transform_coeffs[ch_index]; + start = ctx->startmant[ch_index]; end = ctx->endmant[ch_index]; - } else if (ch_index == -1) { - exps = ctx->dlfeexps; - bap = ctx->lfebap; - coeffs = ctx->transform_coeffs[0]; - start = 0; - end = 7; - } else { - exps = ctx->dcplexps; - bap = ctx->cplbap; - coeffs = ctx->transform_coeffs_cpl; - start = ctx->cplstrtmant; - end = ctx->cplendmant; - } for (i = start; i < end; i++) { @@ -523,20 +502,20 @@ static void remove_dithering(AC3DecodeContext *ctx) { uint8_t *bap; for(ch=1; ch<=ctx->nfchans; ch++) { - if(!ctx->dithflag[ch-1]) { + if(!ctx->dithflag[ch]) { coeffs = ctx->transform_coeffs[ch]; - bap = ctx->bap[ch-1]; - if(ctx->chincpl[ch-1]) - end = ctx->cplstrtmant; + bap = ctx->bap[ch]; + if(ctx->chincpl[ch]) + end = ctx->startmant[CPL_CH]; else - end = ctx->endmant[ch-1]; + end = ctx->endmant[ch]; for(i=0; i<end; i++) { if(bap[i] == 0) coeffs[i] = 0.0f; } - if(ctx->chincpl[ch-1]) { - bap = ctx->cplbap; - for(; i<ctx->cplendmant; i++) { + if(ctx->chincpl[ch]) { + bap = ctx->bap[CPL_CH]; + for(; i<ctx->endmant[CPL_CH]; i++) { if(bap[i] == 0) coeffs[i] = 0.0f; } @@ -551,41 +530,34 @@ static void remove_dithering(AC3DecodeContext *ctx) { */ static int get_transform_coeffs(AC3DecodeContext * ctx) { - int ch, i, end; + int ch, end; int got_cplchan = 0; mant_groups m; m.b1ptr = m.b2ptr = m.b4ptr = 3; - for (ch = 0; ch < ctx->nfchans; ch++) { + for (ch = 1; ch <= ctx->nchans; ch++) { /* transform coefficients for individual channel */ if (get_transform_coeffs_ch(ctx, ch, &m)) return -1; /* tranform coefficients for coupling channels */ if (ctx->chincpl[ch]) { if (!got_cplchan) { - if (get_transform_coeffs_ch(ctx, -2, &m)) { + if (get_transform_coeffs_ch(ctx, CPL_CH, &m)) { av_log(NULL, AV_LOG_ERROR, "error in decoupling channels\n"); return -1; } uncouple_channels(ctx); got_cplchan = 1; } - end = ctx->cplendmant; + end = ctx->endmant[CPL_CH]; } else { end = ctx->endmant[ch]; } do - ctx->transform_coeffs[ch + 1][end] = 0; + ctx->transform_coeffs[ch][end] = 0; while(++end < 256); } - if (ctx->lfeon) { - if (get_transform_coeffs_ch(ctx, -1, &m)) - return -1; - for (i = 7; i < 256; i++) { - ctx->transform_coeffs[0][i] = 0; - } - } /* if any channel doesn't use dithering, zero appropriate coefficients */ if(!ctx->dither_all) @@ -604,7 +576,7 @@ static void do_rematrixing(AC3DecodeContext *ctx) int end, bndend; float tmp0, tmp1; - end = FFMIN(ctx->endmant[0], ctx->endmant[1]); + end = FFMIN(ctx->endmant[1], ctx->endmant[2]); for(bnd=0; bnd<ctx->nrematbnd; bnd++) { if(ctx->rematflg[bnd]) { @@ -664,26 +636,23 @@ static void do_imdct_256(AC3DecodeContext *ctx, int chindex) static inline void do_imdct(AC3DecodeContext *ctx) { int ch; + int nchans; - if (ctx->output_mode & AC3_OUTPUT_LFEON) { - ctx->imdct_512.fft.imdct_calc(&ctx->imdct_512, ctx->tmp_output, - ctx->transform_coeffs[0], ctx->tmp_imdct); - ctx->dsp.vector_fmul_add_add(ctx->output[0], ctx->tmp_output, - ctx->window, ctx->delay[0], 384, 256, 1); - ctx->dsp.vector_fmul_reverse(ctx->delay[0], ctx->tmp_output+256, - ctx->window, 256); - } - for (ch=1; ch<=ctx->nfchans; ch++) { - if (ctx->blksw[ch-1]) { + nchans = ctx->nfchans; + if(ctx->output_mode & AC3_OUTPUT_LFEON) + nchans++; + + for (ch=1; ch<=nchans; ch++) { + if (ctx->blksw[ch]) { do_imdct_256(ctx, ch); } else { ctx->imdct_512.fft.imdct_calc(&ctx->imdct_512, ctx->tmp_output, ctx->transform_coeffs[ch], ctx->tmp_imdct); } - ctx->dsp.vector_fmul_add_add(ctx->output[ch], ctx->tmp_output, - ctx->window, ctx->delay[ch], 384, 256, 1); - ctx->dsp.vector_fmul_reverse(ctx->delay[ch], ctx->tmp_output+256, + ctx->dsp.vector_fmul_add_add(ctx->output[ch-1], ctx->tmp_output, + ctx->window, ctx->delay[ch-1], 384, 256, 1); + ctx->dsp.vector_fmul_reverse(ctx->delay[ch-1], ctx->tmp_output+256, ctx->window, 256); } } @@ -699,13 +668,15 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk) int acmod = ctx->acmod; int i, bnd, seg, ch; GetBitContext *gb = &ctx->gb; - int bit_alloc_flags = 0; + uint8_t bit_alloc_stages[AC3_MAX_CHANNELS]; - for (ch = 0; ch < nfchans; ch++) /*block switch flag */ + memset(bit_alloc_stages, 0, AC3_MAX_CHANNELS); + + for (ch = 1; ch <= nfchans; ch++) /*block switch flag */ ctx->blksw[ch] = get_bits1(gb); ctx->dither_all = 1; - for (ch = 0; ch < nfchans; ch++) { /* dithering flag */ + for (ch = 1; ch <= nfchans; ch++) { /* dithering flag */ ctx->dithflag[ch] = get_bits1(gb); if(!ctx->dithflag[ch]) ctx->dither_all = 0; @@ -726,11 +697,12 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk) } if (get_bits1(gb)) { /* coupling strategy */ + memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); ctx->cplinu = get_bits1(gb); if (ctx->cplinu) { /* coupling in use */ int cplbegf, cplendf; - for (ch = 0; ch < nfchans; ch++) + for (ch = 1; ch <= nfchans; ch++) ctx->chincpl[ch] = get_bits1(gb); if (acmod == AC3_ACMOD_STEREO) @@ -745,8 +717,8 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk) } ctx->ncplbnd = ctx->ncplsubnd = 3 + cplendf - cplbegf; - ctx->cplstrtmant = cplbegf * 12 + 37; - ctx->cplendmant = cplendf * 12 + 73; + ctx->startmant[CPL_CH] = cplbegf * 12 + 37; + ctx->endmant[CPL_CH] = cplendf * 12 + 73; for (bnd = 0; bnd < ctx->ncplsubnd - 1; bnd++) { /* coupling band structure */ if (get_bits1(gb)) { ctx->cplbndstrc[bnd] = 1; @@ -754,7 +726,7 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk) } } } else { - for (ch = 0; ch < nfchans; ch++) + for (ch = 1; ch <= nfchans; ch++) ctx->chincpl[ch] = 0; } } @@ -762,7 +734,7 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk) if (ctx->cplinu) { int cplcoe = 0; - for (ch = 0; ch < nfchans; ch++) { + for (ch = 1; ch <= nfchans; ch++) { if (ctx->chincpl[ch]) { if (get_bits1(gb)) { /* coupling co-ordinates */ int mstrcplco, cplcoexp, cplcomant; @@ -784,7 +756,7 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk) if (acmod == AC3_ACMOD_STEREO && ctx->phsflginu && cplcoe) { for (bnd = 0; bnd < ctx->ncplbnd; bnd++) { if (get_bits1(gb)) - ctx->cplco[1][bnd] = -ctx->cplco[1][bnd]; + ctx->cplco[2][bnd] = -ctx->cplco[2][bnd]; } } } @@ -793,26 +765,30 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk) ctx->rematstr = get_bits1(gb); if (ctx->rematstr) { ctx->nrematbnd = 4; - if(ctx->cplinu && ctx->cplstrtmant <= 61) - ctx->nrematbnd -= 1 + (ctx->cplstrtmant == 37); + if(ctx->cplinu && ctx->startmant[CPL_CH] <= 61) + ctx->nrematbnd -= 1 + (ctx->startmant[CPL_CH] == 37); for(bnd=0; bnd<ctx->nrematbnd; bnd++) ctx->rematflg[bnd] = get_bits1(gb); } } - ctx->cplexpstr = EXP_REUSE; - ctx->lfeexpstr = EXP_REUSE; - if (ctx->cplinu) /* coupling exponent strategy */ - ctx->cplexpstr = get_bits(gb, 2); - for (ch = 0; ch < nfchans; ch++) /* channel exponent strategy */ - ctx->chexpstr[ch] = get_bits(gb, 2); - if (ctx->lfeon) /* lfe exponent strategy */ - ctx->lfeexpstr = get_bits1(gb); - - for (ch = 0; ch < nfchans; ch++) { /* channel bandwidth code */ - if (ctx->chexpstr[ch] != EXP_REUSE) { + ctx->expstr[CPL_CH] = EXP_REUSE; + ctx->expstr[ctx->lfe_ch] = EXP_REUSE; + for (ch = !ctx->cplinu; ch <= ctx->nchans; ch++) { + if(ch == ctx->lfe_ch) + ctx->expstr[ch] = get_bits(gb, 1); + else + ctx->expstr[ch] = get_bits(gb, 2); + if(ctx->expstr[ch] != EXP_REUSE) + bit_alloc_stages[ch] = 3; + } + + for (ch = 1; ch <= nfchans; ch++) { /* channel bandwidth code */ + ctx->startmant[ch] = 0; + if (ctx->expstr[ch] != EXP_REUSE) { + int prev = ctx->endmant[ch]; if (ctx->chincpl[ch]) - ctx->endmant[ch] = ctx->cplstrtmant; + ctx->endmant[ch] = ctx->startmant[CPL_CH]; else { int chbwcod = get_bits(gb, 6); if (chbwcod > 60) { @@ -821,102 +797,69 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk) } ctx->endmant[ch] = chbwcod * 3 + 73; } + if(blk > 0 && ctx->endmant[ch] != prev) + memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); } } - - if (ctx->cplexpstr != EXP_REUSE) {/* coupling exponents */ - int grpsize, ngrps, absexp; - bit_alloc_flags = 64; - grpsize = 3 << (ctx->cplexpstr - 1); - ngrps = (ctx->cplendmant - ctx->cplstrtmant) / grpsize; - absexp = get_bits(gb, 4) << 1; - decode_exponents(gb, ctx->cplexpstr, ngrps, absexp, &ctx->dcplexps[ctx->cplstrtmant]); - } - - for (ch = 0; ch < nfchans; ch++) { /* fbw channel exponents */ - if (ctx->chexpstr[ch] != EXP_REUSE) { - int grpsize, ngrps, absexp; - bit_alloc_flags |= 1 << ch; - grpsize = 3 << (ctx->chexpstr[ch] - 1); + ctx->startmant[ctx->lfe_ch] = 0; + ctx->endmant[ctx->lfe_ch] = 7; + + for (ch = !ctx->cplinu; ch <= ctx->nchans; ch++) { + if (ctx->expstr[ch] != EXP_REUSE) { + int grpsize, ngrps; + grpsize = 3 << (ctx->expstr[ch] - 1); + if(ch == CPL_CH) + ngrps = (ctx->endmant[ch] - ctx->startmant[ch]) / grpsize; + else if(ch == ctx->lfe_ch) + ngrps = 2; + else ngrps = (ctx->endmant[ch] + grpsize - 4) / grpsize; - absexp = ctx->dexps[ch][0] = get_bits(gb, 4); - decode_exponents(gb, ctx->chexpstr[ch], ngrps, absexp, &ctx->dexps[ch][1]); + ctx->dexps[ch][0] = get_bits(gb, 4) << !ch; + decode_exponents(gb, ctx->expstr[ch], ngrps, ctx->dexps[ch][0], + &ctx->dexps[ch][ctx->startmant[ch]+!!ch]); + if(ch != CPL_CH && ch != ctx->lfe_ch) skip_bits(gb, 2); /* skip gainrng */ } } - if (ctx->lfeexpstr != EXP_REUSE) { /* lfe exponents */ - int ngrps, absexp; - bit_alloc_flags |= 32; - ngrps = 2; - absexp = ctx->dlfeexps[0] = get_bits(gb, 4); - decode_exponents(gb, ctx->lfeexpstr, ngrps, absexp, &ctx->dlfeexps[1]); - } - if (get_bits1(gb)) { /* bit allocation information */ - bit_alloc_flags = 127; ctx->bit_alloc_params.sdecay = ff_sdecaytab[get_bits(gb, 2)]; ctx->bit_alloc_params.fdecay = ff_fdecaytab[get_bits(gb, 2)]; ctx->bit_alloc_params.sgain = ff_sgaintab[get_bits(gb, 2)]; ctx->bit_alloc_params.dbknee = ff_dbkneetab[get_bits(gb, 2)]; ctx->bit_alloc_params.floor = ff_floortab[get_bits(gb, 3)]; + for(ch=!ctx->cplinu; ch<=ctx->nchans; ch++) { + bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); + } } if (get_bits1(gb)) { /* snroffset */ int csnr; - bit_alloc_flags = 127; csnr = (get_bits(gb, 6) - 15) << 4; - if (ctx->cplinu) { /* coupling fine snr offset and fast gain code */ - ctx->cplsnroffst = (csnr + get_bits(gb, 4)) << 2; - ctx->cplfgain = ff_fgaintab[get_bits(gb, 3)]; - } - for (ch = 0; ch < nfchans; ch++) { /* channel fine snr offset and fast gain code */ + for (ch = !ctx->cplinu; ch <= ctx->nchans; ch++) { /* snr offset and fast gain */ ctx->snroffst[ch] = (csnr + get_bits(gb, 4)) << 2; ctx->fgain[ch] = ff_fgaintab[get_bits(gb, 3)]; } - if (ctx->lfeon) { /* lfe fine snr offset and fast gain code */ - ctx->lfesnroffst = (csnr + get_bits(gb, 4)) << 2; - ctx->lfefgain = ff_fgaintab[get_bits(gb, 3)]; - } + memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); } if (ctx->cplinu && get_bits1(gb)) { /* coupling leak information */ - bit_alloc_flags |= 64; ctx->bit_alloc_params.cplfleak = get_bits(gb, 3); ctx->bit_alloc_params.cplsleak = get_bits(gb, 3); + bit_alloc_stages[CPL_CH] = FFMAX(bit_alloc_stages[CPL_CH], 2); } if (get_bits1(gb)) { /* delta bit allocation information */ - bit_alloc_flags = 127; - - if (ctx->cplinu) { - ctx->cpldeltbae = get_bits(gb, 2); - if (ctx->cpldeltbae == DBA_RESERVED) { - av_log(NULL, AV_LOG_ERROR, "coupling delta bit allocation strategy reserved\n"); - return -1; - } - } - - for (ch = 0; ch < nfchans; ch++) { + for (ch = !ctx->cplinu; ch <= nfchans; ch++) { ctx->deltbae[ch] = get_bits(gb, 2); if (ctx->deltbae[ch] == DBA_RESERVED) { av_log(NULL, AV_LOG_ERROR, "delta bit allocation strategy reserved\n"); return -1; } + bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); } - if (ctx->cplinu) { - if (ctx->cpldeltbae == DBA_NEW) { /*coupling delta offset, len and bit allocation */ - ctx->cpldeltnseg = get_bits(gb, 3); - for (seg = 0; seg <= ctx->cpldeltnseg; seg++) { - ctx->cpldeltoffst[seg] = get_bits(gb, 5); - ctx->cpldeltlen[seg] = get_bits(gb, 4); - ctx->cpldeltba[seg] = get_bits(gb, 3); - } - } - } - - for (ch = 0; ch < nfchans; ch++) { + for (ch = !ctx->cplinu; ch <= nfchans; ch++) { if (ctx->deltbae[ch] == DBA_NEW) {/*channel delta offset, len and bit allocation */ ctx->deltnseg[ch] = get_bits(gb, 3); for (seg = 0; seg <= ctx->deltnseg[ch]; seg++) { @@ -927,38 +870,35 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk) } } } else if(blk == 0) { - if(ctx->cplinu) - ctx->cpldeltbae = DBA_NONE; - for(ch=0; ch<nfchans; ch++) { + for(ch=0; ch<=ctx->nchans; ch++) { ctx->deltbae[ch] = DBA_NONE; } } - if (bit_alloc_flags) { - if (ctx->cplinu && (bit_alloc_flags & 64)) { - ac3_parametric_bit_allocation(&ctx->bit_alloc_params, ctx->cplbap, - ctx->dcplexps, ctx->cplstrtmant, - ctx->cplendmant, ctx->cplsnroffst, - ctx->cplfgain, 0, - ctx->cpldeltbae, ctx->cpldeltnseg, - ctx->cpldeltoffst, ctx->cpldeltlen, - ctx->cpldeltba); + for(ch=!ctx->cplinu; ch<=ctx->nchans; ch++) { + if(bit_alloc_stages[ch] > 2) { + /* Exponent mapping into PSD and PSD integration */ + ff_ac3_bit_alloc_calc_psd(ctx->dexps[ch], + ctx->startmant[ch], ctx->endmant[ch], + ctx->psd[ch], ctx->bndpsd[ch]); } - for (ch = 0; ch < nfchans; ch++) { - if ((bit_alloc_flags >> ch) & 1) { - ac3_parametric_bit_allocation(&ctx->bit_alloc_params, - ctx->bap[ch], ctx->dexps[ch], 0, - ctx->endmant[ch], ctx->snroffst[ch], - ctx->fgain[ch], 0, ctx->deltbae[ch], - ctx->deltnseg[ch], ctx->deltoffst[ch], - ctx->deltlen[ch], ctx->deltba[ch]); - } + if(bit_alloc_stages[ch] > 1) { + /* Compute excitation function, Compute masking curve, and + Apply delta bit allocation */ + ff_ac3_bit_alloc_calc_mask(&ctx->bit_alloc_params, ctx->bndpsd[ch], + ctx->startmant[ch], ctx->endmant[ch], + ctx->fgain[ch], (ch == ctx->lfe_ch), + ctx->deltbae[ch], ctx->deltnseg[ch], + ctx->deltoffst[ch], ctx->deltlen[ch], + ctx->deltba[ch], ctx->mask[ch]); } - if (ctx->lfeon && (bit_alloc_flags & 32)) { - ac3_parametric_bit_allocation(&ctx->bit_alloc_params, ctx->lfebap, - ctx->dlfeexps, 0, 7, ctx->lfesnroffst, - ctx->lfefgain, 1, - DBA_NONE, 0, NULL, NULL, NULL); + if(bit_alloc_stages[ch] > 0) { + /* Compute bit allocation */ + ff_ac3_bit_alloc_calc_bap(ctx->mask[ch], ctx->psd[ch], + ctx->startmant[ch], ctx->endmant[ch], + ctx->snroffst[ch], + ctx->bit_alloc_params.floor, + ctx->bap[ch]); } } @@ -980,19 +920,14 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk) do_rematrixing(ctx); /* apply scaling to coefficients (headroom, dynrng) */ - if(ctx->lfeon) { - for(i=0; i<7; i++) { - ctx->transform_coeffs[0][i] *= 2.0f * ctx->dynrng; - } - } - for(ch=1; ch<=ctx->nfchans; ch++) { + for(ch=1; ch<=ctx->nchans; ch++) { float gain = 2.0f; if(ctx->acmod == AC3_ACMOD_DUALMONO && ch == 2) { gain *= ctx->dynrng2; } else { gain *= ctx->dynrng; } - for(i=0; i<ctx->endmant[ch-1]; i++) { + for(i=0; i<ctx->endmant[ch]; i++) { ctx->transform_coeffs[ch][i] *= gain; } } @@ -1024,7 +959,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, { AC3DecodeContext *ctx = (AC3DecodeContext *)avctx->priv_data; int16_t *out_samples = (int16_t *)data; - int i, blk, ch, start; + int i, blk, ch; int32_t *int_ptr[6]; for (ch = 0; ch < 6; ch++) @@ -1062,9 +997,8 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, *data_size = 0; return ctx->frame_size; } - start = (ctx->output_mode & AC3_OUTPUT_LFEON) ? 0 : 1; for (i = 0; i < 256; i++) - for (ch = start; ch <= ctx->nfchans; ch++) + for (ch = 0; ch < ctx->out_channels; ch++) *(out_samples++) = convert(int_ptr[ch][i]); } *data_size = NB_BLOCKS * 256 * avctx->channels * sizeof (int16_t); |