shithub: dav1d

Download patch

ref: 5186abdba5cbdec208ced5fe51d47ed307287e33
parent: 8eed0b67610b91b82c46c639079f7f14e5a08704
author: Luc Trudeau <[email protected]>
date: Thu Oct 18 17:58:03 EDT 2018

Avoid calling get_uniform(max=1)

Calling get_uniform(max=1) results in a read_bits(n=0),
In get_uniform, the n param is renamed to max to clarify the
semantics. Asserts are added to detect calls to get_uniform()
and get_bits() that don't actually read anything.

Closes #76

--- a/src/getbits.c
+++ b/src/getbits.c
@@ -62,6 +62,7 @@
 
 unsigned dav1d_get_bits(GetBits *const c, const unsigned n) {
     assert(n <= 32 /* can go up to 57 if we change return type */);
+    assert(n /* can't shift state by 64 */);
 
     if (n > c->bits_left) refill(c, n);
 
@@ -78,11 +79,13 @@
     return res >> shift;
 }
 
-unsigned dav1d_get_uniform(GetBits *const c, const unsigned n) {
-    assert(n > 0);
-    const int l = ulog2(n) + 1;
-    assert(l > 0);
-    const unsigned m = (1U << l) - n;
+unsigned dav1d_get_uniform(GetBits *const c, const unsigned max) {
+    // Output in range [0..max-1]
+    // max must be > 1, or else nothing is read from the bitstream
+    assert(max > 1);
+    const int l = ulog2(max) + 1;
+    assert(l > 1);
+    const unsigned m = (1U << l) - max;
     const unsigned v = dav1d_get_bits(c, l - 1);
     return v < m ? v : (v << 1) - m + dav1d_get_bits(c, 1);
 }
--- a/src/getbits.h
+++ b/src/getbits.h
@@ -41,7 +41,9 @@
 void dav1d_init_get_bits(GetBits *c, const uint8_t *data, size_t sz);
 unsigned dav1d_get_bits(GetBits *c, unsigned n);
 int dav1d_get_sbits(GetBits *c, unsigned n);
-unsigned dav1d_get_uniform(GetBits *c, unsigned range);
+
+// Output in range 0..max-1
+unsigned dav1d_get_uniform(GetBits *c, unsigned max);
 unsigned dav1d_get_vlc(GetBits *c);
 int dav1d_get_bits_subexp(GetBits *c, int ref, unsigned n);
 const uint8_t *dav1d_flush_get_bits(GetBits *c);
--- a/src/obu.c
+++ b/src/obu.c
@@ -464,8 +464,10 @@
         hdr->tiling.cols = 0;
         int widest_tile = 0, max_tile_area_sb = sbw * sbh;
         for (int sbx = 0; sbx < sbw; hdr->tiling.cols++) {
-            const int tile_w = 1 + dav1d_get_uniform(gb, imin(sbw - sbx,
-                                                              max_tile_width_sb));
+            const int tile_width_sb = imin(sbw - sbx, max_tile_width_sb);
+            const int tile_w = (tile_width_sb > 1) ?
+                                   1 + dav1d_get_uniform(gb, tile_width_sb) :
+                                   1;
             hdr->tiling.col_start_sb[hdr->tiling.cols] = sbx;
             sbx += tile_w;
             widest_tile = imax(widest_tile, tile_w);
@@ -476,8 +478,10 @@
 
         hdr->tiling.rows = 0;
         for (int sby = 0; sby < sbh; hdr->tiling.rows++) {
-            const int tile_h = 1 + dav1d_get_uniform(gb, imin(sbh - sby,
-                                                              max_tile_height_sb));
+            const int tile_height_sb = imin(sbh - sby, max_tile_height_sb);
+            const int tile_h = (tile_height_sb > 1) ?
+                                   1 + dav1d_get_uniform(gb, tile_height_sb) :
+                                   1;
             hdr->tiling.row_start_sb[hdr->tiling.rows] = sby;
             sby += tile_h;
         }