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
diff --git a/aom_dsp/ans.h b/aom_dsp/ans.h index 08735bb..f84671c 100644 --- a/aom_dsp/ans.h +++ b/aom_dsp/ans.h
@@ -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
diff --git a/aom_dsp/ansreader.h b/aom_dsp/ansreader.h index 5855789..e0b02f7 100644 --- a/aom_dsp/ansreader.h +++ b/aom_dsp/ansreader.h
@@ -39,9 +39,15 @@ 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 @@ 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 @@ // 110xxxxx implies this byte is a superframe marker return 1; } +#endif // ANS_REVERSE #if CONFIG_ACCOUNTING ans->accounting = NULL; #endif
diff --git a/aom_dsp/answriter.h b/aom_dsp/answriter.h index 23d7b41..b6ac6de 100644 --- a/aom_dsp/answriter.h +++ b/aom_dsp/answriter.h
@@ -57,22 +57,41 @@ 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
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index 493e857..1bed65c 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c
@@ -4554,5 +4554,9 @@ #else data += data_size; #endif +#if CONFIG_ANS && ANS_REVERSE + // Avoid aliasing the superframe index + *data++ = 0; +#endif *size = data - dst; }