Fix for integer overflow in NetEq.
BUG=chromium:668736
Review-Url: https://codereview.webrtc.org/2571483002
Cr-Commit-Position: refs/heads/master@{#15654}
diff --git a/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest.cc
index 863dcd1..be5e2c5 100644
--- a/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest.cc
+++ b/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest.cc
@@ -977,31 +977,31 @@
#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) && \
defined(WEBRTC_CODEC_ILBC) && defined(WEBRTC_CODEC_G722)
TEST_F(AcmReceiverBitExactnessOldApi, 8kHzOutput) {
- Run(8000, PlatformChecksum("dce4890259e9ded50f472455aa470a6f",
- "1c4ada78b12612147f3026920f8dcc14",
- "d804791edf2d00be2bc31c81a47368d4",
- "b2611f7323ab1209d5056399d0babbf5"));
+ Run(8000, PlatformChecksum("25cda36a1b967e75c0eb580924247681",
+ "bbfe6a07f8bca872b5370885825ee061",
+ "d5b9ae44d03dbd7c921dd9c228e03cc5",
+ "4d851d1f2e4b8a2f1727fac8fba4b1e1"));
}
TEST_F(AcmReceiverBitExactnessOldApi, 16kHzOutput) {
- Run(16000, PlatformChecksum("27356bddffaa42b5c841b49aa3a070c5",
- "5667d1872fc351244092ae995e5a5b32",
- "53f5dc8088148479ca112c4c6d0e91cb",
- "4061a876d64d6cec5a38450acf4f245d"));
+ Run(16000, PlatformChecksum("9c7b6f586c4b9d6d0195372660991353",
+ "1ab45baa674e681ec394e0d3824d8605",
+ "dd4e7f2521b5f47c0016b12f06c08695",
+ "5401b64b6dbe7f090f846e89b0d858ce"));
}
TEST_F(AcmReceiverBitExactnessOldApi, 32kHzOutput) {
- Run(32000, PlatformChecksum("eb326547e83292305423b0a7ea57fea1",
- "be7fc3140e6b5188c2e5fae0a394543b",
- "eab9a0bff17320d6457d04f4c56563c6",
- "b60241ef0bac4a75f66eead04e71bb12"));
+ Run(32000, PlatformChecksum("599b9484ca89615641ebd767cccb149f",
+ "9f7d51569647eff38026dd815d43ca91",
+ "78d00d2a3f8f307fc3835ca588a18f3a",
+ "d335eebc72f4d087aa397a9cf8f4967b"));
}
TEST_F(AcmReceiverBitExactnessOldApi, 48kHzOutput) {
- Run(48000, PlatformChecksum("7eb79ea39b68472a5b04cf9a56e49cda",
- "f8cdd6e018688b2fff25c9b865bebdbb",
- "2d18f0f06e7e2fc63b74d06e3c58067f",
- "81c3e4d24ebec23ca48f42fbaec4aba0"));
+ Run(48000, PlatformChecksum("5d3b4357c9044264bb4a601b6548bd55",
+ "8607778183d7ad02b8ce37eeeba4f37c",
+ "fd71398d336b88cbd4fb5002846e91c6",
+ "8ce7e0e1c381d920ee7b57751b257de8"));
}
TEST_F(AcmReceiverBitExactnessOldApi, 48kHzOutputExternalDecoder) {
@@ -1077,10 +1077,10 @@
rtc::scoped_refptr<rtc::RefCountedObject<ADFactory>> factory(
new rtc::RefCountedObject<ADFactory>);
- Run(48000, PlatformChecksum("7eb79ea39b68472a5b04cf9a56e49cda",
- "f8cdd6e018688b2fff25c9b865bebdbb",
- "2d18f0f06e7e2fc63b74d06e3c58067f",
- "81c3e4d24ebec23ca48f42fbaec4aba0"),
+ Run(48000, PlatformChecksum("5d3b4357c9044264bb4a601b6548bd55",
+ "8607778183d7ad02b8ce37eeeba4f37c",
+ "fd71398d336b88cbd4fb5002846e91c6",
+ "8ce7e0e1c381d920ee7b57751b257de8"),
factory, [](AudioCodingModule* acm) {
acm->RegisterReceiveCodec(0, {"MockPCMu", 8000, 1});
});
diff --git a/webrtc/modules/audio_coding/neteq/expand.cc b/webrtc/modules/audio_coding/neteq/expand.cc
index ffe4370..da870d7 100644
--- a/webrtc/modules/audio_coding/neteq/expand.cc
+++ b/webrtc/modules/audio_coding/neteq/expand.cc
@@ -675,12 +675,20 @@
parameters.ar_filter,
kUnvoicedLpcOrder + 1,
128);
- int16_t unvoiced_prescale;
- if (WebRtcSpl_MaxAbsValueW16(unvoiced_vector, 128) > 4000) {
- unvoiced_prescale = 4;
- } else {
- unvoiced_prescale = 0;
- }
+ const int unvoiced_max_abs = [&] {
+ const int16_t max_abs = WebRtcSpl_MaxAbsValueW16(unvoiced_vector, 128);
+ // Since WebRtcSpl_MaxAbsValueW16 returns 2^15 - 1 when the input contains
+ // -2^15, we have to conservatively bump the return value by 1
+ // if it is 2^15 - 1.
+ return max_abs == WEBRTC_SPL_WORD16_MAX ? max_abs + 1 : max_abs;
+ }();
+ // Pick the smallest n such that 2^n > unvoiced_max_abs; then the maximum
+ // value of the dot product is less than 2^7 * 2^(2*n) = 2^(2*n + 7), so to
+ // prevent overflows we want 2n + 7 <= 31, which means we should shift by
+ // 2n + 7 - 31 bits, if this value is greater than zero.
+ int unvoiced_prescale =
+ std::max(0, 2 * WebRtcSpl_GetSizeInBits(unvoiced_max_abs) - 24);
+
int32_t unvoiced_energy = WebRtcSpl_DotProductWithScale(unvoiced_vector,
unvoiced_vector,
128,
diff --git a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc
index b958e27..ecefc45 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc
@@ -442,10 +442,10 @@
webrtc::test::ResourcePath("audio_coding/neteq_universal_new", "rtp");
const std::string output_checksum = PlatformChecksum(
- "acd33f5c73625c1529c412ad59b5565132826f1b",
- "1a2e82a0410421c1d1d3eb0615334db5e2c63784",
- "acd33f5c73625c1529c412ad59b5565132826f1b",
- "52797b781758a1d2303140b80b9c5030c9093d6b");
+ "5a8184bc60c0d7dddb50af8966360675476a8d8b",
+ "be982d2c5685dd1ca4ea5d352283df50e8e5b46d",
+ "5a8184bc60c0d7dddb50af8966360675476a8d8b",
+ "c86aec95439748f4949de95b50c94be291118615");
const std::string network_stats_checksum = PlatformChecksum(
"f59b3dfdb9b1b8bbb61abedd7c8cf3fc47c21f5f",