blob: 9cd34dd48371068d0fd65791277b128fbf66d62e [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu9c01aa12016-09-01 14:32:49 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu9c01aa12016-09-01 14:32:49 -07004 * 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 Xuc27fc142016-08-22 16:08:15 -070010 */
11
Yaowu Xuf883b422016-08-30 14:01:10 -070012#ifndef AOM_DSP_BITREADER_H_
13#define AOM_DSP_BITREADER_H_
Yaowu Xuc27fc142016-08-22 16:08:15 -070014
Alex Converseacef60b2016-09-23 14:21:02 -070015#include <assert.h>
Alex Converse7fe2ae82016-09-28 11:33:20 -070016#include <limits.h>
Alex Converseacef60b2016-09-23 14:21:02 -070017
Yaowu Xuf883b422016-08-30 14:01:10 -070018#include "./aom_config.h"
Nathan E. Eggebaaaa162016-10-24 09:50:52 -040019#if CONFIG_EC_ADAPT && !CONFIG_EC_MULTISYMBOL
20#error "CONFIG_EC_ADAPT is enabled without enabling CONFIG_EC_MULTISYMBOL."
21#endif
22
Yaowu Xuf883b422016-08-30 14:01:10 -070023#include "aom/aomdx.h"
24#include "aom/aom_integer.h"
Alex Converseacef60b2016-09-23 14:21:02 -070025#if CONFIG_ANS
Alex Converse7fe2ae82016-09-28 11:33:20 -070026#include "aom_dsp/ansreader.h"
Nathan E. Egge8043cc42016-03-06 12:42:47 -050027#elif CONFIG_DAALA_EC
28#include "aom_dsp/daalaboolreader.h"
Alex Converseacef60b2016-09-23 14:21:02 -070029#else
Alex Converseeb00cb22016-06-06 15:12:06 -070030#include "aom_dsp/dkboolreader.h"
Alex Converseacef60b2016-09-23 14:21:02 -070031#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070032#include "aom_dsp/prob.h"
Nathan E. Egge44460142016-06-20 13:44:22 -040033#include "av1/common/odintrin.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070034
Michael Bebenita6048d052016-08-25 14:40:54 -070035#if CONFIG_ACCOUNTING
Luc Trudeau83fbd572017-04-21 11:24:34 -040036#include "av1/decoder/accounting.h"
Michael Bebenita6048d052016-08-25 14:40:54 -070037#define ACCT_STR_NAME acct_str
38#define ACCT_STR_PARAM , const char *ACCT_STR_NAME
39#define ACCT_STR_ARG(s) , s
40#else
41#define ACCT_STR_PARAM
42#define ACCT_STR_ARG(s)
43#endif
44
45#define aom_read(r, prob, ACCT_STR_NAME) \
46 aom_read_(r, prob ACCT_STR_ARG(ACCT_STR_NAME))
47#define aom_read_bit(r, ACCT_STR_NAME) \
48 aom_read_bit_(r ACCT_STR_ARG(ACCT_STR_NAME))
49#define aom_read_tree(r, tree, probs, ACCT_STR_NAME) \
50 aom_read_tree_(r, tree, probs ACCT_STR_ARG(ACCT_STR_NAME))
51#define aom_read_literal(r, bits, ACCT_STR_NAME) \
52 aom_read_literal_(r, bits ACCT_STR_ARG(ACCT_STR_NAME))
Nathan E. Eggee0698492017-01-06 19:40:36 -050053#define aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME) \
54 aom_read_cdf_(r, cdf, nsymbs ACCT_STR_ARG(ACCT_STR_NAME))
Michael Bebenita6048d052016-08-25 14:40:54 -070055#define aom_read_symbol(r, cdf, nsymbs, ACCT_STR_NAME) \
56 aom_read_symbol_(r, cdf, nsymbs ACCT_STR_ARG(ACCT_STR_NAME))
57
Yaowu Xuc27fc142016-08-22 16:08:15 -070058#ifdef __cplusplus
59extern "C" {
60#endif
61
Alex Converseacef60b2016-09-23 14:21:02 -070062#if CONFIG_ANS
63typedef struct AnsDecoder aom_reader;
Nathan E. Egge8043cc42016-03-06 12:42:47 -050064#elif CONFIG_DAALA_EC
65typedef struct daala_reader aom_reader;
Alex Converseacef60b2016-09-23 14:21:02 -070066#else
Alex Converseeb00cb22016-06-06 15:12:06 -070067typedef struct aom_dk_reader aom_reader;
Alex Converseacef60b2016-09-23 14:21:02 -070068#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070069
Alex Converseeb00cb22016-06-06 15:12:06 -070070static INLINE int aom_reader_init(aom_reader *r, const uint8_t *buffer,
Alex Converse346440b2017-01-03 13:47:37 -080071 size_t size, aom_decrypt_cb decrypt_cb,
Alex Converseeb00cb22016-06-06 15:12:06 -070072 void *decrypt_state) {
Alex Converseacef60b2016-09-23 14:21:02 -070073#if CONFIG_ANS
74 (void)decrypt_cb;
75 (void)decrypt_state;
Alex Converse5b5140b2016-12-13 14:00:56 -080076 if (size > INT_MAX) return 1;
Alex Converse346440b2017-01-03 13:47:37 -080077 return ans_read_init(r, buffer, (int)size);
Nathan E. Egge8043cc42016-03-06 12:42:47 -050078#elif CONFIG_DAALA_EC
79 (void)decrypt_cb;
80 (void)decrypt_state;
Yaowu Xufebe9b02016-11-09 10:00:31 -080081 return aom_daala_reader_init(r, buffer, (int)size);
Alex Converseacef60b2016-09-23 14:21:02 -070082#else
Alex Converseeb00cb22016-06-06 15:12:06 -070083 return aom_dk_reader_init(r, buffer, size, decrypt_cb, decrypt_state);
Alex Converseacef60b2016-09-23 14:21:02 -070084#endif
Alex Converseeb00cb22016-06-06 15:12:06 -070085}
Yaowu Xuc27fc142016-08-22 16:08:15 -070086
Alex Converseeb00cb22016-06-06 15:12:06 -070087static INLINE const uint8_t *aom_reader_find_end(aom_reader *r) {
Alex Converseacef60b2016-09-23 14:21:02 -070088#if CONFIG_ANS
89 (void)r;
90 assert(0 && "Use the raw buffer size with ANS");
91 return NULL;
Nathan E. Egge8043cc42016-03-06 12:42:47 -050092#elif CONFIG_DAALA_EC
93 return aom_daala_reader_find_end(r);
Alex Converseacef60b2016-09-23 14:21:02 -070094#else
Alex Converseeb00cb22016-06-06 15:12:06 -070095 return aom_dk_reader_find_end(r);
Alex Converseacef60b2016-09-23 14:21:02 -070096#endif
Alex Converseeb00cb22016-06-06 15:12:06 -070097}
Yaowu Xuc27fc142016-08-22 16:08:15 -070098
Yaowu Xuf883b422016-08-30 14:01:10 -070099static INLINE int aom_reader_has_error(aom_reader *r) {
Alex Converseacef60b2016-09-23 14:21:02 -0700100#if CONFIG_ANS
101 return ans_reader_has_error(r);
Nathan E. Egge8043cc42016-03-06 12:42:47 -0500102#elif CONFIG_DAALA_EC
103 return aom_daala_reader_has_error(r);
Alex Converseacef60b2016-09-23 14:21:02 -0700104#else
Alex Converseeb00cb22016-06-06 15:12:06 -0700105 return aom_dk_reader_has_error(r);
Alex Converseacef60b2016-09-23 14:21:02 -0700106#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700107}
108
Michael Bebenitad7baf452016-08-25 11:27:56 -0700109// Returns the position in the bit reader in bits.
Nathan E. Eggeb244f392016-09-06 23:48:43 -0400110static INLINE uint32_t aom_reader_tell(const aom_reader *r) {
Michael Bebenita868fc0b2016-08-03 16:13:04 -0700111#if CONFIG_ANS
112 (void)r;
113 assert(0 && "aom_reader_tell() is unimplemented for ANS");
114 return 0;
115#elif CONFIG_DAALA_EC
116 return aom_daala_reader_tell(r);
117#else
118 return aom_dk_reader_tell(r);
119#endif
120}
121
Michael Bebenitad7baf452016-08-25 11:27:56 -0700122// Returns the position in the bit reader in 1/8th bits.
Nathan E. Eggeb244f392016-09-06 23:48:43 -0400123static INLINE uint32_t aom_reader_tell_frac(const aom_reader *r) {
Michael Bebenitad7baf452016-08-25 11:27:56 -0700124#if CONFIG_ANS
125 (void)r;
126 assert(0 && "aom_reader_tell_frac() is unimplemented for ANS");
127 return 0;
128#elif CONFIG_DAALA_EC
129 return aom_daala_reader_tell_frac(r);
130#else
131 return aom_dk_reader_tell_frac(r);
132#endif
133}
134
Michael Bebenita6048d052016-08-25 14:40:54 -0700135#if CONFIG_ACCOUNTING
136static INLINE void aom_process_accounting(const aom_reader *r ACCT_STR_PARAM) {
137 if (r->accounting != NULL) {
138 uint32_t tell_frac;
139 tell_frac = aom_reader_tell_frac(r);
140 aom_accounting_record(r->accounting, ACCT_STR_NAME,
141 tell_frac - r->accounting->last_tell_frac);
142 r->accounting->last_tell_frac = tell_frac;
143 }
144}
Thomas Daviesf7f87ff2017-03-01 16:24:56 +0000145
Yaowu Xu4ff59b52017-04-24 12:41:56 -0700146static INLINE void aom_update_symb_counts(const aom_reader *r, int is_binary) {
Thomas Daviesf7f87ff2017-03-01 16:24:56 +0000147 if (r->accounting != NULL) {
148 r->accounting->syms.num_multi_syms += !is_binary;
149 r->accounting->syms.num_binary_syms += !!is_binary;
150 }
151}
Michael Bebenita6048d052016-08-25 14:40:54 -0700152#endif
153
154static INLINE int aom_read_(aom_reader *r, int prob ACCT_STR_PARAM) {
155 int ret;
Alex Converseacef60b2016-09-23 14:21:02 -0700156#if CONFIG_ANS
Alex Conversec54692b2017-01-25 16:41:05 -0800157 ret = rabs_read(r, prob);
Nathan E. Egge8043cc42016-03-06 12:42:47 -0500158#elif CONFIG_DAALA_EC
Michael Bebenita6048d052016-08-25 14:40:54 -0700159 ret = aom_daala_read(r, prob);
Alex Converseacef60b2016-09-23 14:21:02 -0700160#else
Michael Bebenita6048d052016-08-25 14:40:54 -0700161 ret = aom_dk_read(r, prob);
Alex Converseacef60b2016-09-23 14:21:02 -0700162#endif
Michael Bebenita6048d052016-08-25 14:40:54 -0700163#if CONFIG_ACCOUNTING
164 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
Thomas Daviesf7f87ff2017-03-01 16:24:56 +0000165 aom_update_symb_counts(r, 1);
Michael Bebenita6048d052016-08-25 14:40:54 -0700166#endif
167 return ret;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700168}
169
Michael Bebenita6048d052016-08-25 14:40:54 -0700170static INLINE int aom_read_bit_(aom_reader *r ACCT_STR_PARAM) {
171 int ret;
Alex Converseacef60b2016-09-23 14:21:02 -0700172#if CONFIG_ANS
Alex Conversec54692b2017-01-25 16:41:05 -0800173 ret = rabs_read_bit(r); // Non trivial optimization at half probability
Nathan E. Egge24f1a902017-02-14 13:29:44 -0500174#elif CONFIG_DAALA_EC && CONFIG_RAWBITS
Nathan E. Egge08c99eb2016-11-09 13:40:26 -0500175 // Note this uses raw bits and is not the same as aom_daala_read(r, 128);
Thomas Daviesf7f87ff2017-03-01 16:24:56 +0000176 // Calls to this function are omitted from raw symbol accounting.
Nathan E. Egge08c99eb2016-11-09 13:40:26 -0500177 ret = aom_daala_read_bit(r);
Alex Converseacef60b2016-09-23 14:21:02 -0700178#else
Michael Bebenita6048d052016-08-25 14:40:54 -0700179 ret = aom_read(r, 128, NULL); // aom_prob_half
Alex Converseacef60b2016-09-23 14:21:02 -0700180#endif
Michael Bebenita6048d052016-08-25 14:40:54 -0700181#if CONFIG_ACCOUNTING
182 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
183#endif
184 return ret;
Alex Converseacef60b2016-09-23 14:21:02 -0700185}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700186
Michael Bebenita6048d052016-08-25 14:40:54 -0700187static INLINE int aom_read_literal_(aom_reader *r, int bits ACCT_STR_PARAM) {
Nathan E. Eggee691a242016-06-16 09:00:39 -0400188 int literal = 0, bit;
189
Michael Bebenita6048d052016-08-25 14:40:54 -0700190 for (bit = bits - 1; bit >= 0; bit--) literal |= aom_read_bit(r, NULL) << bit;
191#if CONFIG_ACCOUNTING
192 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
193#endif
Nathan E. Eggee691a242016-06-16 09:00:39 -0400194 return literal;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700195}
196
Nathan E. Eggec4e9e472017-02-12 19:34:33 -0500197static INLINE int aom_read_tree_as_bits(aom_reader *r,
198 const aom_tree_index *tree,
199 const aom_prob *probs) {
Nathan E. Eggee691a242016-06-16 09:00:39 -0400200 aom_tree_index i = 0;
201
Michael Bebenita6048d052016-08-25 14:40:54 -0700202 while ((i = tree[i + aom_read(r, probs[i >> 1], NULL)]) > 0) continue;
Nathan E. Eggee691a242016-06-16 09:00:39 -0400203 return -i;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700204}
205
Alex Converse58c520a2016-10-20 14:21:06 -0700206#if CONFIG_EC_MULTISYMBOL
Nathan E. Egge2d8dd962016-12-23 10:42:43 -0500207static INLINE int aom_read_cdf_(aom_reader *r, const aom_cdf_prob *cdf,
Nathan E. Eggee0698492017-01-06 19:40:36 -0500208 int nsymbs ACCT_STR_PARAM) {
Michael Bebenita6048d052016-08-25 14:40:54 -0700209 int ret;
Alex Converse1e4e29f2016-11-08 14:12:14 -0800210#if CONFIG_ANS
Alex Conversea1ac9722016-10-12 15:59:58 -0700211 (void)nsymbs;
Michael Bebenita6048d052016-08-25 14:40:54 -0700212 ret = rans_read(r, cdf);
213#elif CONFIG_DAALA_EC
214 ret = daala_read_symbol(r, cdf, nsymbs);
Alex Conversea1ac9722016-10-12 15:59:58 -0700215#else
Alex Converse58c520a2016-10-20 14:21:06 -0700216#error \
217 "CONFIG_EC_MULTISYMBOL is selected without a valid backing entropy " \
218 "coder. Enable daala_ec or ans for a valid configuration."
Alex Conversea1ac9722016-10-12 15:59:58 -0700219#endif
Alex Converse58c520a2016-10-20 14:21:06 -0700220
Michael Bebenita6048d052016-08-25 14:40:54 -0700221#if CONFIG_ACCOUNTING
222 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
Thomas Daviesf7f87ff2017-03-01 16:24:56 +0000223 aom_update_symb_counts(r, (nsymbs == 2));
Nathan E. Egge44460142016-06-20 13:44:22 -0400224#endif
Michael Bebenita6048d052016-08-25 14:40:54 -0700225 return ret;
Nathan E. Egge44460142016-06-20 13:44:22 -0400226}
Nathan E. Eggec98d2862016-12-21 11:30:46 -0500227
Nathan E. Eggee0698492017-01-06 19:40:36 -0500228static INLINE int aom_read_symbol_(aom_reader *r, aom_cdf_prob *cdf,
229 int nsymbs ACCT_STR_PARAM) {
230 int ret;
231 ret = aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME);
232#if CONFIG_EC_ADAPT
233 update_cdf(cdf, ret, nsymbs);
234#endif
235 return ret;
236}
237
Nathan E. Egge0f11c782017-02-12 19:04:04 -0500238static INLINE int aom_read_tree_as_cdf(aom_reader *r,
239 const aom_tree_index *tree,
240 const aom_prob *probs) {
241 aom_tree_index i = 0;
242 do {
243 aom_cdf_prob cdf[16];
244 aom_tree_index index[16];
245 int path[16];
246 int dist[16];
247 int nsymbs;
248 int symb;
249 nsymbs = tree_to_cdf(tree, probs, i, cdf, index, path, dist);
250 symb = aom_read_cdf(r, cdf, nsymbs, NULL);
251 OD_ASSERT(symb >= 0 && symb < nsymbs);
252 i = index[symb];
253 } while (i > 0);
254 return -i;
255}
Alex Converse58c520a2016-10-20 14:21:06 -0700256#endif // CONFIG_EC_MULTISYMBOL
Nathan E. Egge44460142016-06-20 13:44:22 -0400257
Nathan E. Egge0f11c782017-02-12 19:04:04 -0500258static INLINE int aom_read_tree_(aom_reader *r, const aom_tree_index *tree,
259 const aom_prob *probs ACCT_STR_PARAM) {
260 int ret;
261#if CONFIG_EC_MULTISYMBOL
262 ret = aom_read_tree_as_cdf(r, tree, probs);
263#else
Nathan E. Eggec4e9e472017-02-12 19:34:33 -0500264 ret = aom_read_tree_as_bits(r, tree, probs);
Nathan E. Egge0f11c782017-02-12 19:04:04 -0500265#endif
266#if CONFIG_ACCOUNTING
267 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
268#endif
269 return ret;
270}
271
Yaowu Xuc27fc142016-08-22 16:08:15 -0700272#ifdef __cplusplus
273} // extern "C"
274#endif
275
Yaowu Xuf883b422016-08-30 14:01:10 -0700276#endif // AOM_DSP_BITREADER_H_