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/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,