Mercurial > libavcodec.hg
changeset 5305:5892b4a6380b libavcodec
AC-3 decoder, soc revision 31, Jul 14 23:53:28 2006 UTC by cloud9
Removed _ from names
Removed temporary storage for the exponents
Removed ctx->samples
Now each transform coefficients are stored in audio block as an array of transform coefficients for each channel
added ctx->delay (output of later half of previous block)
added audio_block->block_output(output of this block)
I am still not able to produce the output.
I checked the code twice completely. I am not missing anything in
parsing or in bit allocation. Yet it throws error in getting transform
coefficients sometimes. Can anyone review a code of get_transform_coeffs and
help me debug it further. I think the error is in do_bit_allocation routine cuz
get_transform_coeffs is dependent on the bit allocation parameters table.
I have checked the bit allocation algorithm thoroughly and it is as defined in the
standard. Tried everything and got stuck where to go further.
Please help me.
author | jbr |
---|---|
date | Sat, 14 Jul 2007 15:42:15 +0000 |
parents | eff51058fe13 |
children | abc5c130b448 |
files | ac3dec.c |
diffstat | 1 files changed, 478 insertions(+), 434 deletions(-) [+] |
line wrap: on
line diff
--- a/ac3dec.c Sat Jul 14 15:41:27 2007 +0000 +++ b/ac3dec.c Sat Jul 14 15:42:15 2007 +0000 @@ -34,6 +34,10 @@ #include "avutil.h" #include "common.h" +#define MAX_CHANNELS 6 +#define MAX_BLOCK_SIZE 256 +#define MAX_BLOCKS 6 + /* Synchronization information. */ typedef struct { uint16_t sync_word; //synchronization word = always 0x0b77 @@ -44,6 +48,7 @@ /* Derived Attributes */ int sampling_rate; //sampling rate - 48, 44.1 or 32 kHz (value in Hz) int bit_rate; //nominal bit rate (value in kbps) + int framesize; //frame size - 16 bit words } ac3_sync_info; /* flags for the BSI. */ @@ -146,10 +151,7 @@ uint8_t lfeexpstr; //lfe exponent strategy uint8_t chbwcod[5]; //channel bandwdith code for channels in use uint8_t cplabsexp; //coupling absolute exponent - uint8_t cplexps[72]; //coupling exponents - uint8_t exps[5][88]; //channel exponents uint8_t gainrng[5]; //gain range - uint8_t lfeexps[3]; //LFE exponents uint8_t sdcycod; //slow decay code uint8_t fdcycod; //fast decay code uint8_t sgaincod; //slow gain code @@ -196,8 +198,10 @@ uint8_t bap[5][256]; //fbw channels bit allocation parameters table uint8_t lfebap[256]; //lfe bit allocaiton parameters table - float cplcoeffs[256]; //temporary storage for coupling transform coefficients - float cplco[5][18]; //coupling co-ordinates + DECLARE_ALIGNED_16(float, transform_coeffs[MAX_CHANNELS][MAX_BLOCK_SIZE]); //transform coefficients + DECLARE_ALIGNED_16(float, cplcoeffs[256]); //temporary storage for coupling transform coefficients + DECLARE_ALIGNED_16(float, block_output[MAX_CHANNELS][MAX_BLOCK_SIZE]); + float cplco[5][18]; //coupling coordinates float chcoeffs[6]; //channel coefficients for downmix } ac3_audio_block; @@ -281,28 +285,41 @@ ac3_sync_info sync_info; ac3_bsi bsi; ac3_audio_block audio_block; - float *samples; - int output; dither_state state; MDCTContext imdct_ctx_256; MDCTContext imdct_ctx_512; GetBitContext gb; + int output; + DECLARE_ALIGNED_16(float, delay[MAX_CHANNELS][MAX_BLOCK_SIZE]); + DECLARE_ALIGNED_16(FFTSample, tmp_imdct[MAX_BLOCK_SIZE * 2]); + DECLARE_ALIGNED_16(FFTSample, tmp_output[MAX_BLOCK_SIZE * 2]); } AC3DecodeContext; +static void ac3_common_init1(void) +{ + int i, j, k, l, v; + /* compute bndtab and masktab from bandsz */ + k = 0; + l = 0; + for(i=0;i<50;i++) { + bndtab[i] = l; + v = bndsz[i]; + for(j=0;j<v;j++) masktab[k++]=i; + l += v; + } + masktab[253] = masktab[254] = masktab[255] = 0; + bndtab[50] = 0; +} + static int ac3_decode_init(AVCodecContext *avctx) { AC3DecodeContext *ctx = avctx->priv_data; - ac3_common_init(); + ac3_common_init1(); ff_mdct_init(&ctx->imdct_ctx_256, 8, 1); ff_mdct_init(&ctx->imdct_ctx_512, 9, 1); - ctx->samples = av_mallocz(6 * 256 * sizeof (float)); - if (!ctx->samples) { - av_log(avctx, AV_LOG_ERROR, "Cannot allocate memory for samples\n"); - return -1; - } dither_seed(&ctx->state, 0); return 0; @@ -323,19 +340,39 @@ static int ac3_parse_sync_info(AC3DecodeContext *ctx) { ac3_sync_info *sync_info = &ctx->sync_info; + ac3_bsi *bsi = &ctx->bsi; GetBitContext *gb = &ctx->gb; sync_info->sync_word = get_bits(gb, 16); sync_info->crc1 = get_bits(gb, 16); sync_info->fscod = get_bits(gb, 2); if (sync_info->fscod == 0x03) - return -1; + return 0; sync_info->frmsizecod = get_bits(gb, 6); - if (sync_info->frmsizecod >= 0x38) - return -1; + if (sync_info->frmsizecod >= 38) + return 0; sync_info->sampling_rate = ac3_freqs[sync_info->fscod]; sync_info->bit_rate = ac3_bitratetab[sync_info->frmsizecod >> 1]; + /* we include it here in order to determine validity of ac3 frame */ + bsi->bsid = get_bits(gb, 5); + if (bsi->bsid > 0x08) + return 0; + bsi->bsmod = get_bits(gb, 3); + + switch (sync_info->fscod) { + case 0x00: + sync_info->framesize = 4 * sync_info->bit_rate; + return sync_info->framesize; + case 0x01: + sync_info->framesize = 2 * (320 * sync_info->bit_rate / 147 + (sync_info->frmsizecod & 1)); + return sync_info->framesize; + case 0x02: + sync_info->framesize = 6 * sync_info->bit_rate; + return sync_info->framesize; + } + + /* never reached */ return 0; } @@ -345,16 +382,19 @@ ac3_bsi *bsi = &ctx->bsi; uint32_t *flags = &bsi->flags; GetBitContext *gb = &ctx->gb; + int i; *flags = 0; bsi->cmixlev = 0; bsi->surmixlev = 0; bsi->dsurmod = 0; + ctx->audio_block.cpldeltbae = AC3_DBASTR_NONE; + ctx->audio_block.cpldeltnseg = 0; + for (i = 0; i < 5; i++) { + ctx->audio_block.deltbae[i] = AC3_DBASTR_NONE; + ctx->audio_block.deltnseg[i] = 0; + } - bsi->bsid = get_bits(gb, 5); - if (bsi->bsid > 0x08) - return -1; - bsi->bsmod = get_bits(gb, 3); bsi->acmod = get_bits(gb, 3); if (bsi->acmod & 0x01 && bsi->acmod != 0x01) bsi->cmixlev = get_bits(gb, 2); @@ -362,56 +402,55 @@ bsi->surmixlev = get_bits(gb, 2); if (bsi->acmod == 0x02) bsi->dsurmod = get_bits(gb, 2); - if (get_bits(gb, 1)) + if (get_bits1(gb)) *flags |= AC3_BSI_LFEON; bsi->dialnorm = get_bits(gb, 5); - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { *flags |= AC3_BSI_COMPRE; - bsi->compr = get_bits(gb, 5); + bsi->compr = get_bits(gb, 8); } - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { *flags |= AC3_BSI_LANGCODE; bsi->langcod = get_bits(gb, 8); } - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { *flags |= AC3_BSI_AUDPRODIE; bsi->mixlevel = get_bits(gb, 5); bsi->roomtyp = get_bits(gb, 2); } if (bsi->acmod == 0x00) { bsi->dialnorm2 = get_bits(gb, 5); - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { *flags |= AC3_BSI_COMPR2E; - bsi->compr2 = get_bits(gb, 5); + bsi->compr2 = get_bits(gb, 8); } - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { *flags |= AC3_BSI_LANGCOD2E; bsi->langcod2 = get_bits(gb, 8); } - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { *flags |= AC3_BSI_AUDPRODIE; bsi->mixlevel2 = get_bits(gb, 5); bsi->roomtyp2 = get_bits(gb, 2); } } - if (get_bits(gb, 1)) + if (get_bits1(gb)) *flags |= AC3_BSI_COPYRIGHTB; - if (get_bits(gb, 1)) + if (get_bits1(gb)) *flags |= AC3_BSI_ORIGBS; - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { *flags |= AC3_BSI_TIMECOD1E; bsi->timecod1 = get_bits(gb, 14); } - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { *flags |= AC3_BSI_TIMECOD2E; bsi->timecod2 = get_bits(gb, 14); } - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { *flags |= AC3_BSI_ADDBSIE; bsi->addbsil = get_bits(gb, 6); - do { - get_bits(gb, 8); - } while (bsi->addbsil--); + for (i = 0; i < (bsi->addbsil + 1); i++) + skip_bits(gb, 8); } bsi->nfchans = nfchans_tbl[bsi->acmod]; @@ -419,21 +458,23 @@ return 0; } - /* Decodes the grouped exponents (gexps) and stores them + /* Decodes the grouped exponents and stores them * in decoded exponents (dexps). * The code is derived from liba52. * Uses liba52 tables. */ -static int _decode_exponents(int expstr, int ngrps, uint8_t absexp, uint8_t *gexps, uint8_t *dexps) +static int decode_exponents(GetBitContext *gb, int expstr, int ngrps, uint8_t absexp, uint8_t *dexps) { int exps; - int i = 0; while (ngrps--) { - exps = gexps[i++]; + exps = get_bits(gb, 7); absexp += exp_1[exps]; - assert(absexp <= 24); + if (absexp > 24) { + av_log(NULL, AV_LOG_ERROR, "Absolute Exponent > 24, ngrp = %d\n", ngrps); + return -ngrps; + } switch (expstr) { case AC3_EXPSTR_D45: *(dexps++) = absexp; @@ -443,8 +484,12 @@ case AC3_EXPSTR_D15: *(dexps++) = absexp; } + absexp += exp_2[exps]; - assert(absexp <= 24); + if (absexp > 24) { + av_log(NULL, AV_LOG_ERROR, "Absolute Exponent > 24, ngrp = %d\n", ngrps); + return -ngrps; + } switch (expstr) { case AC3_EXPSTR_D45: *(dexps++) = absexp; @@ -456,7 +501,10 @@ } absexp += exp_3[exps]; - assert(absexp <= 24); + if (absexp > 24) { + av_log(NULL, AV_LOG_ERROR, "Absolute Exponent > 24, ngrp = %d\n", ngrps); + return -ngrps; + } switch (expstr) { case AC3_EXPSTR_D45: *(dexps++) = absexp; @@ -471,39 +519,20 @@ return 0; } -static int decode_exponents(AC3DecodeContext *ctx) +static inline int logadd(int a, int b) { - ac3_audio_block *ab = &ctx->audio_block; - int i; - uint8_t *exps; - uint8_t *dexps; + int c = a - b; + int address; - if (ab->flags & AC3_AB_CPLINU && ab->cplexpstr != AC3_EXPSTR_REUSE) - if (_decode_exponents(ab->cplexpstr, ab->ncplgrps, ab->cplabsexp, - ab->cplexps, ab->dcplexps + ab->cplstrtmant)) - return -1; - for (i = 0; i < ctx->bsi.nfchans; i++) - if (ab->chexpstr[i] != AC3_EXPSTR_REUSE) { - exps = ab->exps[i]; - dexps = ab->dexps[i]; - if (_decode_exponents(ab->chexpstr[i], ab->nchgrps[i], exps[0], exps + 1, dexps + 1)) - return -1; - } - if (ctx->bsi.flags & AC3_BSI_LFEON && ab->lfeexpstr != AC3_EXPSTR_REUSE) - if (_decode_exponents(ab->lfeexpstr, 2, ab->lfeexps[0], ab->lfeexps + 1, ab->dlfeexps)) - return -1; - return 0; + address = FFMIN(ABS(c) >> 1, 255); + + if (c >= 0) + return (a + latab[address]); + else + return (b + latab[address]); } -static inline int16_t logadd(int16_t a, int16_t b) -{ - int16_t c = a - b; - uint8_t address = FFMIN((ABS(c) >> 1), 255); - - return ((c >= 0) ? (a + latab[address]) : (b + latab[address])); -} - -static inline int16_t calc_lowcomp(int16_t a, int16_t b0, int16_t b1, uint8_t bin) +static inline int calc_lowcomp(int a, int b0, int b1, int bin) { if (bin < 7) { if ((b0 + 256) == b1) @@ -517,9 +546,8 @@ else if (b0 > b1) a = FFMAX(0, a - 64); } - else { + else a = FFMAX(0, a - 128); - } return a; } @@ -529,15 +557,16 @@ * chnl = 5 coupling channel * chnl = 6 lfe channel */ -static int _do_bit_allocation(AC3DecodeContext *ctx, int chnl) +static void do_bit_allocation1(AC3DecodeContext *ctx, int chnl) { ac3_audio_block *ab = &ctx->audio_block; - int16_t sdecay, fdecay, sgain, dbknee, floor; - int16_t lowcomp, fgain, snroffset, fastleak, slowleak; - int16_t psd[256], bndpsd[50], excite[50], mask[50], delta; - uint8_t start, end, bin, i, j, k, lastbin, bndstrt, bndend, begin, deltnseg, band, seg, address; - uint8_t fscod = ctx->sync_info.fscod; - uint8_t *exps, *deltoffst, *deltlen, *deltba; + int sdecay, fdecay, sgain, dbknee, floor; + int lowcomp = 0, fgain = 0, snroffset = 0, fastleak = 0, slowleak = 0; + int psd[256], bndpsd[50], excite[50], mask[50], delta; + int start = 0, end = 0, bin = 0, i = 0, j = 0, k = 0, lastbin = 0, bndstrt = 0; + int bndend = 0, begin = 0, deltnseg = 0, band = 0, seg = 0, address = 0; + int fscod = ctx->sync_info.fscod; + uint8_t *exps, *deltoffst = 0, *deltlen = 0, *deltba = 0; uint8_t *baps; int do_delta = 0; @@ -557,7 +586,7 @@ slowleak = (ab->cplsleak << 8) + 768; exps = ab->dcplexps; baps = ab->cplbap; - if (ab->cpldeltbae == 0 || ab->cpldeltbae == 1) { + if (ab->cpldeltbae == AC3_DBASTR_NEW || ab->cpldeltbae == AC3_DBASTR_REUSE) { do_delta = 1; deltnseg = ab->cpldeltnseg; deltoffst = ab->cpldeltoffst; @@ -569,6 +598,8 @@ start = 0; end = 7; lowcomp = 0; + fastleak = 0; + slowleak = 0; fgain = fgaintab[ab->lfefgaincod]; snroffset = (((ab->csnroffst - 15) << 4) + ab->lfefsnroffst) << 2; exps = ab->dlfeexps; @@ -578,11 +609,13 @@ start = 0; end = ab->endmant[chnl]; lowcomp = 0; + fastleak = 0; + slowleak = 0; fgain = fgaintab[ab->fgaincod[chnl]]; snroffset = (((ab->csnroffst - 15) << 4) + ab->fsnroffst[chnl]) << 2; exps = ab->dexps[chnl]; baps = ab->bap[chnl]; - if (ab->deltbae[chnl] == 0 || ab->deltbae[chnl] == 1) { + if (ab->deltbae[chnl] == AC3_DBASTR_NEW || ab->deltbae[chnl] == AC3_DBASTR_REUSE) { do_delta = 1; deltnseg = ab->deltnseg[chnl]; deltoffst = ab->deltoffst[chnl]; @@ -592,7 +625,7 @@ } for (bin = start; bin < end; bin++) /* exponent mapping into psd */ - psd[bin] = (3072 - ((int16_t) (exps[bin] << 7))); + psd[bin] = (3072 - ((int)(exps[bin]) << 7)); /* psd integration */ j = start; @@ -629,7 +662,7 @@ break; } } - for (bin = begin; bin < (FFMIN(bndend, 22)); bin++) { + for (bin = begin; bin < FFMIN(bndend, 22); bin++) { if (bndend != 7 || bin != 6) lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin + 1], bin); fastleak -= fdecay; @@ -662,12 +695,12 @@ if (do_delta) { band = 0; for (seg = 0; seg < deltnseg + 1; seg++) { - band += deltoffst[seg]; - if (deltba[seg] >= 4) - delta = (deltba[seg] - 3) << 7; + band += (int)(deltoffst[seg]); + if ((int)(deltba[seg]) >= 4) + delta = ((int)(deltba[seg]) - 3) << 7; else - delta = (deltba[seg] - 4) << 7; - for (k = 0; k < deltlen[seg]; k++) { + delta = ((int)(deltba[seg]) - 4) << 7; + for (k = 0; k < (int)(deltlen[seg]); k++) { mask[band] += delta; band++; } @@ -687,23 +720,21 @@ mask[j] += floor; for (k = i; k < lastbin; k++) { address = (psd[i] - mask[j]) >> 5; - address = FFMIN(63, (FFMAX(0, address))); + address = FFMIN(63, FFMAX(0, address)); baps[i] = baptab[address]; i++; } j++; } while (end > lastbin); - - return 0; } -static int do_bit_allocation(AC3DecodeContext *ctx, int flags) +static void do_bit_allocation(AC3DecodeContext *ctx, int flags) { ac3_audio_block *ab = &ctx->audio_block; int i, snroffst = 0; if (!flags) /* bit allocation is not required */ - return 0; + return; if (ab->flags & AC3_AB_SNROFFSTE) { /* check whether snroffsts are zero */ snroffst += ab->csnroffst; @@ -719,23 +750,18 @@ memset(ab->bap[i], 0, sizeof (ab->bap[i])); memset(ab->lfebap, 0, sizeof (ab->lfebap)); - return 0; + return; } } /* perform bit allocation */ if ((ab->flags & AC3_AB_CPLINU) && (flags & 64)) - if (_do_bit_allocation(ctx, 5)) - return -1; + do_bit_allocation1(ctx, 5); for (i = 0; i < ctx->bsi.nfchans; i++) if (flags & (1 << i)) - if (_do_bit_allocation(ctx, i)) - return -1; + do_bit_allocation1(ctx, i); if ((ctx->bsi.flags & AC3_BSI_LFEON) && (flags & 32)) - if (_do_bit_allocation(ctx, 6)) - return -1; - - return 0; + do_bit_allocation1(ctx, 6); } static inline float to_float(uint8_t exp, int16_t mantissa) @@ -749,8 +775,8 @@ } mant_group; /* Get the transform coefficients for particular channel */ -static int _get_transform_coeffs(uint8_t *exps, uint8_t *bap, float chcoeff, - float *samples, int start, int end, int dith_flag, GetBitContext *gb, +static int get_transform_coeffs1(uint8_t *exps, uint8_t *bap, float chcoeff, + float *coeffs, int start, int end, int dith_flag, GetBitContext *gb, dither_state *state) { int16_t mantissa; @@ -765,21 +791,24 @@ i = 0; while (i < start) - samples[i++] = 0; + coeffs[i++] = 0; for (i = start; i < end; i++) { switch (bap[i]) { case 0: - if (!dith_flag) - mantissa = 0; - else + if (!dith_flag) { + coeffs[i] = 0; + continue; + } + else { mantissa = dither_int16(state); - samples[i] = to_float(exps[i], mantissa) * chcoeff; - break; + coeffs[i] = to_float(exps[i], mantissa) * chcoeff; + continue; + } case 1: if (l3_grp.gcptr > 2) { - gcode = get_bits(gb, qntztab[1]); + gcode = get_bits(gb, 5); if (gcode > 26) return -1; l3_grp.gcodes[0] = gcode / 9; @@ -788,12 +817,12 @@ l3_grp.gcptr = 0; } mantissa = l3_q_tab[l3_grp.gcodes[l3_grp.gcptr++]]; - samples[i] = to_float(exps[i], mantissa) * chcoeff; - break; + coeffs[i] = to_float(exps[i], mantissa) * chcoeff; + continue; case 2: if (l5_grp.gcptr > 2) { - gcode = get_bits(gb, qntztab[2]); + gcode = get_bits(gb, 7); if (gcode > 124) return -1; l5_grp.gcodes[0] = gcode / 25; @@ -802,116 +831,101 @@ l5_grp.gcptr = 0; } mantissa = l5_q_tab[l5_grp.gcodes[l5_grp.gcptr++]]; - samples[i] = to_float(exps[i], mantissa) * chcoeff; - break; + coeffs[i] = to_float(exps[i], mantissa) * chcoeff; + continue; case 3: - mantissa = get_bits(gb, qntztab[3]); + mantissa = get_bits(gb, 3); if (mantissa > 6) return -1; mantissa = l7_q_tab[mantissa]; - samples[i] = to_float(exps[i], mantissa); - break; + coeffs[i] = to_float(exps[i], mantissa); + continue; case 4: if (l11_grp.gcptr > 1) { - gcode = get_bits(gb, qntztab[4]); + gcode = get_bits(gb, 7); if (gcode > 120) return -1; l11_grp.gcodes[0] = gcode / 11; l11_grp.gcodes[1] = gcode % 11; } mantissa = l11_q_tab[l11_grp.gcodes[l11_grp.gcptr++]]; - samples[i] = to_float(exps[i], mantissa) * chcoeff; - break; + coeffs[i] = to_float(exps[i], mantissa) * chcoeff; + continue; case 5: - mantissa = get_bits(gb, qntztab[5]); + mantissa = get_bits(gb, 4); if (mantissa > 14) return -1; mantissa = l15_q_tab[mantissa]; - samples[i] = to_float(exps[i], mantissa) * chcoeff; - break; + coeffs[i] = to_float(exps[i], mantissa) * chcoeff; + continue; default: mantissa = get_bits(gb, qntztab[bap[i]]) << (16 - qntztab[bap[i]]); - samples[i] = to_float(exps[i], mantissa) * chcoeff; - break; + coeffs[i] = to_float(exps[i], mantissa) * chcoeff; + continue; } } i = end; while (i < 256) - samples[i++] = 0; + coeffs[i++] = 0; return 0; } -static int uncouple_channels(AC3DecodeContext * ctx) +static void uncouple_channels(AC3DecodeContext * ctx) { ac3_audio_block *ab = &ctx->audio_block; int ch, sbnd, bin; int index; - float (*samples)[256]; int16_t mantissa; - samples = (float (*)[256])((ctx->bsi.flags & AC3_BSI_LFEON) ? (ctx->samples + 256) : (ctx->samples)); - /* uncouple channels */ for (ch = 0; ch < ctx->bsi.nfchans; ch++) if (ab->chincpl & (1 << ch)) for (sbnd = ab->cplbegf; sbnd < 3 + ab->cplendf; sbnd++) for (bin = 0; bin < 12; bin++) { index = sbnd * 12 + bin + 37; - samples[ch][index] = ab->cplcoeffs[index] * ab->cplco[ch][sbnd] * ab->chcoeffs[ch]; + ab->transform_coeffs[ch + 1][index] = ab->cplcoeffs[index] * ab->cplco[ch][sbnd] * ab->chcoeffs[ch]; + /* generate dither if required */ + if (!ab->bap[ch][index] && (ab->chincpl & (1 << ch)) && (ab->dithflag & (1 << ch))) { + mantissa = dither_int16(&ctx->state); + ab->transform_coeffs[ch + 1][index] = to_float(ab->dexps[ch][index], mantissa) * ab->chcoeffs[ch]; + } } - - /* generate dither if required */ - for (ch = 0; ch < ctx->bsi.nfchans; ch++) - if ((ab->chincpl & (1 << ch)) && (ab->dithflag & (1 << ch))) - for (index = 0; index < ab->endmant[ch]; index++) - if (!ab->bap[ch][index]) { - mantissa = dither_int16(&ctx->state); - samples[ch][index] = to_float(ab->dexps[ch][index], mantissa) * ab->chcoeffs[ch]; - } - - return 0; } static int get_transform_coeffs(AC3DecodeContext * ctx) { int i; ac3_audio_block *ab = &ctx->audio_block; - float *samples = ctx->samples; int got_cplchan = 0; int dithflag = 0; - samples += (ctx->bsi.flags & AC3_BSI_LFEON) ? 256 : 0; for (i = 0; i < ctx->bsi.nfchans; i++) { - if ((ab->flags & AC3_AB_CPLINU) && (ab->chincpl & (1 << i))) - dithflag = 0; /* don't generate dither until channels are decoupled */ - else - dithflag = ab->dithflag & (1 << i); + dithflag = ab->dithflag & (1 << i); /* transform coefficients for individual channel */ - if (_get_transform_coeffs(ab->dexps[i], ab->bap[i], ab->chcoeffs[i], samples + (i * 256), + if (get_transform_coeffs1(ab->dexps[i], ab->bap[i], ab->chcoeffs[i], ab->transform_coeffs[i + 1], 0, ab->endmant[i], dithflag, &ctx->gb, &ctx->state)) return -1; /* tranform coefficients for coupling channels */ if ((ab->flags & AC3_AB_CPLINU) && (ab->chincpl & (1 << i)) && !got_cplchan) { - if (_get_transform_coeffs(ab->dcplexps, ab->cplbap, 1.0f, ab->cplcoeffs, + if (get_transform_coeffs1(ab->dcplexps, ab->cplbap, 1.0f, ab->cplcoeffs, ab->cplstrtmant, ab->cplendmant, 0, &ctx->gb, &ctx->state)) return -1; got_cplchan = 1; } } if (ctx->bsi.flags & AC3_BSI_LFEON) - if (_get_transform_coeffs(ab->lfeexps, ab->lfebap, 1.0f, samples - 256, 0, 7, 0, &ctx->gb, &ctx->state)) + if (get_transform_coeffs1(ab->dlfeexps, ab->lfebap, 1.0f, ab->transform_coeffs[0], 0, 7, 0, &ctx->gb, &ctx->state)) return -1; /* uncouple the channels from the coupling channel */ if (ab->flags & AC3_AB_CPLINU) - if (uncouple_channels(ctx)) - return -1; + uncouple_channels(ctx); return 0; } @@ -920,7 +934,7 @@ * from coupling co-ordinates of each band and coupling band * structure information */ -static int generate_coupling_coordinates(AC3DecodeContext * ctx) +static void generate_coupling_coordinates(AC3DecodeContext * ctx) { ac3_audio_block *ab = &ctx->audio_block; uint8_t exp, mstrcplco; @@ -952,23 +966,19 @@ cplbndstrc >>= 1; } } - - return 0; } -static int _do_rematrixing(AC3DecodeContext *ctx, int start, int end) +static void do_rematrixing1(AC3DecodeContext *ctx, int start, int end) { float tmp0, tmp1; while (start < end) { - tmp0 = ctx->samples[start]; - tmp1 = (ctx->samples + 256)[start]; - ctx->samples[start] = tmp0 + tmp1; - (ctx->samples + 256)[start] = tmp0 - tmp1; + tmp0 = ctx->audio_block.transform_coeffs[1][start]; + tmp1 = ctx->audio_block.transform_coeffs[2][start]; + ctx->audio_block.transform_coeffs[1][start] = tmp0 + tmp1; + ctx->audio_block.transform_coeffs[2][start] = tmp0 - tmp1; start++; } - - return 0; } static void do_rematrixing(AC3DecodeContext *ctx) @@ -979,16 +989,16 @@ bndend = FFMIN(ab->endmant[0], ab->endmant[1]); if (ab->rematflg & 1) - _do_rematrixing(ctx, bnd1, bnd2); + do_rematrixing1(ctx, bnd1, bnd2); if (ab->rematflg & 2) - _do_rematrixing(ctx, bnd2, bnd3); + do_rematrixing1(ctx, bnd2, bnd3); if (ab->rematflg & 4) { if (ab->cplbegf > 0 && ab->cplbegf <= 2 && (ab->flags & AC3_AB_CPLINU)) - _do_rematrixing(ctx, bnd3, bndend); + do_rematrixing1(ctx, bnd3, bndend); else { - _do_rematrixing(ctx, bnd3, bnd4); + do_rematrixing1(ctx, bnd3, bnd4); if (ab->rematflg & 8) - _do_rematrixing(ctx, bnd4, bndend); + do_rematrixing1(ctx, bnd4, bndend); } } } @@ -1002,7 +1012,7 @@ ac3_audio_block *ab = &ctx->audio_block; if (to == AC3_OUTPUT_UNMODIFIED) - return 0; + return; switch (from) { case AC3_INPUT_DUALMONO: @@ -1116,284 +1126,312 @@ } } -static inline void downmix_dualmono_to_mono(float *samples) +static inline void mix_dualmono_to_mono(AC3DecodeContext *ctx) { int i; + float (*output)[256] = ctx->audio_block.block_output; - for (i = 0; i < 256; i++) { - samples[i] += samples[i + 256]; - samples[i + 256] = 0; - } + for (i = 0; i < 256; i++) + output[1][i] += output[2][i]; + memset(output[2], 0, sizeof(output[2])); } -static inline void downmix_dualmono_to_stereo(float *samples) +static inline void mix_dualmono_to_stereo(AC3DecodeContext *ctx) { int i; float tmp; - - for (i = 0; i < 256; i++) { - tmp = samples[i] + samples[i + 256]; - samples[i] = samples[i + 256] = tmp; - } -} - -static inline void downmix_mono_to_stereo(float *samples) -{ - int i; - - for (i = 0; i < 256; i++) - samples[i + 256] = samples[i]; -} - -static inline void downmix_stereo_to_mono(float *samples) -{ - int i; - - for (i = 0; i < 256; i++) { - samples[i] += samples[i + 256]; - samples[i + 256] = 0; - } -} - -static inline void downmix_3f_to_mono(float *samples) -{ - int i; + float (*output)[256] = ctx->audio_block.block_output; for (i = 0; i < 256; i++) { - samples[i] += (samples[i + 256] + samples[i + 512]); - samples[i + 256] = samples[i + 512] = 0; - } -} - -static inline void downmix_3f_to_stereo(float *samples) -{ - int i; - - for (i = 0; i < 256; i++) { - samples[i] += samples[i + 256]; - samples[i + 256] = samples[i + 512]; - samples[i + 512] = 0; - } -} - -static inline void downmix_2f_1r_to_mono(float *samples) -{ - int i; - - for (i = 0; i < 256; i++) { - samples[i] += (samples[i + 256] + samples[i + 512]); - samples[i + 256] = samples[i + 512] = 0; - } -} - -static inline void downmix_2f_1r_to_stereo(float *samples) -{ - int i; - - for (i = 0; i < 256; i++) { - samples[i] += samples[i + 512]; - samples[i + 256] += samples[i + 512]; - samples[i + 512] = 0; - } -} - -static inline void downmix_2f_1r_to_dolby(float *samples) -{ - int i; - - for (i = 0; i < 256; i++) { - samples[i] -= samples[i + 512]; - samples[i + 256] += samples[i + 512]; - samples[i + 512] = 0; + tmp = output[1][i] + output[2][i]; + output[1][i] = output[2][i] = tmp; } } -static inline void downmix_3f_1r_to_mono(float *samples) +static inline void upmix_mono_to_stereo(AC3DecodeContext *ctx) { int i; + float (*output)[256] = ctx->audio_block.block_output; - for (i = 0; i < 256; i++) { - samples[i] += (samples[i + 256] + samples[i + 512] + samples[i + 768]); - samples[i + 256] = samples[i + 512] = samples[i + 768] = 0; - } + for (i = 0; i < 256; i++) + output[2][i] = output[1][i]; +} + +static inline void mix_stereo_to_mono(AC3DecodeContext *ctx) +{ + int i; + float (*output)[256] = ctx->audio_block.block_output; + + for (i = 0; i < 256; i++) + output[1][i] += output[2][i]; + memset(output[2], 0, sizeof(output[2])); } -static inline void downmix_3f_1r_to_stereo(float *samples) +static inline void mix_3f_to_mono(AC3DecodeContext *ctx) { int i; + float (*output)[256] = ctx->audio_block.block_output; + + for (i = 0; i < 256; i++) + output[1][i] += (output[2][i] + output[3][i]); + memset(output[2], 0, sizeof(output[2])); + memset(output[3], 0, sizeof(output[3])); +} + +static inline void mix_3f_to_stereo(AC3DecodeContext *ctx) +{ + int i; + float (*output)[256] = ctx->audio_block.block_output; for (i = 0; i < 256; i++) { - samples[i] += (samples[i + 256] + samples[i + 768]); - samples[i + 256] += (samples[i + 512] + samples[i + 768]); - samples[i + 512] = samples[i + 768] = 0; + output[1][i] += output[2][i]; + output[2][i] += output[3][i]; } + memset(output[3], 0, sizeof(output[3])); } -static inline void downmix_3f_1r_to_dolby(float *samples) +static inline void mix_2f_1r_to_mono(AC3DecodeContext *ctx) { int i; + float (*output)[256] = ctx->audio_block.block_output; + + for (i = 0; i < 256; i++) + output[1][i] += (output[2][i] + output[3][i]); + memset(output[2], 0, sizeof(output[2])); + memset(output[3], 0, sizeof(output[3])); + +} + +static inline void mix_2f_1r_to_stereo(AC3DecodeContext *ctx) +{ + int i; + float (*output)[256] = ctx->audio_block.block_output; for (i = 0; i < 256; i++) { - samples[i] += (samples[i + 256] - samples[i + 768]); - samples[i + 256] += (samples[i + 512] + samples[i + 768]); - samples[i + 512] = samples[i + 768] = 0; + output[1][i] += output[2][i]; + output[2][i] += output[3][i]; } + memset(output[3], 0, sizeof(output[3])); } -static inline void downmix_2f_2r_to_mono(float *samples) +static inline void mix_2f_1r_to_dolby(AC3DecodeContext *ctx) { int i; + float (*output)[256] = ctx->audio_block.block_output; for (i = 0; i < 256; i++) { - samples[i] += (samples[i + 256] + samples[i + 512] + samples[i + 768]); - samples[i + 256] = samples[i + 512] = samples[i + 768] = 0; + output[1][i] -= output[3][i]; + output[2][i] += output[3][i]; } + memset(output[3], 0, sizeof(output[3])); } -static inline void downmix_2f_2r_to_stereo(float *samples) +static inline void mix_3f_1r_to_mono(AC3DecodeContext *ctx) { int i; + float (*output)[256] = ctx->audio_block.block_output; + + for (i = 0; i < 256; i++) + output[1][i] = (output[2][i] + output[3][i] + output[4][i]); + memset(output[2], 0, sizeof(output[2])); + memset(output[3], 0, sizeof(output[3])); + memset(output[4], 0, sizeof(output[4])); +} + +static inline void mix_3f_1r_to_stereo(AC3DecodeContext *ctx) +{ + int i; + float (*output)[256] = ctx->audio_block.block_output; for (i = 0; i < 256; i++) { - samples[i] += samples[i + 512]; - samples[i + 256] = samples[i + 768]; - samples[i + 512] = samples[i + 768] = 0; + output[1][i] += (output[2][i] + output[4][i]); + output[2][i] += (output[3][i] + output[4][i]); } + memset(output[3], 0, sizeof(output[3])); + memset(output[4], 0, sizeof(output[4])); } -static inline void downmix_2f_2r_to_dolby(float *samples) +static inline void mix_3f_1r_to_dolby(AC3DecodeContext *ctx) { int i; + float (*output)[256] = ctx->audio_block.block_output; for (i = 0; i < 256; i++) { - samples[i] -= samples[i + 512]; - samples[i + 256] += samples[i + 768]; - samples[i + 512] = samples[i + 768] = 0; + output[1][i] += (output[2][i] - output[4][i]); + output[2][i] += (output[3][i] + output[4][i]); } + memset(output[3], 0, sizeof(output[3])); + memset(output[4], 0, sizeof(output[4])); } -static inline void downmix_3f_2r_to_mono(float *samples) +static inline void mix_2f_2r_to_mono(AC3DecodeContext *ctx) { int i; + float (*output)[256] = ctx->audio_block.block_output; + + for (i = 0; i < 256; i++) + output[1][i] = (output[2][i] + output[3][i] + output[4][i]); + memset(output[2], 0, sizeof(output[2])); + memset(output[3], 0, sizeof(output[3])); + memset(output[4], 0, sizeof(output[4])); +} + +static inline void mix_2f_2r_to_stereo(AC3DecodeContext *ctx) +{ + int i; + float (*output)[256] = ctx->audio_block.block_output; for (i = 0; i < 256; i++) { - samples[i] += (samples[i + 256] + samples[i + 512] + samples[i + 768] + samples[i + 1024]); - samples[i + 256] = samples[i + 512] = samples[i + 768] = samples[i + 1024] = 0; + output[1][i] += output[3][i]; + output[2][i] += output[4][i]; } + memset(output[3], 0, sizeof(output[3])); + memset(output[4], 0, sizeof(output[4])); } -static inline void downmix_3f_2r_to_stereo(float *samples) +static inline void mix_2f_2r_to_dolby(AC3DecodeContext *ctx) { int i; + float (*output)[256] = ctx->audio_block.block_output; for (i = 0; i < 256; i++) { - samples[i] += (samples[i + 256] + samples[i + 768]); - samples[i + 256] = (samples[i + 512] + samples[i + 1024]); - samples[i + 512] = samples[i + 768] = samples[i + 1024] = 0; + output[1][i] -= output[3][i]; + output[2][i] += output[4][i]; } + memset(output[3], 0, sizeof(output[3])); + memset(output[4], 0, sizeof(output[4])); +} + +static inline void mix_3f_2r_to_mono(AC3DecodeContext *ctx) +{ + int i; + float (*output)[256] = ctx->audio_block.block_output; + + for (i = 0; i < 256; i++) + output[1][i] += (output[2][i] + output[3][i] + output[4][i] + output[5][i]); + memset(output[2], 0, sizeof(output[2])); + memset(output[3], 0, sizeof(output[3])); + memset(output[4], 0, sizeof(output[4])); + memset(output[5], 0, sizeof(output[5])); } -static inline void downmix_3f_2r_to_dolby(float *samples) +static inline void mix_3f_2r_to_stereo(AC3DecodeContext *ctx) { int i; + float (*output)[256] = ctx->audio_block.block_output; for (i = 0; i < 256; i++) { - samples[i] += (samples[i + 256] - samples[i + 768]); - samples[i + 256] = (samples[i + 512] + samples[i + 1024]); - samples[i + 512] = samples[i + 768] = samples[i + 1024] = 0; + output[1][i] += (output[2][i] + output[4][i]); + output[2][i] += (output[3][i] + output[5][i]); } + memset(output[3], 0, sizeof(output[3])); + memset(output[4], 0, sizeof(output[4])); + memset(output[5], 0, sizeof(output[5])); +} + +static inline void mix_3f_2r_to_dolby(AC3DecodeContext *ctx) +{ + int i; + float (*output)[256] = ctx->audio_block.block_output; + + for (i = 0; i < 256; i++) { + output[1][i] += (output[2][i] - output[4][i] - output[5][i]); + output[2][i] += (output[3][i] + output[4][i] + output[5][i]); + } + memset(output[3], 0, sizeof(output[3])); + memset(output[4], 0, sizeof(output[4])); + memset(output[5], 0, sizeof(output[5])); } static void do_downmix(AC3DecodeContext *ctx) { int from = ctx->bsi.acmod; int to = ctx->output; - float *samples = ctx->samples + ((ctx->bsi.flags & AC3_BSI_LFEON) ? 256 : 0); switch (from) { case AC3_INPUT_DUALMONO: switch (to) { case AC3_OUTPUT_MONO: - downmix_dualmono_to_mono(samples); + mix_dualmono_to_mono(ctx); break; case AC3_OUTPUT_STEREO: /* We Assume that sum of both mono channels is requested */ - downmix_dualmono_to_stereo(samples); + mix_dualmono_to_stereo(ctx); break; } break; case AC3_INPUT_MONO: switch (to) { case AC3_OUTPUT_STEREO: - downmix_mono_to_stereo(samples); + upmix_mono_to_stereo(ctx); break; } break; case AC3_INPUT_STEREO: switch (to) { case AC3_OUTPUT_MONO: - downmix_stereo_to_mono(samples); + mix_stereo_to_mono(ctx); break; } break; case AC3_INPUT_3F: switch (to) { case AC3_OUTPUT_MONO: - downmix_3f_to_mono(samples); + mix_3f_to_mono(ctx); break; case AC3_OUTPUT_STEREO: - downmix_3f_to_stereo(samples); + mix_3f_to_stereo(ctx); break; } break; case AC3_INPUT_2F_1R: switch (to) { case AC3_OUTPUT_MONO: - downmix_2f_1r_to_mono(samples); + mix_2f_1r_to_mono(ctx); break; case AC3_OUTPUT_STEREO: - downmix_2f_1r_to_stereo(samples); + mix_2f_1r_to_stereo(ctx); break; case AC3_OUTPUT_DOLBY: - downmix_2f_1r_to_dolby(samples); + mix_2f_1r_to_dolby(ctx); break; } break; case AC3_INPUT_3F_1R: switch (to) { case AC3_OUTPUT_MONO: - downmix_3f_1r_to_mono(samples); + mix_3f_1r_to_mono(ctx); break; case AC3_OUTPUT_STEREO: - downmix_3f_1r_to_stereo(samples); + mix_3f_1r_to_stereo(ctx); break; case AC3_OUTPUT_DOLBY: - downmix_3f_1r_to_dolby(samples); + mix_3f_1r_to_dolby(ctx); break; } break; case AC3_INPUT_2F_2R: switch (to) { case AC3_OUTPUT_MONO: - downmix_2f_2r_to_mono(samples); + mix_2f_2r_to_mono(ctx); break; case AC3_OUTPUT_STEREO: - downmix_2f_2r_to_stereo(samples); + mix_2f_2r_to_stereo(ctx); break; case AC3_OUTPUT_DOLBY: - downmix_2f_2r_to_dolby(samples); + mix_2f_2r_to_dolby(ctx); break; } break; case AC3_INPUT_3F_2R: switch (to) { case AC3_OUTPUT_MONO: - downmix_3f_2r_to_mono(samples); + mix_3f_2r_to_mono(ctx); break; case AC3_OUTPUT_STEREO: - downmix_3f_2r_to_stereo(samples); + mix_3f_2r_to_stereo(ctx); break; case AC3_OUTPUT_DOLBY: - downmix_3f_2r_to_dolby(samples); + mix_3f_2r_to_dolby(ctx); break; } break; @@ -1405,22 +1443,23 @@ ac3_audio_block *ab = &ctx->audio_block; int nfchans = ctx->bsi.nfchans; int acmod = ctx->bsi.acmod; - int i, bnd, rbnd, grp, seg; + int i, bnd, rbnd, seg, grpsize; GetBitContext *gb = &ctx->gb; uint32_t *flags = &ab->flags; int bit_alloc_flags = 0; float drange; + uint8_t *dexps; *flags = 0; ab->blksw = 0; for (i = 0; i < 5; i++) ab->chcoeffs[i] = 1.0; for (i = 0; i < nfchans; i++) /*block switch flag */ - ab->blksw |= get_bits(gb, 1) << i; + ab->blksw |= get_bits1(gb) << i; ab->dithflag = 0; for (i = 0; i < nfchans; i++) /* dithering flag */ - ab->dithflag |= get_bits(gb, 1) << i; - if (get_bits(gb, 1)) { /* dynamic range */ + ab->dithflag |= get_bits1(gb) << i; + if (get_bits1(gb)) { /* dynamic range */ *flags |= AC3_AB_DYNRNGE; ab->dynrng = get_bits(gb, 8); drange = ((((ab->dynrng & 0x1f) | 0x20) << 13) * scale_factors[3 - (ab->dynrng >> 5)]); @@ -1428,7 +1467,7 @@ ab->chcoeffs[i] *= drange; } if (acmod == 0x00) { /* dynamic range 1+1 mode */ - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { *flags |= AC3_AB_DYNRNG2E; ab->dynrng2 = get_bits(gb, 8); drange = ((((ab->dynrng2 & 0x1f) | 0x20) << 13) * scale_factors[3 - (ab->dynrng2 >> 5)]); @@ -1437,22 +1476,27 @@ } get_downmix_coeffs(ctx); ab->chincpl = 0; - if (get_bits(gb, 1)) { /* coupling strategy */ + if (get_bits1(gb)) { /* coupling strategy */ *flags |= AC3_AB_CPLSTRE; ab->cplbndstrc = 0; - if (get_bits(gb, 1)) { /* coupling in use */ + if (get_bits1(gb)) { /* coupling in use */ *flags |= AC3_AB_CPLINU; for (i = 0; i < nfchans; i++) - ab->chincpl |= get_bits(gb, 1) << i; + ab->chincpl |= get_bits1(gb) << i; + if (acmod == 0x00 || acmod == 0x01) + return -1; /* coupling needs atleast two shared channels */ if (acmod == 0x02) - if (get_bits(gb, 1)) /* phase flag in use */ + if (get_bits1(gb)) /* phase flag in use */ *flags |= AC3_AB_PHSFLGINU; ab->cplbegf = get_bits(gb, 4); ab->cplendf = get_bits(gb, 4); - assert((ab->ncplsubnd = 3 + ab->cplendf - ab->cplbegf) > 0); - ab->ncplbnd = ab->ncplsubnd; + if (3 + ab->cplendf - ab->cplbegf < 0) + return -1; + ab->ncplbnd = ab->ncplsubnd = 3 + ab->cplendf - ab->cplbegf; + ab->cplstrtmant = ab->cplbegf * 12 + 37; + ab->cplendmant = ((ab->cplendf + 3) * 12) + 37; for (i = 0; i < ab->ncplsubnd - 1; i++) /* coupling band structure */ - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { ab->cplbndstrc |= 1 << i; ab->ncplbnd--; } @@ -1462,7 +1506,7 @@ ab->cplcoe = 0; for (i = 0; i < nfchans; i++) if (ab->chincpl & (1 << i)) - if (get_bits(gb, 1)) { /* coupling co-ordinates */ + if (get_bits1(gb)) { /* coupling co-ordinates */ ab->cplcoe |= 1 << i; ab->mstrcplco[i] = get_bits(gb, 2); for (bnd = 0; bnd < ab->ncplbnd; bnd++) { @@ -1470,77 +1514,83 @@ ab->cplcomant[i][bnd] = get_bits(gb, 4); } } - } - ab->phsflg = 0; - if ((acmod == 0x02) && (*flags & AC3_AB_PHSFLGINU) && (ab->cplcoe & 1 || ab->cplcoe & (1 << 1))) { - for (bnd = 0; bnd < ab->ncplbnd; bnd++) - if (get_bits(gb, 1)) - ab->phsflg |= 1 << bnd; + ab->phsflg = 0; + if ((acmod == 0x02) && (*flags & AC3_AB_PHSFLGINU) && (ab->cplcoe & 1 || ab->cplcoe & (1 << 1))) { + for (bnd = 0; bnd < ab->ncplbnd; bnd++) + if (get_bits1(gb)) + ab->phsflg |= 1 << bnd; + } } generate_coupling_coordinates(ctx); ab->rematflg = 0; if (acmod == 0x02) /* rematrixing */ - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { *flags |= AC3_AB_REMATSTR; - if (ab->cplbegf > 2 || !(*flags & AC3_AB_CPLINU)) + if (!(*flags & AC3_AB_CPLINU) || ab->cplbegf > 2) for (rbnd = 0; rbnd < 4; rbnd++) - ab->rematflg |= get_bits(gb, 1) << bnd; - else if (ab->cplbegf > 0 && ab->cplbegf <= 2 && *flags & AC3_AB_CPLINU) + ab->rematflg |= get_bits1(gb) << rbnd; + if (ab->cplbegf > 0 && ab->cplbegf <= 2 && (*flags & AC3_AB_CPLINU)) for (rbnd = 0; rbnd < 3; rbnd++) - ab->rematflg |= get_bits(gb, 1) << bnd; - else if (!(ab->cplbegf) && *flags & AC3_AB_CPLINU) + ab->rematflg |= get_bits1(gb) << rbnd; + if (ab->cplbegf == 0 && (*flags & AC3_AB_CPLINU)) for (rbnd = 0; rbnd < 2; rbnd++) - ab->rematflg |= get_bits(gb, 1) << bnd; + ab->rematflg |= get_bits1(gb) << rbnd; } + ab->cplexpstr = AC3_EXPSTR_REUSE; + ab->lfeexpstr = AC3_EXPSTR_REUSE; if (*flags & AC3_AB_CPLINU) /* coupling exponent strategy */ ab->cplexpstr = get_bits(gb, 2); for (i = 0; i < nfchans; i++) /* channel exponent strategy */ ab->chexpstr[i] = get_bits(gb, 2); if (ctx->bsi.flags & AC3_BSI_LFEON) /* lfe exponent strategy */ - ab->lfeexpstr = get_bits(gb, 1); + ab->lfeexpstr = get_bits1(gb); for (i = 0; i < nfchans; i++) /* channel bandwidth code */ - if (ab->chexpstr[i] != AC3_EXPSTR_REUSE) - if (!(ab->chincpl & (1 << i))) { + if (ab->chexpstr[i] != AC3_EXPSTR_REUSE) { + if ((ab->chincpl & (1 << i))) + ab->endmant[i] = ab->cplstrtmant; + else { ab->chbwcod[i] = get_bits(gb, 6); - assert (ab->chbwcod[i] <= 60); + if (ab->chbwcod[i] > 60) { + av_log(NULL, AV_LOG_ERROR, "chbwcod = %d > 60", ab->chbwcod[i]); + return -1; + } + ab->endmant[i] = ((ab->chbwcod[i] + 12) * 3) + 37; } + } if (*flags & AC3_AB_CPLINU) if (ab->cplexpstr != AC3_EXPSTR_REUSE) {/* coupling exponents */ bit_alloc_flags |= 64; ab->cplabsexp = get_bits(gb, 4) << 1; - ab->cplstrtmant = (ab->cplbegf * 12) + 37; - ab->cplendmant = ((ab->cplendmant + 3) * 12) + 37; ab->ncplgrps = (ab->cplendmant - ab->cplstrtmant) / (3 << (ab->cplexpstr - 1)); - for (grp = 0; grp < ab->ncplgrps; grp++) - ab->cplexps[grp] = get_bits(gb, 7); + if (decode_exponents(gb, ab->cplexpstr, ab->ncplgrps, ab->cplabsexp, ab->dcplexps + ab->cplstrtmant)) { + av_log(NULL, AV_LOG_ERROR, "error decoding coupling exponents\n"); + return -1; + } } for (i = 0; i < nfchans; i++) /* fbw channel exponents */ if (ab->chexpstr[i] != AC3_EXPSTR_REUSE) { bit_alloc_flags |= 1 << i; - if (ab->chincpl & (1 << i)) - ab->endmant[i] = (ab->cplbegf * 12) + 37; - else - ab->endmant[i] = ((ab->chbwcod[i] + 3) * 12) + 37; - ab->nchgrps[i] = - (ab->endmant[i] + (3 << (ab->chexpstr[i] - 1)) - 4) / (3 << (ab->chexpstr[i] - 1)); - ab->exps[i][0] = ab->dexps[i][0] = get_bits(gb, 4); - for (grp = 1; grp <= ab->nchgrps[i]; grp++) - ab->exps[i][grp] = get_bits(gb, 7); + grpsize = 3 << (ab->chexpstr[i] - 1); + ab->nchgrps[i] = (ab->endmant[i] + grpsize - 4) / grpsize; + dexps = ab->dexps[i]; + dexps[0] = get_bits(gb, 4); + if (decode_exponents(gb, ab->chexpstr[i], ab->nchgrps[i], dexps[0], dexps + 1)) { + av_log(NULL, AV_LOG_ERROR, "error decoding channel %d exponents\n", i); + return -1; + } ab->gainrng[i] = get_bits(gb, 2); } if (ctx->bsi.flags & AC3_BSI_LFEON) /* lfe exponents */ if (ab->lfeexpstr != AC3_EXPSTR_REUSE) { bit_alloc_flags |= 32; - ab->lfeexps[0] = ab->dlfeexps[0] = get_bits(gb, 4); - ab->lfeexps[1] = get_bits(gb, 7); - ab->lfeexps[2] = get_bits(gb, 7); + ab->dlfeexps[0] = get_bits(gb, 4); + if (decode_exponents(gb, ab->lfeexpstr, 2, ab->dlfeexps[0], ab->dlfeexps + 1)) { + av_log(NULL, AV_LOG_ERROR, "error decoding lfe exponents\n"); + return -1; + } } - if (decode_exponents(ctx)) {/* decode the exponents for this block */ - av_log(NULL, AV_LOG_ERROR, "Error parsing exponents\n"); - return -1; - } - if (get_bits(gb, 1)) { /* bit allocation information */ + if (get_bits1(gb)) { /* bit allocation information */ *flags |= AC3_AB_BAIE; bit_alloc_flags |= 127; ab->sdcycod = get_bits(gb, 2); @@ -1549,7 +1599,7 @@ ab->dbpbcod = get_bits(gb, 2); ab->floorcod = get_bits(gb, 3); } - if (get_bits(gb, 1)) { /* snroffset */ + if (get_bits1(gb)) { /* snroffset */ *flags |= AC3_AB_SNROFFSTE; bit_alloc_flags |= 127; ab->csnroffst = get_bits(gb, 6); @@ -1567,13 +1617,13 @@ } } if (*flags & AC3_AB_CPLINU) - if (get_bits(gb, 1)) { /* coupling leak information */ + if (get_bits1(gb)) { /* coupling leak information */ bit_alloc_flags |= 64; *flags |= AC3_AB_CPLLEAKE; ab->cplfleak = get_bits(gb, 3); ab->cplsleak = get_bits(gb, 3); } - if (get_bits(gb, 1)) { /* delta bit allocation information */ + if (get_bits1(gb)) { /* delta bit allocation information */ *flags |= AC3_AB_DELTBAIE; bit_alloc_flags |= 127; if (*flags & AC3_AB_CPLINU) { @@ -1609,17 +1659,14 @@ } } } - if (do_bit_allocation (ctx, bit_alloc_flags)) /* perform the bit allocation */ { - av_log(NULL, AV_LOG_ERROR, "Error in bit allocation routine\n"); - return -1; - } - if (get_bits(gb, 1)) { /* unused dummy data */ + + do_bit_allocation (ctx, bit_alloc_flags); /* perform the bit allocation */ + + if (get_bits1(gb)) { /* unused dummy data */ *flags |= AC3_AB_SKIPLE; ab->skipl = get_bits(gb, 9); - while (ab->skipl) { - get_bits(gb, 8); - ab->skipl--; - } + for (i = 0; i < ab->skipl; i++) + skip_bits(gb, 8); } /* unpack the transform coefficients * * this also uncouples channels if coupling is in use. @@ -1632,59 +1679,34 @@ if (*flags & AC3_AB_REMATSTR) do_rematrixing(ctx); - if (ctx->output != AC3_OUTPUT_UNMODIFIED) - do_downmix(ctx); - return 0; } -/**** the following two functions comes from ac3dec */ -static inline int blah (int32_t i) -{ - if (i > 0x43c07fff) - return 32767; - else if (i < 0x43bf8000) - return -32768; - else - return i - 0x43c00000; -} - -static inline void float_to_int (float * _f, int16_t * s16, int samples) +static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint8_t *buf, int buf_size) { - int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format - int i; - - for (i = 0; i < samples; i++) { - s16[i] = blah (f[i]); - } -} -/**** end */ - - - -static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint8_t * buf, int buf_size) -{ - AC3DecodeContext *ctx = avctx->priv_data; + AC3DecodeContext *ctx = (AC3DecodeContext *)avctx->priv_data; + ac3_audio_block *ab = &ctx->audio_block; int frame_start; - int i, j, k, l; - float tmp0[128], tmp1[128], tmp[512]; - short *out_samples = (short *)data; - float *samples = ctx->samples; + int i, j, k, l, value; + float tmp_block_first_half[128], tmp_block_second_half[128]; + int16_t *out_samples = (int16_t *)data; + int nfchans; //Synchronize the frame. frame_start = ac3_synchronize(buf, buf_size); if (frame_start == -1) { av_log(avctx, AV_LOG_ERROR, "frame is not synchronized\n"); *data_size = 0; - return -1; + return buf_size; } //Initialize the GetBitContext with the start of valid AC3 Frame. init_get_bits(&(ctx->gb), buf + frame_start, (buf_size - frame_start) * 8); + //Parse the syncinfo. - ////If 'fscod' is not valid the decoder shall mute as per the standard. - if (ac3_parse_sync_info(ctx)) { - av_log(avctx, AV_LOG_ERROR, "fscod is not valid\n"); + //If 'fscod' or 'bsid' is not valid the decoder shall mute as per the standard. + if (!ac3_parse_sync_info(ctx)) { + av_log(avctx, AV_LOG_ERROR, "\n"); *data_size = 0; return -1; } @@ -1703,15 +1725,18 @@ return -1; } + for (i = 0; i < MAX_BLOCKS; i++) + memset(ctx->delay[i], 0, sizeof(ctx->delay[i])); avctx->sample_rate = ctx->sync_info.sampling_rate; + avctx->bit_rate = ctx->sync_info.bit_rate; if (avctx->channels == 0) { - avctx->channels = ctx->bsi.nfchans + ((ctx->bsi.flags & AC3_BSI_LFEON) ? 1 : 0); + //avctx->channels = ctx->bsi.nfchans + ((ctx->bsi.flags & AC3_BSI_LFEON) ? 1 : 0); ctx->output = AC3_OUTPUT_UNMODIFIED; } else if ((ctx->bsi.nfchans + ((ctx->bsi.flags & AC3_BSI_LFEON) ? 1 : 0)) < avctx->channels) { av_log(avctx, AV_LOG_INFO, "ac3_decoder: AC3 Source Channels Are Less Then Specified %d: Output to %d Channels\n", avctx->channels, (ctx->bsi.nfchans + ((ctx->bsi.flags & AC3_BSI_LFEON) ? 1 : 0))); - avctx->channels = ctx->bsi.nfchans + ((ctx->bsi.flags & AC3_BSI_LFEON) ? 1 : 0); + //avctx->channels = ctx->bsi.nfchans + ((ctx->bsi.flags & AC3_BSI_LFEON) ? 1 : 0); ctx->output = AC3_OUTPUT_UNMODIFIED; } else if (avctx->channels == 1) { @@ -1724,53 +1749,72 @@ } - avctx->bit_rate = ctx->sync_info.bit_rate; av_log(avctx, AV_LOG_INFO, "channels = %d \t bit rate = %d \t sampling rate = %d \n", avctx->channels, avctx->sample_rate, avctx->bit_rate); //Parse the Audio Blocks. + *data_size = 0; for (i = 0; i < 6; i++) { if (ac3_parse_audio_block(ctx, i)) { av_log(avctx, AV_LOG_ERROR, "error parsing the audio block\n"); *data_size = 0; return -1; } - samples = ctx->samples; + + av_log(NULL, AV_LOG_INFO, "doing imdct\n"); + if (ctx->bsi.flags & AC3_BSI_LFEON) { - ff_imdct_calc(&ctx->imdct_ctx_512, ctx->samples + 1536, samples, tmp); + ff_imdct_calc(&ctx->imdct_ctx_512, ctx->tmp_output, ab->transform_coeffs[0], ctx->tmp_imdct); for (l = 0; l < 256; l++) - samples[l] = (ctx->samples + 1536)[l]; - float_to_int(samples, out_samples, 256); - samples += 256; - out_samples += 256; + ab->block_output[0][l] = ctx->tmp_output[l] * window[l] + ctx->delay[0][l] * window[255 -l]; + memcpy(ctx->delay[0], ctx->tmp_output + 256, sizeof(ctx->delay[0])); } + for (j = 0; j < ctx->bsi.nfchans; j++) { if (ctx->audio_block.blksw & (1 << j)) { for (k = 0; k < 128; k++) { - tmp0[k] = samples[2 * k]; - tmp1[k] = samples[2 * k + 1]; + tmp_block_first_half[k] = ab->transform_coeffs[j + 1][2 * k]; + tmp_block_second_half[k] = ab->transform_coeffs[j + 1][2 * k + 1]; } - ff_imdct_calc(&ctx->imdct_ctx_256, ctx->samples + 1536, tmp0, tmp); + ff_imdct_calc(&ctx->imdct_ctx_256, ctx->tmp_output, tmp_block_first_half, ctx->tmp_imdct); for (l = 0; l < 256; l++) - samples[l] = (ctx->samples + 1536)[l] * window[l] + (ctx->samples + 2048)[l] * window[255 - l]; - ff_imdct_calc(&ctx->imdct_ctx_256, ctx->samples + 2048, tmp1, tmp); - float_to_int(samples, out_samples, 256); - samples += 256; - out_samples += 256; - } - else { - ff_imdct_calc(&ctx->imdct_ctx_512, ctx->samples + 1536, samples, tmp); + ab->block_output[j + 1][l] = ctx->tmp_output[l] * window[l] + ctx->delay[j + 1][l] * window[255 - l]; + ff_imdct_calc(&ctx->imdct_ctx_256, ctx->delay[j + 1], tmp_block_second_half, ctx->tmp_imdct); + } else { + ff_imdct_calc(&ctx->imdct_ctx_512, ctx->tmp_output, ab->transform_coeffs[j + 1], ctx->tmp_imdct); for (l = 0; l < 256; l++) - samples[l] = (ctx->samples + 1536)[l] * window[l] + (ctx->samples + 2048)[l] * window[255 - l]; - float_to_int(samples, out_samples, 256); - memcpy(ctx->samples + 2048, ctx->samples + 1792, 256 * sizeof (float)); - samples += 256; - out_samples += 256; + ab->block_output[j + 1][l] = ctx->tmp_output[l] * window[l] + ctx->delay[j + 1][l] * window[255 - l]; + memcpy(ctx->delay[j + 1], ctx->tmp_output + 256, sizeof(ctx->delay[j + 1])); } } + if (ctx->bsi.flags & AC3_BSI_LFEON) { + for (l = 0; l < 256; l++) { + value = lrint(ab->block_output[0][l]); + if (value < -32768) + value = -32768; + else if (value > 32767) + value = 32767; + *(out_samples++) = value; + } + *data_size += 256 * sizeof(int16_t); + } + do_downmix(ctx); + if (ctx->output == AC3_OUTPUT_UNMODIFIED) + nfchans = ctx->bsi.nfchans; + else + nfchans = avctx->channels; + for (k = 0; k < nfchans; k++) + for (l = 0; l < 256; l++) { + value = lrint(ab->block_output[k + 1][l]); + if (value < -32768) + value = -32768; + else if (value > 32767) + value = 32767; + *(out_samples++) = value; + } + *data_size += nfchans * 256 * sizeof (int16_t); } - *data_size = 6 * ctx->bsi.nfchans * 256 * sizeof (int16_t); - return (buf_size - frame_start); + return ctx->sync_info.framesize; } static int ac3_decode_end(AVCodecContext *ctx)