aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>2015-11-18 13:43:01 +0100
committerAndreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>2015-12-17 20:03:48 +0100
commitb9087aa651674ce94853d824aedb1691d75bd9fd (patch)
treeffca8aea1768ec86e702742b91c3f1366bdbd3d9
parent7e94ea3dd1e5cbf56926c2b769738a0a51bd35bc (diff)
downloadffmpeg-b9087aa651674ce94853d824aedb1691d75bd9fd.tar.gz
sbr_qmf_analysis: sanitize input for 32-bit imdct
If the input contains too many too large values, the imdct can overflow. Even if it didn't, the output would be larger than the valid range of 29 bits. Note that this is a very delicate limit: Allowing values up to 1<<25 does not prevent input larger than 1<<29 from arriving at sbr_sum_square, while limiting values to 1<<23 breaks the fate-aac-fixed-al_sbr_hq_cm_48_5.1 test. Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com> (cherry picked from commit fdc94db37e89165964fdf34f1cd7632e44108bd0) Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
-rw-r--r--libavcodec/aacsbr_template.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/libavcodec/aacsbr_template.c b/libavcodec/aacsbr_template.c
index 4f845ee6f8..b36c266ad1 100644
--- a/libavcodec/aacsbr_template.c
+++ b/libavcodec/aacsbr_template.c
@@ -1154,6 +1154,9 @@ static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
INTFLOAT z[320], INTFLOAT W[2][32][32][2], int buf_idx)
{
int i;
+#if USE_FIXED
+ int j;
+#endif
memcpy(x , x+1024, (320-32)*sizeof(x[0]));
memcpy(x+288, in, 1024*sizeof(x[0]));
for (i = 0; i < 32; i++) { // numTimeSlots*RATE = 16*2 as 960 sample frames
@@ -1161,6 +1164,21 @@ static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
dsp->vector_fmul_reverse(z, sbr_qmf_window_ds, x, 320);
sbrdsp->sum64x5(z);
sbrdsp->qmf_pre_shuffle(z);
+#if USE_FIXED
+ for (j = 64; j < 128; j++) {
+ if (z[j] > 1<<24) {
+ av_log(NULL, AV_LOG_WARNING,
+ "sbr_qmf_analysis: value %09d too large, setting to %09d\n",
+ z[j], 1<<24);
+ z[j] = 1<<24;
+ } else if (z[j] < -(1<<24)) {
+ av_log(NULL, AV_LOG_WARNING,
+ "sbr_qmf_analysis: value %09d too small, setting to %09d\n",
+ z[j], -(1<<24));
+ z[j] = -(1<<24);
+ }
+ }
+#endif
mdct->imdct_half(mdct, z, z+64);
sbrdsp->qmf_post_shuffle(W[buf_idx][i], z);
x += 32;