Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 4 | * This source code is subject to the terms of the BSD 2 Clause License and |
| 5 | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| 6 | * was not distributed with this source code in the LICENSE file, you can |
| 7 | * obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| 8 | * Media Patent License 1.0 was not distributed with this source code in the |
| 9 | * PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 10 | */ |
| 11 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 12 | #ifndef AOM_DSP_BITREADER_H_ |
| 13 | #define AOM_DSP_BITREADER_H_ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 14 | |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 15 | #include <assert.h> |
Alex Converse | 7fe2ae8 | 2016-09-28 11:33:20 -0700 | [diff] [blame] | 16 | #include <limits.h> |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 17 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 18 | #include "./aom_config.h" |
Nathan E. Egge | baaaa16 | 2016-10-24 09:50:52 -0400 | [diff] [blame] | 19 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 20 | #include "aom/aomdx.h" |
| 21 | #include "aom/aom_integer.h" |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 22 | #if CONFIG_ANS |
Alex Converse | 7fe2ae8 | 2016-09-28 11:33:20 -0700 | [diff] [blame] | 23 | #include "aom_dsp/ansreader.h" |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 24 | #else |
Nathan E. Egge | 476c63c | 2017-05-18 18:35:16 -0400 | [diff] [blame] | 25 | #include "aom_dsp/daalaboolreader.h" |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 26 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 27 | #include "aom_dsp/prob.h" |
Nathan E. Egge | 4446014 | 2016-06-20 13:44:22 -0400 | [diff] [blame] | 28 | #include "av1/common/odintrin.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 29 | |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 30 | #if CONFIG_ACCOUNTING |
Luc Trudeau | 83fbd57 | 2017-04-21 11:24:34 -0400 | [diff] [blame] | 31 | #include "av1/decoder/accounting.h" |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 32 | #define ACCT_STR_NAME acct_str |
| 33 | #define ACCT_STR_PARAM , const char *ACCT_STR_NAME |
| 34 | #define ACCT_STR_ARG(s) , s |
| 35 | #else |
| 36 | #define ACCT_STR_PARAM |
| 37 | #define ACCT_STR_ARG(s) |
| 38 | #endif |
| 39 | |
| 40 | #define aom_read(r, prob, ACCT_STR_NAME) \ |
| 41 | aom_read_(r, prob ACCT_STR_ARG(ACCT_STR_NAME)) |
| 42 | #define aom_read_bit(r, ACCT_STR_NAME) \ |
| 43 | aom_read_bit_(r ACCT_STR_ARG(ACCT_STR_NAME)) |
| 44 | #define aom_read_tree(r, tree, probs, ACCT_STR_NAME) \ |
| 45 | aom_read_tree_(r, tree, probs ACCT_STR_ARG(ACCT_STR_NAME)) |
| 46 | #define aom_read_literal(r, bits, ACCT_STR_NAME) \ |
| 47 | aom_read_literal_(r, bits ACCT_STR_ARG(ACCT_STR_NAME)) |
Nathan E. Egge | e069849 | 2017-01-06 19:40:36 -0500 | [diff] [blame] | 48 | #define aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME) \ |
| 49 | aom_read_cdf_(r, cdf, nsymbs ACCT_STR_ARG(ACCT_STR_NAME)) |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 50 | #define aom_read_symbol(r, cdf, nsymbs, ACCT_STR_NAME) \ |
| 51 | aom_read_symbol_(r, cdf, nsymbs ACCT_STR_ARG(ACCT_STR_NAME)) |
| 52 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 53 | #ifdef __cplusplus |
| 54 | extern "C" { |
| 55 | #endif |
| 56 | |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 57 | #if CONFIG_ANS |
| 58 | typedef struct AnsDecoder aom_reader; |
| 59 | #else |
Nathan E. Egge | 476c63c | 2017-05-18 18:35:16 -0400 | [diff] [blame] | 60 | typedef struct daala_reader aom_reader; |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 61 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 62 | |
Alex Converse | eb00cb2 | 2016-06-06 15:12:06 -0700 | [diff] [blame] | 63 | static INLINE int aom_reader_init(aom_reader *r, const uint8_t *buffer, |
Alex Converse | 346440b | 2017-01-03 13:47:37 -0800 | [diff] [blame] | 64 | size_t size, aom_decrypt_cb decrypt_cb, |
Alex Converse | eb00cb2 | 2016-06-06 15:12:06 -0700 | [diff] [blame] | 65 | void *decrypt_state) { |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 66 | (void)decrypt_cb; |
| 67 | (void)decrypt_state; |
Nathan E. Egge | 476c63c | 2017-05-18 18:35:16 -0400 | [diff] [blame] | 68 | #if CONFIG_ANS |
Alex Converse | 5b5140b | 2016-12-13 14:00:56 -0800 | [diff] [blame] | 69 | if (size > INT_MAX) return 1; |
Alex Converse | 346440b | 2017-01-03 13:47:37 -0800 | [diff] [blame] | 70 | return ans_read_init(r, buffer, (int)size); |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 71 | #else |
Nathan E. Egge | 476c63c | 2017-05-18 18:35:16 -0400 | [diff] [blame] | 72 | return aom_daala_reader_init(r, buffer, (int)size); |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 73 | #endif |
Alex Converse | eb00cb2 | 2016-06-06 15:12:06 -0700 | [diff] [blame] | 74 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 75 | |
Alex Converse | eb00cb2 | 2016-06-06 15:12:06 -0700 | [diff] [blame] | 76 | static INLINE const uint8_t *aom_reader_find_end(aom_reader *r) { |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 77 | #if CONFIG_ANS |
| 78 | (void)r; |
| 79 | assert(0 && "Use the raw buffer size with ANS"); |
| 80 | return NULL; |
| 81 | #else |
Nathan E. Egge | 476c63c | 2017-05-18 18:35:16 -0400 | [diff] [blame] | 82 | return aom_daala_reader_find_end(r); |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 83 | #endif |
Alex Converse | eb00cb2 | 2016-06-06 15:12:06 -0700 | [diff] [blame] | 84 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 85 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 86 | static INLINE int aom_reader_has_error(aom_reader *r) { |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 87 | #if CONFIG_ANS |
| 88 | return ans_reader_has_error(r); |
| 89 | #else |
Nathan E. Egge | 476c63c | 2017-05-18 18:35:16 -0400 | [diff] [blame] | 90 | return aom_daala_reader_has_error(r); |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 91 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 92 | } |
| 93 | |
Michael Bebenita | d7baf45 | 2016-08-25 11:27:56 -0700 | [diff] [blame] | 94 | // Returns the position in the bit reader in bits. |
Nathan E. Egge | b244f39 | 2016-09-06 23:48:43 -0400 | [diff] [blame] | 95 | static INLINE uint32_t aom_reader_tell(const aom_reader *r) { |
Michael Bebenita | 868fc0b | 2016-08-03 16:13:04 -0700 | [diff] [blame] | 96 | #if CONFIG_ANS |
| 97 | (void)r; |
| 98 | assert(0 && "aom_reader_tell() is unimplemented for ANS"); |
| 99 | return 0; |
Michael Bebenita | 868fc0b | 2016-08-03 16:13:04 -0700 | [diff] [blame] | 100 | #else |
Nathan E. Egge | 476c63c | 2017-05-18 18:35:16 -0400 | [diff] [blame] | 101 | return aom_daala_reader_tell(r); |
Michael Bebenita | 868fc0b | 2016-08-03 16:13:04 -0700 | [diff] [blame] | 102 | #endif |
| 103 | } |
| 104 | |
Michael Bebenita | d7baf45 | 2016-08-25 11:27:56 -0700 | [diff] [blame] | 105 | // Returns the position in the bit reader in 1/8th bits. |
Nathan E. Egge | b244f39 | 2016-09-06 23:48:43 -0400 | [diff] [blame] | 106 | static INLINE uint32_t aom_reader_tell_frac(const aom_reader *r) { |
Michael Bebenita | d7baf45 | 2016-08-25 11:27:56 -0700 | [diff] [blame] | 107 | #if CONFIG_ANS |
| 108 | (void)r; |
| 109 | assert(0 && "aom_reader_tell_frac() is unimplemented for ANS"); |
| 110 | return 0; |
Michael Bebenita | d7baf45 | 2016-08-25 11:27:56 -0700 | [diff] [blame] | 111 | #else |
Nathan E. Egge | 476c63c | 2017-05-18 18:35:16 -0400 | [diff] [blame] | 112 | return aom_daala_reader_tell_frac(r); |
Michael Bebenita | d7baf45 | 2016-08-25 11:27:56 -0700 | [diff] [blame] | 113 | #endif |
| 114 | } |
| 115 | |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 116 | #if CONFIG_ACCOUNTING |
| 117 | static INLINE void aom_process_accounting(const aom_reader *r ACCT_STR_PARAM) { |
| 118 | if (r->accounting != NULL) { |
| 119 | uint32_t tell_frac; |
| 120 | tell_frac = aom_reader_tell_frac(r); |
| 121 | aom_accounting_record(r->accounting, ACCT_STR_NAME, |
| 122 | tell_frac - r->accounting->last_tell_frac); |
| 123 | r->accounting->last_tell_frac = tell_frac; |
| 124 | } |
| 125 | } |
Thomas Davies | f7f87ff | 2017-03-01 16:24:56 +0000 | [diff] [blame] | 126 | |
Yaowu Xu | 4ff59b5 | 2017-04-24 12:41:56 -0700 | [diff] [blame] | 127 | static INLINE void aom_update_symb_counts(const aom_reader *r, int is_binary) { |
Thomas Davies | f7f87ff | 2017-03-01 16:24:56 +0000 | [diff] [blame] | 128 | if (r->accounting != NULL) { |
| 129 | r->accounting->syms.num_multi_syms += !is_binary; |
| 130 | r->accounting->syms.num_binary_syms += !!is_binary; |
| 131 | } |
| 132 | } |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 133 | #endif |
| 134 | |
| 135 | static INLINE int aom_read_(aom_reader *r, int prob ACCT_STR_PARAM) { |
| 136 | int ret; |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 137 | #if CONFIG_ANS |
Alex Converse | c54692b | 2017-01-25 16:41:05 -0800 | [diff] [blame] | 138 | ret = rabs_read(r, prob); |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 139 | #else |
Nathan E. Egge | 476c63c | 2017-05-18 18:35:16 -0400 | [diff] [blame] | 140 | ret = aom_daala_read(r, prob); |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 141 | #endif |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 142 | #if CONFIG_ACCOUNTING |
| 143 | if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME); |
Thomas Davies | f7f87ff | 2017-03-01 16:24:56 +0000 | [diff] [blame] | 144 | aom_update_symb_counts(r, 1); |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 145 | #endif |
| 146 | return ret; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 147 | } |
| 148 | |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 149 | static INLINE int aom_read_bit_(aom_reader *r ACCT_STR_PARAM) { |
| 150 | int ret; |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 151 | #if CONFIG_ANS |
Alex Converse | c54692b | 2017-01-25 16:41:05 -0800 | [diff] [blame] | 152 | ret = rabs_read_bit(r); // Non trivial optimization at half probability |
Nathan E. Egge | 476c63c | 2017-05-18 18:35:16 -0400 | [diff] [blame] | 153 | #elif CONFIG_RAWBITS |
Nathan E. Egge | 08c99eb | 2016-11-09 13:40:26 -0500 | [diff] [blame] | 154 | // Note this uses raw bits and is not the same as aom_daala_read(r, 128); |
Thomas Davies | f7f87ff | 2017-03-01 16:24:56 +0000 | [diff] [blame] | 155 | // Calls to this function are omitted from raw symbol accounting. |
Nathan E. Egge | 08c99eb | 2016-11-09 13:40:26 -0500 | [diff] [blame] | 156 | ret = aom_daala_read_bit(r); |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 157 | #else |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 158 | ret = aom_read(r, 128, NULL); // aom_prob_half |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 159 | #endif |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 160 | #if CONFIG_ACCOUNTING |
| 161 | if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME); |
| 162 | #endif |
| 163 | return ret; |
Alex Converse | acef60b | 2016-09-23 14:21:02 -0700 | [diff] [blame] | 164 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 165 | |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 166 | static INLINE int aom_read_literal_(aom_reader *r, int bits ACCT_STR_PARAM) { |
Nathan E. Egge | e691a24 | 2016-06-16 09:00:39 -0400 | [diff] [blame] | 167 | int literal = 0, bit; |
| 168 | |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 169 | for (bit = bits - 1; bit >= 0; bit--) literal |= aom_read_bit(r, NULL) << bit; |
| 170 | #if CONFIG_ACCOUNTING |
| 171 | if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME); |
| 172 | #endif |
Nathan E. Egge | e691a24 | 2016-06-16 09:00:39 -0400 | [diff] [blame] | 173 | return literal; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 174 | } |
| 175 | |
Nathan E. Egge | 2d8dd96 | 2016-12-23 10:42:43 -0500 | [diff] [blame] | 176 | static INLINE int aom_read_cdf_(aom_reader *r, const aom_cdf_prob *cdf, |
Nathan E. Egge | e069849 | 2017-01-06 19:40:36 -0500 | [diff] [blame] | 177 | int nsymbs ACCT_STR_PARAM) { |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 178 | int ret; |
Alex Converse | 1e4e29f | 2016-11-08 14:12:14 -0800 | [diff] [blame] | 179 | #if CONFIG_ANS |
Alex Converse | a1ac972 | 2016-10-12 15:59:58 -0700 | [diff] [blame] | 180 | (void)nsymbs; |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 181 | ret = rans_read(r, cdf); |
Alex Converse | a1ac972 | 2016-10-12 15:59:58 -0700 | [diff] [blame] | 182 | #else |
Nathan E. Egge | cd53951 | 2017-05-16 12:00:36 -0400 | [diff] [blame] | 183 | ret = daala_read_symbol(r, cdf, nsymbs); |
Alex Converse | a1ac972 | 2016-10-12 15:59:58 -0700 | [diff] [blame] | 184 | #endif |
Alex Converse | 58c520a | 2016-10-20 14:21:06 -0700 | [diff] [blame] | 185 | |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 186 | #if CONFIG_ACCOUNTING |
| 187 | if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME); |
Thomas Davies | f7f87ff | 2017-03-01 16:24:56 +0000 | [diff] [blame] | 188 | aom_update_symb_counts(r, (nsymbs == 2)); |
Nathan E. Egge | 4446014 | 2016-06-20 13:44:22 -0400 | [diff] [blame] | 189 | #endif |
Michael Bebenita | 6048d05 | 2016-08-25 14:40:54 -0700 | [diff] [blame] | 190 | return ret; |
Nathan E. Egge | 4446014 | 2016-06-20 13:44:22 -0400 | [diff] [blame] | 191 | } |
Nathan E. Egge | c98d286 | 2016-12-21 11:30:46 -0500 | [diff] [blame] | 192 | |
Nathan E. Egge | e069849 | 2017-01-06 19:40:36 -0500 | [diff] [blame] | 193 | static INLINE int aom_read_symbol_(aom_reader *r, aom_cdf_prob *cdf, |
| 194 | int nsymbs ACCT_STR_PARAM) { |
| 195 | int ret; |
| 196 | ret = aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME); |
Nathan E. Egge | e069849 | 2017-01-06 19:40:36 -0500 | [diff] [blame] | 197 | update_cdf(cdf, ret, nsymbs); |
Nathan E. Egge | e069849 | 2017-01-06 19:40:36 -0500 | [diff] [blame] | 198 | return ret; |
| 199 | } |
| 200 | |
Nathan E. Egge | 0f11c78 | 2017-02-12 19:04:04 -0500 | [diff] [blame] | 201 | static INLINE int aom_read_tree_as_cdf(aom_reader *r, |
| 202 | const aom_tree_index *tree, |
| 203 | const aom_prob *probs) { |
| 204 | aom_tree_index i = 0; |
| 205 | do { |
| 206 | aom_cdf_prob cdf[16]; |
| 207 | aom_tree_index index[16]; |
| 208 | int path[16]; |
| 209 | int dist[16]; |
| 210 | int nsymbs; |
| 211 | int symb; |
| 212 | nsymbs = tree_to_cdf(tree, probs, i, cdf, index, path, dist); |
| 213 | symb = aom_read_cdf(r, cdf, nsymbs, NULL); |
| 214 | OD_ASSERT(symb >= 0 && symb < nsymbs); |
| 215 | i = index[symb]; |
| 216 | } while (i > 0); |
| 217 | return -i; |
| 218 | } |
Nathan E. Egge | 4446014 | 2016-06-20 13:44:22 -0400 | [diff] [blame] | 219 | |
Nathan E. Egge | 0f11c78 | 2017-02-12 19:04:04 -0500 | [diff] [blame] | 220 | static INLINE int aom_read_tree_(aom_reader *r, const aom_tree_index *tree, |
| 221 | const aom_prob *probs ACCT_STR_PARAM) { |
| 222 | int ret; |
Nathan E. Egge | 0f11c78 | 2017-02-12 19:04:04 -0500 | [diff] [blame] | 223 | ret = aom_read_tree_as_cdf(r, tree, probs); |
Nathan E. Egge | 0f11c78 | 2017-02-12 19:04:04 -0500 | [diff] [blame] | 224 | #if CONFIG_ACCOUNTING |
| 225 | if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME); |
| 226 | #endif |
| 227 | return ret; |
| 228 | } |
| 229 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 230 | #ifdef __cplusplus |
| 231 | } // extern "C" |
| 232 | #endif |
| 233 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 234 | #endif // AOM_DSP_BITREADER_H_ |