Commit b0bbd606 authored by Alex Converse's avatar Alex Converse

ans: Allow compressed buffer reversal

The final ANS state gets further compacted because aliasing the super
frame marker is not an issue.

Change-Id: I26208accb117a6748abb6f1c32c28fadbc48de09
parent d1d76ba8
......@@ -23,6 +23,8 @@
extern "C" {
#endif // __cplusplus
#define ANS_REVERSE 0
typedef uint8_t AnsP8;
#define ANS_P8_PRECISION 256u
#define ANS_P8_SHIFT 8
......
......@@ -39,9 +39,15 @@ struct AnsDecoder {
static INLINE unsigned refill_state(struct AnsDecoder *const ans,
unsigned state) {
#if ANS_REVERSE
while (state < L_BASE && ans->buf_offset < 0) {
state = state * IO_BASE + ans->buf[ans->buf_offset++];
}
#else
while (state < L_BASE && ans->buf_offset > 0) {
state = state * IO_BASE + ans->buf[--ans->buf_offset];
}
#endif
return state;
}
......@@ -106,6 +112,20 @@ static INLINE int ans_read_init(struct AnsDecoder *const ans,
const uint8_t *const buf, int offset) {
unsigned x;
if (offset < 1) return 1;
#if ANS_REVERSE
ans->buf = buf + offset;
ans->buf_offset = -offset;
x = buf[0];
if ((x & 0x80) == 0) {
if (offset < 2) return 1;
ans->buf_offset += 2;
ans->state = mem_get_be16(buf) & 0x7FFF;
} else {
if (offset < 3) return 1;
ans->buf_offset += 3;
ans->state = mem_get_be24(buf) & 0x7FFFFF;
}
#else
ans->buf = buf;
x = buf[offset - 1];
if ((x & 0x80) == 0) {
......@@ -124,6 +144,7 @@ static INLINE int ans_read_init(struct AnsDecoder *const ans,
// 110xxxxx implies this byte is a superframe marker
return 1;
}
#endif // ANS_REVERSE
#if CONFIG_ACCOUNTING
ans->accounting = NULL;
#endif
......
......@@ -57,22 +57,41 @@ static INLINE void ans_write_init(struct AnsCoder *const ans,
static INLINE int ans_write_end(struct AnsCoder *const ans) {
uint32_t state;
int ans_size;
assert(ans->state >= L_BASE);
assert(ans->state < L_BASE * IO_BASE);
state = ans->state - L_BASE;
if (state < (1u << 15)) {
mem_put_le16(ans->buf + ans->buf_offset, (0x00u << 15) + state);
return ans->buf_offset + 2;
ans_size = ans->buf_offset + 2;
#if ANS_REVERSE
} else if (state < (1u << 23)) {
mem_put_le24(ans->buf + ans->buf_offset, (0x01u << 23) + state);
ans_size = ans->buf_offset + 3;
#else
} else if (state < (1u << 22)) {
mem_put_le24(ans->buf + ans->buf_offset, (0x02u << 22) + state);
return ans->buf_offset + 3;
ans_size = ans->buf_offset + 3;
} else if (state < (1u << 29)) {
mem_put_le32(ans->buf + ans->buf_offset, (0x07u << 29) + state);
return ans->buf_offset + 4;
ans_size = ans->buf_offset + 4;
#endif
} else {
assert(0 && "State is too large to be serialized");
return ans->buf_offset;
}
#if ANS_REVERSE
{
int i;
uint8_t tmp;
for (i = 0; i < (ans_size >> 1); i++) {
tmp = ans->buf[i];
ans->buf[i] = ans->buf[ans_size - 1 - i];
ans->buf[ans_size - 1 - i] = tmp;
}
}
#endif
return ans_size;
}
// uABS with normalization
......
......@@ -4553,6 +4553,10 @@ void av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dst, size_t *size) {
aom_wb_write_literal(&saved_wb, compressed_header_size, 16);
#else
data += data_size;
#endif
#if CONFIG_ANS && ANS_REVERSE
// Avoid aliasing the superframe index
*data++ = 0;
#endif
*size = data - dst;
}
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