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;
}