diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2007-07-15 13:53:42 +0000 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2007-07-15 13:53:42 +0000 |
commit | 623b79435dc3803e08c6b9b7758793fe98907468 (patch) | |
tree | 14f572927a9cb8e4dd0dd6d4f74754c8e0cd0432 | |
parent | 8749180c3b13bf11ac444d7309a1e4fe9e612638 (diff) | |
download | ffmpeg-623b79435dc3803e08c6b9b7758793fe98907468.tar.gz |
use shared ac3 bit allocation function
Originally committed as revision 9684 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/ac3dec.c | 214 |
1 files changed, 27 insertions, 187 deletions
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 62c7616376..5028385568 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -161,6 +161,7 @@ typedef struct { int cplstrtmant; //coupling start mantissa int cplendmant; //coupling end mantissa int endmant[5]; //channel end mantissas + AC3BitAllocParameters bit_alloc_params; ///< bit allocation parameters uint8_t dcplexps[256]; //decoded coupling exponents uint8_t dexps[5][256]; //decoded fbw channel exponents @@ -549,211 +550,39 @@ static int decode_exponents(GetBitContext *gb, int expstr, int ngrps, uint8_t ab return 0; } -/*********** HELPER FUNCTIONS FOR BIT ALLOCATION ***********/ -static inline int logadd(int a, int b) -{ - int c = a - b; - int address; - - address = FFMIN((FFABS(c) >> 1), 255); - - if (c >= 0) - return (a + ff_ac3_latab[address]); - else - return (b + ff_ac3_latab[address]); -} - -static inline int calc_lowcomp(int a, int b0, int b1, int bin) -{ - if (bin < 7) { - if ((b0 + 256) == b1) - a = 384; - else if (b0 > b1) - a = FFMAX(0, (a - 64)); - } - else if (bin < 20) { - if ((b0 + 256) == b1) - a = 320; - else if (b0 > b1) - a = FFMAX(0, (a - 64)); - } - else - a = FFMAX(0, (a - 128)); - - return a; -} -/*********** END HELPER FUNCTIONS FOR BIT ALLOCATION ***********/ - /* Performs bit allocation. * This function performs bit allocation for the requested chanenl. */ static void do_bit_allocation(AC3DecodeContext *ctx, int chnl) { - int16_t psd[256], bndpsd[50], excite[50], mask[50], delta; - int sdecay, fdecay, sgain, dbknee, floor; - int lowcomp = 0, fgain = 0, snroffset = 0, fastleak = 0, slowleak = 0, do_delta = 0; - 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->fscod; - uint8_t *deltoffst = 0, *deltlen = 0, *deltba = 0; - uint8_t *exps = 0, *bap = 0; - - /* initialization */ - sdecay = ff_sdecaytab[ctx->sdcycod]; - fdecay = ff_fdecaytab[ctx->fdcycod]; - sgain = ff_sgaintab[ctx->sgaincod]; - dbknee = ff_dbkneetab[ctx->dbpbcod]; - floor = ff_floortab[ctx->floorcod]; + int fgain, snroffset; if (chnl == 5) { - start = ctx->cplstrtmant; - end = ctx->cplendmant; fgain = ff_fgaintab[ctx->cplfgaincod]; snroffset = (((ctx->csnroffst - 15) << 4) + ctx->cplfsnroffst) << 2; - fastleak = (ctx->cplfleak << 8) + 768; - slowleak = (ctx->cplsleak << 8) + 768; - exps = ctx->dcplexps; - bap = ctx->cplbap; - if (ctx->cpldeltbae == DBA_NEW || ctx->deltbae == DBA_REUSE) { - do_delta = 1; - deltnseg = ctx->cpldeltnseg; - deltoffst = ctx->cpldeltoffst; - deltlen = ctx->cpldeltlen; - deltba = ctx->cpldeltba; - } + ac3_parametric_bit_allocation(&ctx->bit_alloc_params, ctx->cplbap, + ctx->dcplexps, ctx->cplstrtmant, + ctx->cplendmant, snroffset, fgain, 0, + ctx->cpldeltbae, ctx->cpldeltnseg, + ctx->cpldeltoffst, ctx->cpldeltlen, + ctx->cpldeltba); } else if (chnl == 6) { - start = 0; - end = 7; - lowcomp = 0; - fastleak = 0; - slowleak = 0; fgain = ff_fgaintab[ctx->lfefgaincod]; snroffset = (((ctx->csnroffst - 15) << 4) + ctx->lfefsnroffst) << 2; - exps = ctx->dlfeexps; - bap = ctx->lfebap; + ac3_parametric_bit_allocation(&ctx->bit_alloc_params, ctx->lfebap, + ctx->dlfeexps, 0, 7, snroffset, fgain, 1, + DBA_NONE, 0, NULL, NULL, NULL); } else { - start = 0; - end = ctx->endmant[chnl]; - lowcomp = 0; - fastleak = 0; - slowleak = 0; fgain = ff_fgaintab[ctx->fgaincod[chnl]]; snroffset = (((ctx->csnroffst - 15) << 4) + ctx->fsnroffst[chnl]) << 2; - exps = ctx->dexps[chnl]; - bap = ctx->bap[chnl]; - if (ctx->deltbae[chnl] == DBA_NEW || ctx->deltbae[chnl] == DBA_REUSE) { - do_delta = 1; - deltnseg = ctx->deltnseg[chnl]; - deltoffst = ctx->deltoffst[chnl]; - deltlen = ctx->deltlen[chnl]; - deltba = ctx->deltba[chnl]; - } - } - - for (bin = start; bin < end; bin++) /* exponent mapping into psd */ - psd[bin] = psdtab[exps[bin]]; - - /* psd integration */ - j = start; - k = masktab[start]; - do { - lastbin = FFMIN((bndtab[k] + ff_ac3_bndsz[k]), end); - bndpsd[k] = psd[j]; - j++; - for (i = j; i < lastbin; i++) { - bndpsd[k] = logadd(bndpsd[k], psd[j]); - j++; - } - k++; - } while (end > lastbin); - - /* compute the excite function */ - bndstrt = masktab[start]; - bndend = masktab[end - 1] + 1; - if (bndstrt == 0) { - lowcomp = calc_lowcomp(lowcomp, bndpsd[0], bndpsd[1], 0); - excite[0] = bndpsd[0] - fgain - lowcomp; - lowcomp = calc_lowcomp(lowcomp, bndpsd[1], bndpsd[2], 1); - excite[1] = bndpsd[1] - fgain - lowcomp; - begin = 7; - for (bin = 2; bin < 7; bin++) { - if ((bndend != 7) || (bin != 6)) - lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin + 1], bin); - fastleak = bndpsd[bin] - fgain; - slowleak = bndpsd[bin] - sgain; - excite[bin] = fastleak - lowcomp; - if ((bndend != 7) || (bin != 6)) - if (bndpsd[bin] <= bndpsd[bin + 1]) { - begin = bin + 1; - break; - } - } - 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; - fastleak = FFMAX(fastleak, (bndpsd[bin] - fgain)); - slowleak -= sdecay; - slowleak = FFMAX(slowleak, (bndpsd[bin] - sgain)); - excite[bin] = FFMAX((fastleak - lowcomp), slowleak); - } - begin = 22; - } - else { - begin = bndstrt; - } - for (bin = begin; bin < bndend; bin++) { - fastleak -= fdecay; - fastleak = FFMAX(fastleak, (bndpsd[bin] - fgain)); - slowleak -= sdecay; - slowleak = FFMAX(slowleak, (bndpsd[bin] - sgain)); - excite[bin] = FFMAX(fastleak, slowleak); + ac3_parametric_bit_allocation(&ctx->bit_alloc_params, ctx->bap[chnl], + ctx->dexps[chnl], 0, ctx->endmant[chnl], + snroffset, fgain, 0, ctx->deltbae[chnl], + ctx->deltnseg[chnl], ctx->deltoffst[chnl], + ctx->deltlen[chnl], ctx->deltba[chnl]); } - - /* compute the masking curve */ - for (bin = bndstrt; bin < bndend; bin++) { - if (bndpsd[bin] < dbknee) - excite[bin] += ((dbknee - bndpsd[bin]) >> 2); - mask[bin] = FFMAX(excite[bin], ff_ac3_hth[bin][fscod]); - } - - /* apply the delta bit allocation */ - if (do_delta) { - band = 0; - for (seg = 0; seg < deltnseg + 1; seg++) { - band += deltoffst[seg]; - if (deltba[seg] >= 4) - delta = (deltba[seg] - 3) << 7; - else - delta = (deltba[seg] - 4) << 7; - for (k = 0; k < deltlen[seg]; k++) { - mask[band] += delta; - band++; - } - } - } - - /*compute the bit allocation */ - i = start; - j = masktab[start]; - do { - lastbin = FFMIN((bndtab[j] + ff_ac3_bndsz[j]), end); - mask[j] -= snroffset; - mask[j] -= floor; - if (mask[j] < 0) - mask[j] = 0; - mask[j] &= 0x1fe0; - mask[j] += floor; - for (k = i; k < lastbin; k++) { - address = (psd[i] - mask[j]) >> 5; - address = FFMIN(63, (FFMAX(0, address))); - bap[i] = ff_ac3_baptab[address]; - i++; - } - j++; - } while (end > lastbin); } /* Check if snroffsets are zero. */ @@ -1856,6 +1685,17 @@ static int ac3_parse_audio_block(AC3DecodeContext * ctx) for (i = 0; i < nfchans; i++) memset(ctx->bap[i], 0, sizeof(ctx->bap[i])); } else { + /* set bit allocation parameters */ + ctx->bit_alloc_params.fscod = ctx->fscod; + ctx->bit_alloc_params.halfratecod = 0; + ctx->bit_alloc_params.sdecay = ff_sdecaytab[ctx->sdcycod]; + ctx->bit_alloc_params.fdecay = ff_fdecaytab[ctx->fdcycod]; + ctx->bit_alloc_params.sgain = ff_sgaintab[ctx->sgaincod]; + ctx->bit_alloc_params.dbknee = ff_dbkneetab[ctx->dbpbcod]; + ctx->bit_alloc_params.floor = ff_floortab[ctx->floorcod]; + ctx->bit_alloc_params.cplfleak = ctx->cplfleak; + ctx->bit_alloc_params.cplsleak = ctx->cplsleak; + if (ctx->chincpl && (bit_alloc_flags & 64)) do_bit_allocation(ctx, 5); for (i = 0; i < nfchans; i++) |