use shared ac3 bit allocation function

Originally committed as revision 9684 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Justin Ruggles 2007-07-15 13:53:42 +00:00
parent 8749180c3b
commit 623b79435d

View File

@ -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];
}
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]);
}
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);
}
/* 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++)