]> granicus.if.org Git - libvpx/commitdiff
Temporarily convert to 64 bits to avoid overflows
authorJorge E. Moreira <jemoreira@google.com>
Fri, 8 May 2020 22:23:48 +0000 (15:23 -0700)
committerJorge Moreira Broche <jemoreira@google.com>
Mon, 11 May 2020 21:29:18 +0000 (21:29 +0000)
In the vp8_cost_branch function a couple of unsigned int are being
multiplied by integer coefficients and added to later be divided by
256. While the end result most likely fits an unsigned int, the
intermediary result of multiplying and adding sometimes doesn't (I was
able to reproduce it by leaving the encoder running at 60 fps for a
while). To avoid the multiplication overflow (which is undefined
behavior and causes a wrong result anyways) the calculation is
performed using unsigned long long instead and cast to unsigned int
for return.

Bug: b/154172422
Test: run cuttlefish with webrtc enabled for an hour
Change-Id: If7ebbda38b2450a59ed3c99ffbb59dc62431a324

vp8/encoder/treewriter.h

index c02683a58b785597deeefff243c12fd07c1ff147..4e9ed6af17cdd9850ce2a79cf269c3cb54e304ec 100644 (file)
@@ -14,6 +14,8 @@
 /* Trees map alphabets into huffman-like codes suitable for an arithmetic
    bit coder.  Timothy S Murphy  11 October 2004 */
 
+#include <stdint.h>
+
 #include "./vpx_config.h"
 #include "vp8/common/treecoder.h"
 
@@ -48,7 +50,9 @@ static INLINE unsigned int vp8_cost_branch(const unsigned int ct[2],
                                            vp8_prob p) {
   /* Imitate existing calculation */
 
-  return ((ct[0] * vp8_cost_zero(p)) + (ct[1] * vp8_cost_one(p))) >> 8;
+  return (unsigned int)(((((uint64_t)ct[0]) * vp8_cost_zero(p)) +
+                         (((uint64_t)ct[1]) * vp8_cost_one(p))) >>
+                        8);
 }
 
 /* Small functions to write explicit values and tokens, as well as