use shared ac3 bit allocation function
Originally committed as revision 9684 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
8749180c3b
commit
623b79435d
@ -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++)
|
||||
|
Loading…
x
Reference in New Issue
Block a user