Commit fa9c9d1c authored by Alex Converse's avatar Alex Converse

Adjust how the final ANS state is written.

The new prefixes are
0: 15 bits of state are added to the base state.
10: 22 bits of state are added to the base state.
110: Reserved for super frame marker
111: 29 bits of state are added to the base state.

The likelihood of any final state is proportional to 1 / state. Given a
state range of [2**15, 2 **23) this should save on average 0.4 bits
per serialized final state.

BDRATE
subset1: -.000%
lowres: -.010%

Change-Id: I8e66e4a6667f5692c541083e6d6edc35ff411181
parent feffd11f
......@@ -105,19 +105,16 @@ static INLINE int ans_read_init(struct AnsDecoder *const ans,
unsigned x;
if (offset < 1) return 1;
ans->buf = buf;
x = buf[offset - 1] >> 6;
if (x == 0) {
ans->buf_offset = offset - 1;
ans->state = buf[offset - 1] & 0x3F;
} else if (x == 1) {
x = buf[offset - 1];
if ((x & 0x80) == 0) {
if (offset < 2) return 1;
ans->buf_offset = offset - 2;
ans->state = mem_get_le16(buf + offset - 2) & 0x3FFF;
} else if (x == 2) {
ans->state = mem_get_le16(buf + offset - 2) & 0x7FFF;
} else if ((x & 0xC0) == 0x80) {
if (offset < 3) return 1;
ans->buf_offset = offset - 3;
ans->state = mem_get_le24(buf + offset - 3) & 0x3FFFFF;
} else if ((buf[offset - 1] & 0xE0) == 0xE0) {
} else if ((x & 0xE0) == 0xE0) {
if (offset < 4) return 1;
ans->buf_offset = offset - 4;
ans->state = mem_get_le32(buf + offset - 4) & 0x1FFFFFFF;
......
......@@ -60,17 +60,14 @@ static INLINE int ans_write_end(struct AnsCoder *const ans) {
assert(ans->state >= L_BASE);
assert(ans->state < L_BASE * IO_BASE);
state = ans->state - L_BASE;
if (state < (1 << 6)) {
ans->buf[ans->buf_offset] = (0x00 << 6) + state;
return ans->buf_offset + 1;
} else if (state < (1 << 14)) {
mem_put_le16(ans->buf + ans->buf_offset, (0x01 << 14) + state);
if (state < (1u << 15)) {
mem_put_le16(ans->buf + ans->buf_offset, (0x00u << 15) + state);
return ans->buf_offset + 2;
} else if (state < (1 << 22)) {
mem_put_le24(ans->buf + ans->buf_offset, (0x02 << 22) + state);
} else if (state < (1u << 22)) {
mem_put_le24(ans->buf + ans->buf_offset, (0x02u << 22) + state);
return ans->buf_offset + 3;
} else if (state < (1 << 29)) {
mem_put_le32(ans->buf + ans->buf_offset, (0x07 << 29) + state);
} else if (state < (1u << 29)) {
mem_put_le32(ans->buf + ans->buf_offset, (0x07u << 29) + state);
return ans->buf_offset + 4;
} else {
assert(0 && "State is too large to be serialized");
......
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