aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFraunhofer IIS FDK <audio-fdk@iis.fraunhofer.de>2021-03-16 14:50:24 +0100
committerJean-Michel Trivi <jmtrivi@google.com>2021-05-07 10:56:07 -0700
commit56de8e29ce7b5c86b1ba7cac9b3286b4a900642f (patch)
tree64127cca84080d6eed0afbf6d303ee94c9100e6f
parent773ff1d3e8921ed2c9d2def344cf4b6b47f861c8 (diff)
downloadfdk-aac-56de8e29ce7b5c86b1ba7cac9b3286b4a900642f.tar.gz
fdk-aac-56de8e29ce7b5c86b1ba7cac9b3286b4a900642f.tar.bz2
fdk-aac-56de8e29ce7b5c86b1ba7cac9b3286b4a900642f.zip
Utilize dynamic scaling in slotAmp() to avoid signed integer overflows.
Bug: 186777497 Test: atest android.media.cts.DecoderTestAacFormat android.media.cts.DecoderTestXheAac android.media.cts.DecoderTestAacDrc Change-Id: Ia66fbbd16dec4f9e04d67463cca91d75f3741131
-rw-r--r--libSACdec/src/sac_reshapeBBEnv.cpp77
1 files changed, 54 insertions, 23 deletions
diff --git a/libSACdec/src/sac_reshapeBBEnv.cpp b/libSACdec/src/sac_reshapeBBEnv.cpp
index 272d009..72f4e58 100644
--- a/libSACdec/src/sac_reshapeBBEnv.cpp
+++ b/libSACdec/src/sac_reshapeBBEnv.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -241,29 +241,56 @@ static inline void combineDryWet(FIXP_DBL *RESTRICT pReal,
}
}
-static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry,
- FIXP_DBL *RESTRICT slotAmp_wet,
- FIXP_DBL *RESTRICT pHybOutputRealDry,
- FIXP_DBL *RESTRICT pHybOutputImagDry,
- FIXP_DBL *RESTRICT pHybOutputRealWet,
- FIXP_DBL *RESTRICT pHybOutputImagWet, INT cplxBands,
- INT hybBands) {
- INT qs;
+static inline void slotAmp(
+ FIXP_DBL *RESTRICT slotAmp_dry, INT *RESTRICT slotAmp_dry_e,
+ FIXP_DBL *RESTRICT slotAmp_wet, INT *RESTRICT slotAmp_wet_e,
+ FIXP_DBL *RESTRICT pHybOutputRealDry, FIXP_DBL *RESTRICT pHybOutputImagDry,
+ FIXP_DBL *RESTRICT pHybOutputRealWet, FIXP_DBL *RESTRICT pHybOutputImagWet,
+ INT cplxBands, INT hybBands) {
+ INT qs, s1, s2, headroom_dry, headroom_wet;
FIXP_DBL dry, wet;
+ /* headroom can be reduced by 1 bit due to use of fPow2Div2 */
+ s1 = DFRACT_BITS - 1 - CntLeadingZeros(hybBands + cplxBands);
+ headroom_dry = fMin(getScalefactor(pHybOutputRealDry, hybBands),
+ getScalefactor(pHybOutputImagDry, cplxBands));
+ headroom_wet = fMin(getScalefactor(pHybOutputRealWet, hybBands),
+ getScalefactor(pHybOutputImagWet, cplxBands));
+
dry = wet = FL2FXCONST_DBL(0.0f);
for (qs = 0; qs < cplxBands; qs++) {
- dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)) +
- fPow2Div2(pHybOutputImagDry[qs] << (1)));
- wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)) +
- fPow2Div2(pHybOutputImagWet[qs] << (1)));
+ /* sum up dry part */
+ dry += (fPow2Div2(pHybOutputRealDry[qs] << headroom_dry) >> s1);
+ dry += (fPow2Div2(pHybOutputImagDry[qs] << headroom_dry) >> s1);
+ /* sum up wet part */
+ wet += (fPow2Div2(pHybOutputRealWet[qs] << headroom_wet) >> s1);
+ wet += (fPow2Div2(pHybOutputImagWet[qs] << headroom_wet) >> s1);
}
for (; qs < hybBands; qs++) {
- dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)));
- wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)));
+ dry += (fPow2Div2(pHybOutputRealDry[qs] << headroom_dry) >> s1);
+ wet += (fPow2Div2(pHybOutputRealWet[qs] << headroom_wet) >> s1);
+ }
+
+ /* consider fPow2Div2() */
+ s1 += 1;
+
+ /* normalize dry part, ensure that exponent is even */
+ s2 = fixMax(0, CntLeadingZeros(dry) - 1);
+ *slotAmp_dry = dry << s2;
+ *slotAmp_dry_e = s1 - s2 - 2 * headroom_dry;
+ if (*slotAmp_dry_e & 1) {
+ *slotAmp_dry = *slotAmp_dry >> 1;
+ *slotAmp_dry_e += 1;
+ }
+
+ /* normalize wet part, ensure that exponent is even */
+ s2 = fixMax(0, CntLeadingZeros(wet) - 1);
+ *slotAmp_wet = wet << s2;
+ *slotAmp_wet_e = s1 - s2 - 2 * headroom_wet;
+ if (*slotAmp_wet_e & 1) {
+ *slotAmp_wet = *slotAmp_wet >> 1;
+ *slotAmp_wet_e += 1;
}
- *slotAmp_dry = dry >> (2 * (1));
- *slotAmp_wet = wet >> (2 * (1));
}
#if defined(__aarch64__)
@@ -533,6 +560,7 @@ void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
INT ts) {
INT ch, scale;
INT dryFacSF, slotAmpSF;
+ INT slotAmp_dry_e, slotAmp_wet_e;
FIXP_DBL tmp, dryFac, envShape;
FIXP_DBL slotAmp_dry, slotAmp_wet, slotAmp_ratio;
FIXP_DBL envDry[MAX_OUTPUT_CHANNELS], envDmx[2];
@@ -594,22 +622,25 @@ void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
dryFacSF = SF_SHAPE + 2 * dryFacSF;
}
+ slotAmp_dry_e = slotAmp_wet_e = 0;
+
/* calculate slotAmp_dry and slotAmp_wet */
- slotAmp(&slotAmp_dry, &slotAmp_wet, &self->hybOutputRealDry__FDK[ch][6],
+ slotAmp(&slotAmp_dry, &slotAmp_dry_e, &slotAmp_wet, &slotAmp_wet_e,
+ &self->hybOutputRealDry__FDK[ch][6],
&self->hybOutputImagDry__FDK[ch][6],
&self->hybOutputRealWet__FDK[ch][6],
&self->hybOutputImagWet__FDK[ch][6], cplxBands, hybBands);
+ /* exponents must be even due to subsequent square root calculation */
+ FDK_ASSERT(((slotAmp_dry_e & 1) == 0) && ((slotAmp_wet_e & 1) == 0));
+
/* slotAmp_ratio will be scaled by slotAmpSF bits */
if (slotAmp_dry != FL2FXCONST_DBL(0.0f)) {
- sc = fixMax(0, CntLeadingZeros(slotAmp_wet) - 1);
- sc = sc - (sc & 1);
-
- slotAmp_wet = sqrtFixp(slotAmp_wet << sc);
+ slotAmp_wet = sqrtFixp(slotAmp_wet);
slotAmp_dry = invSqrtNorm2(slotAmp_dry, &slotAmpSF);
slotAmp_ratio = fMult(slotAmp_wet, slotAmp_dry);
- slotAmpSF = slotAmpSF - (sc >> 1);
+ slotAmpSF = slotAmpSF + (slotAmp_wet_e >> 1) - (slotAmp_dry_e >> 1);
}
/* calculate common scale factor */