aboutsummaryrefslogtreecommitdiffstats
path: root/libSACdec/src
diff options
context:
space:
mode:
authorFraunhofer IIS FDK <audio-fdk@iis.fraunhofer.de>2019-10-29 13:07:42 +0100
committerJean-Michel Trivi <jmtrivi@google.com>2019-12-27 09:03:39 -0800
commit110e4ca996edb074e2b0071d63472bf26f0a6dd8 (patch)
treef9d9ad7a3675e23372c5a78ecede8bcc479dd797 /libSACdec/src
parentee6c6fa4ba104941150998d53792af80ab9b3b5a (diff)
downloadfdk-aac-110e4ca996edb074e2b0071d63472bf26f0a6dd8.tar.gz
fdk-aac-110e4ca996edb074e2b0071d63472bf26f0a6dd8.tar.bz2
fdk-aac-110e4ca996edb074e2b0071d63472bf26f0a6dd8.zip
Avoid signed integer overflow in subbandTPApply() dry energy calculation.
Bug: 145668819 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I4f61efa70e77ae64b99fe7cafbc2b43f5cc09b06
Diffstat (limited to 'libSACdec/src')
-rw-r--r--libSACdec/src/sac_stp.cpp61
1 files changed, 41 insertions, 20 deletions
diff --git a/libSACdec/src/sac_stp.cpp b/libSACdec/src/sac_stp.cpp
index 17e4472..b6e5947 100644
--- a/libSACdec/src/sac_stp.cpp
+++ b/libSACdec/src/sac_stp.cpp
@@ -106,6 +106,8 @@ amm-info@iis.fraunhofer.de
#include "FDK_matrixCalloc.h"
#include "sac_rom.h"
+#define SF_FREQ_DOMAIN_HEADROOM (2 * (1))
+
#define BP_GF_START 6
#define BP_GF_SIZE 25
#define HP_SIZE 9
@@ -114,6 +116,11 @@ amm-info@iis.fraunhofer.de
#define SF_WET 5
#define SF_DRY \
3 /* SF_DRY == 2 would produce good conformance test results as well */
+#define SF_DRY_NRG \
+ (4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \
+ i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \
+ calculation needs 4 bits headroom, headroom can be reduced by 1 \
+ bit due to fPow2Div2() usage */
#define SF_PRODUCT_BP_GF 13
#define SF_PRODUCT_BP_GF_GF 26
#define SF_SCALE 2
@@ -172,18 +179,8 @@ amm-info@iis.fraunhofer.de
STP_SCALE_LIMIT_LO_LD64 = LD64(STP_SCALE_LIMIT_LO*STP_SCALE_LIMIT_LO)
*/
-#define DRY_ENER_WEIGHT(DryEner) DryEner = DryEner >> dry_scale_dmx
-
#define WET_ENER_WEIGHT(WetEner) WetEner = WetEner << wet_scale_dmx
-#define DRY_ENER_SUM_REAL(DryEner, dmxReal, n) \
- DryEner += \
- fMultDiv2(fPow2Div2(dmxReal << SF_DRY), pBP[n]) >> ((2 * SF_DRY) - 2)
-
-#define DRY_ENER_SUM_CPLX(DryEner, dmxReal, dmxImag, n) \
- DryEner += fMultDiv2( \
- fPow2Div2(dmxReal << SF_DRY) + fPow2Div2(dmxImag << SF_DRY), pBP[n])
-
#define CALC_WET_SCALE(dryIdx, wetIdx) \
if ((DryEnerLD64[dryIdx] - STP_SCALE_LIMIT_HI_LD64) > WetEnerLD64[wetIdx]) { \
scale[wetIdx] = STP_SCALE_LIMIT_HI; \
@@ -362,7 +359,12 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
{
cplxBands = BP_GF_SIZE;
cplxHybBands = self->hybridBands;
- dry_scale_dmx = (2 * SF_DRY) - 2;
+ if (self->treeConfig == TREE_212) {
+ dry_scale_dmx = 2; /* 2 bits to compensate fMultDiv2() and fPow2Div2()
+ used in energy calculation */
+ } else {
+ dry_scale_dmx = (2 * SF_DRY) - 2;
+ }
wet_scale_dmx = 2;
}
@@ -409,12 +411,33 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
pBP = hStpDec->BP_GF - BP_GF_START;
switch (self->treeConfig) {
case TREE_212:
+ INT sMin, sNorm, sReal, sImag;
+
+ sReal = fMin(getScalefactor(&qmfOutputRealDry[i_LF][BP_GF_START],
+ cplxBands - BP_GF_START),
+ getScalefactor(&qmfOutputRealDry[i_RF][BP_GF_START],
+ cplxBands - BP_GF_START));
+ sImag = fMin(getScalefactor(&qmfOutputImagDry[i_LF][BP_GF_START],
+ cplxBands - BP_GF_START),
+ getScalefactor(&qmfOutputImagDry[i_RF][BP_GF_START],
+ cplxBands - BP_GF_START));
+ sMin = fMin(sReal, sImag) - 1;
+
for (n = BP_GF_START; n < cplxBands; n++) {
- dmxReal0 = qmfOutputRealDry[i_LF][n] + qmfOutputRealDry[i_RF][n];
- dmxImag0 = qmfOutputImagDry[i_LF][n] + qmfOutputImagDry[i_RF][n];
- DRY_ENER_SUM_CPLX(DryEner0, dmxReal0, dmxImag0, n);
+ dmxReal0 = scaleValue(qmfOutputRealDry[i_LF][n], sMin) +
+ scaleValue(qmfOutputRealDry[i_RF][n], sMin);
+ dmxImag0 = scaleValue(qmfOutputImagDry[i_LF][n], sMin) +
+ scaleValue(qmfOutputImagDry[i_RF][n], sMin);
+
+ DryEner0 += (fMultDiv2(fPow2Div2(dmxReal0), pBP[n]) +
+ fMultDiv2(fPow2Div2(dmxImag0), pBP[n])) >>
+ SF_DRY_NRG;
}
- DRY_ENER_WEIGHT(DryEner0);
+
+ sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_DRY_NRG + dry_scale_dmx -
+ (2 * sMin) + nrgScale;
+ DryEner0 = scaleValueSaturate(
+ DryEner0, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
break;
default:;
}
@@ -422,7 +445,7 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
/* normalise the 'direct' signals */
for (ch = 0; ch < self->numInputChannels; ch++) {
- DryEner[ch] = DryEner[ch] << (nrgScale);
+ if (self->treeConfig != TREE_212) DryEner[ch] = DryEner[ch] << nrgScale;
hStpDec->runDryEner[ch] =
fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) +
fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]);
@@ -434,10 +457,8 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
}
}
- if (self->treeConfig == TREE_212) {
- for (; ch < MAX_INPUT_CHANNELS; ch++) {
- DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
- }
+ for (; ch < MAX_INPUT_CHANNELS; ch++) {
+ DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
}
/* normalise the 'diffuse' signals */