Specify ANS window size at initialization Change-Id: Ia1757d580dd230d9e743b1f8c3e87df164008684
diff --git a/aom_dsp/ansreader.h b/aom_dsp/ansreader.h index 8a7788e..099d094 100644 --- a/aom_dsp/ansreader.h +++ b/aom_dsp/ansreader.h
@@ -34,6 +34,7 @@ uint32_t state; #if ANS_MAX_SYMBOLS int symbols_left; + int window_size; #endif #if CONFIG_ACCOUNTING Accounting *accounting; @@ -134,6 +135,9 @@ } static INLINE int ans_read_init(struct AnsDecoder *const ans, +#if ANS_MAX_SYMBOLS + int window_size, +#endif const uint8_t *const buf, int offset) { unsigned x; if (offset < 1) return 1; @@ -176,14 +180,19 @@ ans->state += L_BASE; if (ans->state >= L_BASE * IO_BASE) return 1; #if ANS_MAX_SYMBOLS - ans->symbols_left = ANS_MAX_SYMBOLS; + ans->window_size = window_size; + ans->symbols_left = window_size; #endif return 0; } #if ANS_REVERSE static INLINE int ans_read_reinit(struct AnsDecoder *const ans) { - return ans_read_init(ans, ans->buf + ans->buf_offset, -ans->buf_offset); + return ans_read_init(ans, +#if ANS_MAX_SYMBOLS + ans->window_size, +#endif + ans->buf + ans->buf_offset, -ans->buf_offset); } #endif
diff --git a/aom_dsp/bitreader.h b/aom_dsp/bitreader.h index 4ab8b5b..05216c8 100644 --- a/aom_dsp/bitreader.h +++ b/aom_dsp/bitreader.h
@@ -68,13 +68,21 @@ #endif static INLINE int aom_reader_init(aom_reader *r, const uint8_t *buffer, - size_t size, aom_decrypt_cb decrypt_cb, + size_t size, +#if CONFIG_ANS && ANS_MAX_SYMBOLS + size_t window_size, +#endif + aom_decrypt_cb decrypt_cb, void *decrypt_state) { #if CONFIG_ANS (void)decrypt_cb; (void)decrypt_state; if (size > INT_MAX) return 1; - return ans_read_init(r, buffer, (int)size); + return ans_read_init(r, +#if ANS_MAX_SYMBOLS + (int)window_size, +#endif + buffer, (int)size); #elif CONFIG_DAALA_EC (void)decrypt_cb; (void)decrypt_state;
diff --git a/aom_dsp/buf_ans.c b/aom_dsp/buf_ans.c index c4ac643..c911983 100644 --- a/aom_dsp/buf_ans.c +++ b/aom_dsp/buf_ans.c
@@ -16,9 +16,9 @@ #include "aom/internal/aom_codec_internal.h" void aom_buf_ans_alloc(struct BufAnsCoder *c, - struct aom_internal_error_info *error, int size_hint) { + struct aom_internal_error_info *error, int size) { c->error = error; - c->size = size_hint; + c->size = size; AOM_CHECK_MEM_ERROR(error, c->buf, aom_malloc(c->size * sizeof(*c->buf))); // Initialize to overfull to trigger the assert in write. c->offset = c->size + 1; @@ -30,6 +30,7 @@ c->size = 0; } +#if !ANS_MAX_SYMBOLS void aom_buf_ans_grow(struct BufAnsCoder *c) { struct buffered_ans_symbol *new_buf = NULL; int new_size = c->size * 2; @@ -40,6 +41,7 @@ c->buf = new_buf; c->size = new_size; } +#endif void aom_buf_ans_flush(struct BufAnsCoder *const c) { int offset;
diff --git a/aom_dsp/buf_ans.h b/aom_dsp/buf_ans.h index b315bd7..2a36a64 100644 --- a/aom_dsp/buf_ans.h +++ b/aom_dsp/buf_ans.h
@@ -43,14 +43,24 @@ int size; int offset; int output_bytes; +#if ANS_MAX_SYMBOLS + int window_size; +#endif }; +// Allocate a buffered ANS coder to store size symbols. +// When ANS_MAX_SYMBOLS is turned on, the size is the fixed size of each ANS +// partition. +// When ANS_MAX_SYMBOLS is turned off, size is merely an initial hint and the +// buffer will grow on demand void aom_buf_ans_alloc(struct BufAnsCoder *c, - struct aom_internal_error_info *error, int size_hint); + struct aom_internal_error_info *error, int hint); void aom_buf_ans_free(struct BufAnsCoder *c); +#if !ANS_MAX_SYMBOLS void aom_buf_ans_grow(struct BufAnsCoder *c); +#endif void aom_buf_ans_flush(struct BufAnsCoder *const c); @@ -64,30 +74,34 @@ static INLINE void buf_uabs_write(struct BufAnsCoder *const c, uint8_t val, AnsP8 prob) { assert(c->offset <= c->size); +#if !ANS_MAX_SYMBOLS if (c->offset == c->size) { aom_buf_ans_grow(c); } +#endif c->buf[c->offset].method = ANS_METHOD_UABS; c->buf[c->offset].val_start = val; c->buf[c->offset].prob = prob; ++c->offset; #if ANS_MAX_SYMBOLS - if (c->offset == ANS_MAX_SYMBOLS) aom_buf_ans_flush(c); + if (c->offset == c->size) aom_buf_ans_flush(c); #endif } static INLINE void buf_rans_write(struct BufAnsCoder *const c, const struct rans_sym *const sym) { assert(c->offset <= c->size); +#if !ANS_MAX_SYMBOLS if (c->offset == c->size) { aom_buf_ans_grow(c); } +#endif c->buf[c->offset].method = ANS_METHOD_RANS; c->buf[c->offset].val_start = sym->cum_prob; c->buf[c->offset].prob = sym->prob; ++c->offset; #if ANS_MAX_SYMBOLS - if (c->offset == ANS_MAX_SYMBOLS) aom_buf_ans_flush(c); + if (c->offset == c->size) aom_buf_ans_flush(c); #endif }
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index 5f3b3b7..71160c7 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c
@@ -2183,7 +2183,11 @@ aom_internal_error(error_info, AOM_CODEC_CORRUPT_FRAME, "Truncated packet or corrupt tile length"); - if (aom_reader_init(r, data, read_size, decrypt_cb, decrypt_state)) + if (aom_reader_init(r, data, read_size, +#if CONFIG_ANS && ANS_MAX_SYMBOLS + ANS_MAX_SYMBOLS, +#endif + decrypt_cb, decrypt_state)) aom_internal_error(error_info, AOM_CODEC_MEM_ERROR, "Failed to allocate bool decoder %d", 1); } @@ -4149,8 +4153,11 @@ int j; #endif - if (aom_reader_init(&r, data, partition_size, pbi->decrypt_cb, - pbi->decrypt_state)) + if (aom_reader_init(&r, data, partition_size, +#if CONFIG_ANS && ANS_MAX_SYMBOLS + ANS_MAX_SYMBOLS, +#endif + pbi->decrypt_cb, pbi->decrypt_state)) aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR, "Failed to allocate bool decoder 0");
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index f652fe0..a882a0b 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -791,7 +791,8 @@ CHECK_MEM_ERROR(cm, cpi->tile_tok[0][0], aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0]))); #if CONFIG_ANS - aom_buf_ans_alloc(&cpi->buf_ans, &cm->error, tokens); + aom_buf_ans_alloc(&cpi->buf_ans, &cm->error, + ANS_MAX_SYMBOLS ? ANS_MAX_SYMBOLS : tokens); #endif // CONFIG_ANS }
diff --git a/test/accounting_test.cc b/test/accounting_test.cc index e0dfaa2..5f3defc 100644 --- a/test/accounting_test.cc +++ b/test/accounting_test.cc
@@ -35,7 +35,11 @@ } aom_stop_encode(&bw); aom_reader br; - aom_reader_init(&br, bw_buffer, bw.pos, NULL, NULL); + aom_reader_init(&br, bw_buffer, bw.pos, +#if CONFIG_ANS && ANS_MAX_SYMBOLS + 1 << 16, +#endif + NULL, NULL); Accounting accounting; aom_accounting_init(&accounting);
diff --git a/test/ans_test.cc b/test/ans_test.cc index 4c63352..760b541 100644 --- a/test/ans_test.cc +++ b/test/ans_test.cc
@@ -26,6 +26,9 @@ typedef std::vector<std::pair<uint8_t, bool> > PvVec; const int kPrintStats = 0; +// When ANS is windowed use the window size, otherwise use a small value to +// exercise the buffer growth code +const int kBufAnsSize = ANS_MAX_SYMBOLS ? ANS_MAX_SYMBOLS : 100; PvVec abs_encode_build_vals(int iters) { PvVec ret; @@ -49,7 +52,7 @@ bool check_uabs(const PvVec &pv_vec, uint8_t *buf) { BufAnsCoder a; - aom_buf_ans_alloc(&a, NULL, 100); + aom_buf_ans_alloc(&a, NULL, kBufAnsSize); buf_ans_write_init(&a, buf); std::clock_t start = std::clock(); @@ -62,7 +65,12 @@ aom_buf_ans_free(&a); bool okay = true; AnsDecoder d; - if (ans_read_init(&d, buf, offset)) return false; + if (ans_read_init(&d, +#if ANS_MAX_SYMBOLS + kBufAnsSize, +#endif + buf, offset)) + return false; start = std::clock(); for (PvVec::const_iterator it = pv_vec.begin(); it != pv_vec.end(); ++it) { okay = okay && (uabs_read(&d, 256 - it->first) != 0) == it->second; @@ -115,7 +123,7 @@ bool check_rans(const std::vector<int> &sym_vec, const rans_sym *const tab, uint8_t *buf) { BufAnsCoder a; - aom_buf_ans_alloc(&a, NULL, 100); + aom_buf_ans_alloc(&a, NULL, kBufAnsSize); buf_ans_write_init(&a, buf); aom_cdf_prob dec_tab[kRansSymbols]; rans_build_dec_tab(tab, dec_tab); @@ -131,7 +139,12 @@ aom_buf_ans_free(&a); bool okay = true; AnsDecoder d; - if (ans_read_init(&d, buf, offset)) return false; + if (ans_read_init(&d, +#if ANS_MAX_SYMBOLS + kBufAnsSize, +#endif + buf, offset)) + return false; start = std::clock(); for (std::vector<int>::const_iterator it = sym_vec.begin(); it != sym_vec.end(); ++it) {