mirror of https://github.com/mstorsjo/fdk-aac.git
Revise scaling in extractBBEnv() to avoid potential signed integer overflows.
Bug: 146936823 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I268f4ed2778ffad6cbd90e1df627daf2eab97604
This commit is contained in:
parent
ed5a207a1f
commit
3070b0e81b
|
@ -1,7 +1,7 @@
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||||
|
|
||||||
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
|
||||||
Forschung e.V. All rights reserved.
|
Forschung e.V. All rights reserved.
|
||||||
|
|
||||||
1. INTRODUCTION
|
1. INTRODUCTION
|
||||||
|
@ -162,75 +162,59 @@ static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal,
|
||||||
FIXP_DBL nrg;
|
FIXP_DBL nrg;
|
||||||
|
|
||||||
/* qs = 12, 13, 14 */
|
/* qs = 12, 13, 14 */
|
||||||
slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) +
|
slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) +
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
(SF_FACTOR_SLOT - 1));
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) +
|
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
/* qs = 15 */
|
/* qs = 15 */
|
||||||
slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) +
|
slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
/* qs = 16, 17 */
|
/* qs = 16, 17 */
|
||||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
slotNrg[4] =
|
||||||
slotNrg[4] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
/* qs = 18, 19, 20 */
|
/* qs = 18, 19, 20 */
|
||||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
slotNrg[5] =
|
||||||
(SF_FACTOR_SLOT - 1));
|
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
slotNrg[5] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
/* qs = 21, 22 */
|
/* qs = 21, 22 */
|
||||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
slotNrg[6] =
|
||||||
slotNrg[6] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
/* qs = 23, 24 */
|
/* qs = 23, 24 */
|
||||||
if (hybBands > 23) {
|
if (hybBands > 23) {
|
||||||
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) +
|
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) +
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
/* qs = 25, 26, 29, 28, 29 */
|
/* qs = 25, 26, 29, 28, 29 */
|
||||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
(SF_FACTOR_SLOT - 1));
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
slotNrg[7] =
|
||||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
slotNrg[7] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
|
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
/* qs = 30 ... min(41,hybBands-1) */
|
/* qs = 30 ... min(41,hybBands-1) */
|
||||||
nrg = ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
for (qs = 31; qs < hybBands; qs++) {
|
for (qs = 31; qs < hybBands; qs++) {
|
||||||
nrg += ((fPow2Div2((*pReal++) << maxValSF) +
|
nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
|
||||||
fPow2Div2((*pImag++) << maxValSF)) >>
|
(fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
|
||||||
(SF_FACTOR_SLOT - 1));
|
|
||||||
}
|
}
|
||||||
slotNrg[8] = nrg;
|
slotNrg[8] = nrg;
|
||||||
} else {
|
} else {
|
||||||
|
@ -239,49 +223,22 @@ static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline INT getMaxValDmx(FIXP_DBL *RESTRICT pReal,
|
static inline void combineDryWet(FIXP_DBL *RESTRICT pReal,
|
||||||
FIXP_DBL *RESTRICT pImag, INT cplxBands,
|
|
||||||
INT hybBands) {
|
|
||||||
INT qs, clz;
|
|
||||||
FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
|
|
||||||
|
|
||||||
for (qs = 12; qs < cplxBands; qs++) {
|
|
||||||
maxVal |= fAbs(pReal[qs]);
|
|
||||||
maxVal |= fAbs(pImag[qs]);
|
|
||||||
}
|
|
||||||
for (; qs < hybBands; qs++) {
|
|
||||||
maxVal |= fAbs(pReal[qs]);
|
|
||||||
}
|
|
||||||
|
|
||||||
clz = fixMax(0, CntLeadingZeros(maxVal) - 1);
|
|
||||||
|
|
||||||
return (clz);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline INT getMaxValDryWet(FIXP_DBL *RESTRICT pReal,
|
|
||||||
FIXP_DBL *RESTRICT pImag,
|
FIXP_DBL *RESTRICT pImag,
|
||||||
FIXP_DBL *RESTRICT pHybOutputRealDry,
|
FIXP_DBL *RESTRICT pHybOutputRealDry,
|
||||||
FIXP_DBL *RESTRICT pHybOutputImagDry,
|
FIXP_DBL *RESTRICT pHybOutputImagDry,
|
||||||
FIXP_DBL *RESTRICT pHybOutputRealWet,
|
FIXP_DBL *RESTRICT pHybOutputRealWet,
|
||||||
FIXP_DBL *RESTRICT pHybOutputImagWet,
|
FIXP_DBL *RESTRICT pHybOutputImagWet,
|
||||||
INT cplxBands, INT hybBands) {
|
INT cplxBands, INT hybBands) {
|
||||||
INT qs, clz;
|
INT qs;
|
||||||
FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
|
|
||||||
|
|
||||||
for (qs = 12; qs < cplxBands; qs++) {
|
for (qs = 12; qs < cplxBands; qs++) {
|
||||||
pReal[qs] = pHybOutputRealDry[qs] + pHybOutputRealWet[qs];
|
pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
|
||||||
maxVal |= fAbs(pReal[qs]);
|
pImag[qs] = (pHybOutputImagDry[qs] >> 1) + (pHybOutputImagWet[qs] >> 1);
|
||||||
pImag[qs] = pHybOutputImagDry[qs] + pHybOutputImagWet[qs];
|
|
||||||
maxVal |= fAbs(pImag[qs]);
|
|
||||||
}
|
}
|
||||||
for (; qs < hybBands; qs++) {
|
for (; qs < hybBands; qs++) {
|
||||||
pReal[qs] = pHybOutputRealDry[qs] + pHybOutputRealWet[qs];
|
pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
|
||||||
maxVal |= fAbs(pReal[qs]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clz = fixMax(0, CntLeadingZeros(maxVal) - 1);
|
|
||||||
|
|
||||||
return (clz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry,
|
static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry,
|
||||||
|
@ -386,15 +343,18 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
|
||||||
prevChOffs = ch;
|
prevChOffs = ch;
|
||||||
pReal = pScratchBuffer;
|
pReal = pScratchBuffer;
|
||||||
pImag = pScratchBuffer + 42;
|
pImag = pScratchBuffer + 42;
|
||||||
clz = getMaxValDryWet(
|
combineDryWet(pReal, pImag, self->hybOutputRealDry__FDK[ch],
|
||||||
pReal, pImag, self->hybOutputRealDry__FDK[ch],
|
self->hybOutputImagDry__FDK[ch],
|
||||||
self->hybOutputImagDry__FDK[ch], self->hybOutputRealWet__FDK[ch],
|
self->hybOutputRealWet__FDK[ch],
|
||||||
self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
|
self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
|
||||||
|
clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
|
||||||
|
getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
|
||||||
} else {
|
} else {
|
||||||
prevChOffs = ch + self->numOutputChannels;
|
prevChOffs = ch + self->numOutputChannels;
|
||||||
pReal = self->hybInputReal__FDK[ch];
|
pReal = self->hybInputReal__FDK[ch];
|
||||||
pImag = self->hybInputImag__FDK[ch];
|
pImag = self->hybInputImag__FDK[ch];
|
||||||
clz = getMaxValDmx(pReal, pImag, cplxBands, hybBands);
|
clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
|
||||||
|
getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
|
||||||
}
|
}
|
||||||
|
|
||||||
partNrg = partNrgPrev = pBBEnvState->partNrgPrev__FDK[prevChOffs];
|
partNrg = partNrgPrev = pBBEnvState->partNrgPrev__FDK[prevChOffs];
|
||||||
|
@ -411,8 +371,10 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
|
||||||
SF_FACTOR_SLOT */
|
SF_FACTOR_SLOT */
|
||||||
}
|
}
|
||||||
|
|
||||||
slotNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT;
|
slotNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
|
||||||
frameNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT;
|
SF_FACTOR_SLOT;
|
||||||
|
frameNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
|
||||||
|
SF_FACTOR_SLOT;
|
||||||
|
|
||||||
partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1,
|
partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1,
|
||||||
pPartNrgPrevSF[0] - pPartNrgPrev2SF[0] + 1);
|
pPartNrgPrevSF[0] - pPartNrgPrev2SF[0] + 1);
|
||||||
|
|
Loading…
Reference in New Issue