aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustin Ruggles <justin.ruggles@gmail.com>2007-08-04 19:19:48 +0000
committerJustin Ruggles <justin.ruggles@gmail.com>2007-08-04 19:19:48 +0000
commit7b4076a777e7db6c67ae3a0a0213176be159fd5c (patch)
tree9306a891de0e94538fa5deaf33a97b51055c4845
parent365515ac7f04a31afb1bbb7f9e1a7292bacb7605 (diff)
downloadffmpeg-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.c342
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);