|
|
|
@ -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++) |
|
|
|
|