Commit 5186abdb authored by Luc Trudeau's avatar Luc Trudeau
Browse files

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
parent 8eed0b67
Pipeline #1212 passed with stage
in 1 minute and 59 seconds
...@@ -62,6 +62,7 @@ static void refill(GetBits *const c, const unsigned n) { ...@@ -62,6 +62,7 @@ static void refill(GetBits *const c, const unsigned n) {
unsigned dav1d_get_bits(GetBits *const c, const unsigned n) { 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 <= 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); if (n > c->bits_left) refill(c, n);
...@@ -78,11 +79,13 @@ int dav1d_get_sbits(GetBits *const c, const unsigned n) { ...@@ -78,11 +79,13 @@ int dav1d_get_sbits(GetBits *const c, const unsigned n) {
return res >> shift; return res >> shift;
} }
unsigned dav1d_get_uniform(GetBits *const c, const unsigned n) { unsigned dav1d_get_uniform(GetBits *const c, const unsigned max) {
assert(n > 0); // Output in range [0..max-1]
const int l = ulog2(n) + 1; // max must be > 1, or else nothing is read from the bitstream
assert(l > 0); assert(max > 1);
const unsigned m = (1U << l) - n; const int l = ulog2(max) + 1;
assert(l > 1);
const unsigned m = (1U << l) - max;
const unsigned v = dav1d_get_bits(c, l - 1); const unsigned v = dav1d_get_bits(c, l - 1);
return v < m ? v : (v << 1) - m + dav1d_get_bits(c, 1); return v < m ? v : (v << 1) - m + dav1d_get_bits(c, 1);
} }
......
...@@ -41,7 +41,9 @@ typedef struct GetBits { ...@@ -41,7 +41,9 @@ typedef struct GetBits {
void dav1d_init_get_bits(GetBits *c, const uint8_t *data, size_t sz); void dav1d_init_get_bits(GetBits *c, const uint8_t *data, size_t sz);
unsigned dav1d_get_bits(GetBits *c, unsigned n); unsigned dav1d_get_bits(GetBits *c, unsigned n);
int dav1d_get_sbits(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); unsigned dav1d_get_vlc(GetBits *c);
int dav1d_get_bits_subexp(GetBits *c, int ref, unsigned n); int dav1d_get_bits_subexp(GetBits *c, int ref, unsigned n);
const uint8_t *dav1d_flush_get_bits(GetBits *c); const uint8_t *dav1d_flush_get_bits(GetBits *c);
......
...@@ -464,8 +464,10 @@ static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb, ...@@ -464,8 +464,10 @@ static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb,
hdr->tiling.cols = 0; hdr->tiling.cols = 0;
int widest_tile = 0, max_tile_area_sb = sbw * sbh; int widest_tile = 0, max_tile_area_sb = sbw * sbh;
for (int sbx = 0; sbx < sbw; hdr->tiling.cols++) { for (int sbx = 0; sbx < sbw; hdr->tiling.cols++) {
const int tile_w = 1 + dav1d_get_uniform(gb, imin(sbw - sbx, const int tile_width_sb = imin(sbw - sbx, max_tile_width_sb);
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; hdr->tiling.col_start_sb[hdr->tiling.cols] = sbx;
sbx += tile_w; sbx += tile_w;
widest_tile = imax(widest_tile, tile_w); widest_tile = imax(widest_tile, tile_w);
...@@ -476,8 +478,10 @@ static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb, ...@@ -476,8 +478,10 @@ static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb,
hdr->tiling.rows = 0; hdr->tiling.rows = 0;
for (int sby = 0; sby < sbh; hdr->tiling.rows++) { for (int sby = 0; sby < sbh; hdr->tiling.rows++) {
const int tile_h = 1 + dav1d_get_uniform(gb, imin(sbh - sby, const int tile_height_sb = imin(sbh - sby, max_tile_height_sb);
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; hdr->tiling.row_start_sb[hdr->tiling.rows] = sby;
sby += tile_h; sby += tile_h;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment