blob: c781c5a4339e00c91c4c4d52049726b4491c4b59 [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
36#include "av1/common/accounting.h"
37#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))
53#define aom_read_tree_bits(r, tree, probs, ACCT_STR_NAME) \
54 aom_read_tree_bits_(r, tree, probs ACCT_STR_ARG(ACCT_STR_NAME))
Nathan E. Eggee0698492017-01-06 19:40:36 -050055#define aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME) \
56 aom_read_cdf_(r, cdf, nsymbs ACCT_STR_ARG(ACCT_STR_NAME))
Michael Bebenita6048d052016-08-25 14:40:54 -070057#define aom_read_symbol(r, cdf, nsymbs, ACCT_STR_NAME) \
58 aom_read_symbol_(r, cdf, nsymbs ACCT_STR_ARG(ACCT_STR_NAME))
Nathan E. Eggee0698492017-01-06 19:40:36 -050059#define aom_read_cdf_unscaled(r, cdf, nsymbs, ACCT_STR_NAME) \
60 aom_read_cdf_unscaled_(r, cdf, nsymbs ACCT_STR_ARG(ACCT_STR_NAME))
Michael Bebenita6048d052016-08-25 14:40:54 -070061
Yaowu Xuc27fc142016-08-22 16:08:15 -070062#ifdef __cplusplus
63extern "C" {
64#endif
65
Alex Converseacef60b2016-09-23 14:21:02 -070066#if CONFIG_ANS
67typedef struct AnsDecoder aom_reader;
Nathan E. Egge8043cc42016-03-06 12:42:47 -050068#elif CONFIG_DAALA_EC
69typedef struct daala_reader aom_reader;
Alex Converseacef60b2016-09-23 14:21:02 -070070#else
Alex Converseeb00cb22016-06-06 15:12:06 -070071typedef struct aom_dk_reader aom_reader;
Alex Converseacef60b2016-09-23 14:21:02 -070072#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070073
Alex Converseeb00cb22016-06-06 15:12:06 -070074static INLINE int aom_reader_init(aom_reader *r, const uint8_t *buffer,
Alex Converse2cdf0d82016-12-13 13:53:09 -080075 size_t size,
76#if CONFIG_ANS && ANS_MAX_SYMBOLS
77 size_t window_size,
78#endif
79 aom_decrypt_cb decrypt_cb,
Alex Converseeb00cb22016-06-06 15:12:06 -070080 void *decrypt_state) {
Alex Converseacef60b2016-09-23 14:21:02 -070081#if CONFIG_ANS
82 (void)decrypt_cb;
83 (void)decrypt_state;
Alex Converse5b5140b2016-12-13 14:00:56 -080084 if (size > INT_MAX) return 1;
Alex Converse2cdf0d82016-12-13 13:53:09 -080085 return ans_read_init(r,
86#if ANS_MAX_SYMBOLS
87 (int)window_size,
88#endif
89 buffer, (int)size);
Nathan E. Egge8043cc42016-03-06 12:42:47 -050090#elif CONFIG_DAALA_EC
91 (void)decrypt_cb;
92 (void)decrypt_state;
Yaowu Xufebe9b02016-11-09 10:00:31 -080093 return aom_daala_reader_init(r, buffer, (int)size);
Alex Converseacef60b2016-09-23 14:21:02 -070094#else
Alex Converseeb00cb22016-06-06 15:12:06 -070095 return aom_dk_reader_init(r, buffer, size, decrypt_cb, decrypt_state);
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
Alex Converseeb00cb22016-06-06 15:12:06 -070099static INLINE const uint8_t *aom_reader_find_end(aom_reader *r) {
Alex Converseacef60b2016-09-23 14:21:02 -0700100#if CONFIG_ANS
101 (void)r;
102 assert(0 && "Use the raw buffer size with ANS");
103 return NULL;
Nathan E. Egge8043cc42016-03-06 12:42:47 -0500104#elif CONFIG_DAALA_EC
105 return aom_daala_reader_find_end(r);
Alex Converseacef60b2016-09-23 14:21:02 -0700106#else
Alex Converseeb00cb22016-06-06 15:12:06 -0700107 return aom_dk_reader_find_end(r);
Alex Converseacef60b2016-09-23 14:21:02 -0700108#endif
Alex Converseeb00cb22016-06-06 15:12:06 -0700109}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700110
Yaowu Xuf883b422016-08-30 14:01:10 -0700111static INLINE int aom_reader_has_error(aom_reader *r) {
Alex Converseacef60b2016-09-23 14:21:02 -0700112#if CONFIG_ANS
113 return ans_reader_has_error(r);
Nathan E. Egge8043cc42016-03-06 12:42:47 -0500114#elif CONFIG_DAALA_EC
115 return aom_daala_reader_has_error(r);
Alex Converseacef60b2016-09-23 14:21:02 -0700116#else
Alex Converseeb00cb22016-06-06 15:12:06 -0700117 return aom_dk_reader_has_error(r);
Alex Converseacef60b2016-09-23 14:21:02 -0700118#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700119}
120
Michael Bebenitad7baf452016-08-25 11:27:56 -0700121// Returns the position in the bit reader in bits.
Nathan E. Eggeb244f392016-09-06 23:48:43 -0400122static INLINE uint32_t aom_reader_tell(const aom_reader *r) {
Michael Bebenita868fc0b2016-08-03 16:13:04 -0700123#if CONFIG_ANS
124 (void)r;
125 assert(0 && "aom_reader_tell() is unimplemented for ANS");
126 return 0;
127#elif CONFIG_DAALA_EC
128 return aom_daala_reader_tell(r);
129#else
130 return aom_dk_reader_tell(r);
131#endif
132}
133
Michael Bebenitad7baf452016-08-25 11:27:56 -0700134// Returns the position in the bit reader in 1/8th bits.
Nathan E. Eggeb244f392016-09-06 23:48:43 -0400135static INLINE uint32_t aom_reader_tell_frac(const aom_reader *r) {
Michael Bebenitad7baf452016-08-25 11:27:56 -0700136#if CONFIG_ANS
137 (void)r;
138 assert(0 && "aom_reader_tell_frac() is unimplemented for ANS");
139 return 0;
140#elif CONFIG_DAALA_EC
141 return aom_daala_reader_tell_frac(r);
142#else
143 return aom_dk_reader_tell_frac(r);
144#endif
145}
146
Michael Bebenita6048d052016-08-25 14:40:54 -0700147#if CONFIG_ACCOUNTING
148static INLINE void aom_process_accounting(const aom_reader *r ACCT_STR_PARAM) {
149 if (r->accounting != NULL) {
150 uint32_t tell_frac;
151 tell_frac = aom_reader_tell_frac(r);
152 aom_accounting_record(r->accounting, ACCT_STR_NAME,
153 tell_frac - r->accounting->last_tell_frac);
154 r->accounting->last_tell_frac = tell_frac;
155 }
156}
157#endif
158
159static INLINE int aom_read_(aom_reader *r, int prob ACCT_STR_PARAM) {
160 int ret;
Alex Converseacef60b2016-09-23 14:21:02 -0700161#if CONFIG_ANS
Michael Bebenita6048d052016-08-25 14:40:54 -0700162 ret = uabs_read(r, prob);
Nathan E. Egge8043cc42016-03-06 12:42:47 -0500163#elif CONFIG_DAALA_EC
Michael Bebenita6048d052016-08-25 14:40:54 -0700164 ret = aom_daala_read(r, prob);
Alex Converseacef60b2016-09-23 14:21:02 -0700165#else
Michael Bebenita6048d052016-08-25 14:40:54 -0700166 ret = aom_dk_read(r, prob);
Alex Converseacef60b2016-09-23 14:21:02 -0700167#endif
Michael Bebenita6048d052016-08-25 14:40:54 -0700168#if CONFIG_ACCOUNTING
169 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
170#endif
171 return ret;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700172}
173
Michael Bebenita6048d052016-08-25 14:40:54 -0700174static INLINE int aom_read_bit_(aom_reader *r ACCT_STR_PARAM) {
175 int ret;
Alex Converseacef60b2016-09-23 14:21:02 -0700176#if CONFIG_ANS
Michael Bebenita6048d052016-08-25 14:40:54 -0700177 ret = uabs_read_bit(r); // Non trivial optimization at half probability
Nathan E. Egge08c99eb2016-11-09 13:40:26 -0500178#elif CONFIG_DAALA_EC
179 // Note this uses raw bits and is not the same as aom_daala_read(r, 128);
180 ret = aom_daala_read_bit(r);
Alex Converseacef60b2016-09-23 14:21:02 -0700181#else
Michael Bebenita6048d052016-08-25 14:40:54 -0700182 ret = aom_read(r, 128, NULL); // aom_prob_half
Alex Converseacef60b2016-09-23 14:21:02 -0700183#endif
Michael Bebenita6048d052016-08-25 14:40:54 -0700184#if CONFIG_ACCOUNTING
185 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
186#endif
187 return ret;
Alex Converseacef60b2016-09-23 14:21:02 -0700188}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700189
Michael Bebenita6048d052016-08-25 14:40:54 -0700190static INLINE int aom_read_literal_(aom_reader *r, int bits ACCT_STR_PARAM) {
Nathan E. Eggee691a242016-06-16 09:00:39 -0400191 int literal = 0, bit;
192
Michael Bebenita6048d052016-08-25 14:40:54 -0700193 for (bit = bits - 1; bit >= 0; bit--) literal |= aom_read_bit(r, NULL) << bit;
194#if CONFIG_ACCOUNTING
195 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
196#endif
Nathan E. Eggee691a242016-06-16 09:00:39 -0400197 return literal;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700198}
199
Michael Bebenita6048d052016-08-25 14:40:54 -0700200static INLINE int aom_read_tree_bits_(aom_reader *r, const aom_tree_index *tree,
201 const aom_prob *probs ACCT_STR_PARAM) {
Nathan E. Eggee691a242016-06-16 09:00:39 -0400202 aom_tree_index i = 0;
203
Michael Bebenita6048d052016-08-25 14:40:54 -0700204 while ((i = tree[i + aom_read(r, probs[i >> 1], NULL)]) > 0) continue;
205#if CONFIG_ACCOUNTING
206 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
207#endif
Nathan E. Eggee691a242016-06-16 09:00:39 -0400208 return -i;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700209}
210
Michael Bebenita6048d052016-08-25 14:40:54 -0700211static INLINE int aom_read_tree_(aom_reader *r, const aom_tree_index *tree,
212 const aom_prob *probs ACCT_STR_PARAM) {
213 int ret;
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500214#if CONFIG_DAALA_EC
Michael Bebenita6048d052016-08-25 14:40:54 -0700215 ret = daala_read_tree_bits(r, tree, probs);
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500216#else
Michael Bebenita6048d052016-08-25 14:40:54 -0700217 ret = aom_read_tree_bits(r, tree, probs, NULL);
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500218#endif
Michael Bebenita6048d052016-08-25 14:40:54 -0700219#if CONFIG_ACCOUNTING
220 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
221#endif
222 return ret;
Nathan E. Eggeeeedc632016-06-19 12:02:33 -0400223}
224
Alex Converse58c520a2016-10-20 14:21:06 -0700225#if CONFIG_EC_MULTISYMBOL
Nathan E. Eggee0698492017-01-06 19:40:36 -0500226static INLINE int aom_read_cdf_(aom_reader *r, aom_cdf_prob *cdf,
227 int nsymbs ACCT_STR_PARAM) {
Michael Bebenita6048d052016-08-25 14:40:54 -0700228 int ret;
Alex Converse1e4e29f2016-11-08 14:12:14 -0800229#if CONFIG_ANS
Alex Conversea1ac9722016-10-12 15:59:58 -0700230 (void)nsymbs;
Michael Bebenita6048d052016-08-25 14:40:54 -0700231 ret = rans_read(r, cdf);
232#elif CONFIG_DAALA_EC
233 ret = daala_read_symbol(r, cdf, nsymbs);
Alex Conversea1ac9722016-10-12 15:59:58 -0700234#else
Alex Converse58c520a2016-10-20 14:21:06 -0700235#error \
236 "CONFIG_EC_MULTISYMBOL is selected without a valid backing entropy " \
237 "coder. Enable daala_ec or ans for a valid configuration."
Alex Conversea1ac9722016-10-12 15:59:58 -0700238#endif
Alex Converse58c520a2016-10-20 14:21:06 -0700239
Michael Bebenita6048d052016-08-25 14:40:54 -0700240#if CONFIG_ACCOUNTING
241 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
Nathan E. Egge44460142016-06-20 13:44:22 -0400242#endif
Michael Bebenita6048d052016-08-25 14:40:54 -0700243 return ret;
Nathan E. Egge44460142016-06-20 13:44:22 -0400244}
Nathan E. Eggec98d2862016-12-21 11:30:46 -0500245
Nathan E. Eggee0698492017-01-06 19:40:36 -0500246static INLINE int aom_read_symbol_(aom_reader *r, aom_cdf_prob *cdf,
247 int nsymbs ACCT_STR_PARAM) {
248 int ret;
249 ret = aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME);
250#if CONFIG_EC_ADAPT
251 update_cdf(cdf, ret, nsymbs);
252#endif
253 return ret;
254}
255
Nathan E. Eggec98d2862016-12-21 11:30:46 -0500256#if CONFIG_PVQ
Nathan E. Eggee0698492017-01-06 19:40:36 -0500257static INLINE int aom_read_cdf_unscaled_(aom_reader *r, const aom_cdf_prob *cdf,
258 int nsymbs ACCT_STR_PARAM) {
Nathan E. Eggec98d2862016-12-21 11:30:46 -0500259 int ret;
260#if CONFIG_DAALA_EC
261 ret = od_ec_decode_cdf_unscaled(&r->ec, cdf, nsymbs);
262#else
263#error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
264#endif
265
266#if CONFIG_ACCOUNTING
267 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
268#endif
269 return ret;
270}
271#endif
Alex Converse58c520a2016-10-20 14:21:06 -0700272#endif // CONFIG_EC_MULTISYMBOL
Nathan E. Egge44460142016-06-20 13:44:22 -0400273
Yaowu Xuc27fc142016-08-22 16:08:15 -0700274#ifdef __cplusplus
275} // extern "C"
276#endif
277
Yaowu Xuf883b422016-08-30 14:01:10 -0700278#endif // AOM_DSP_BITREADER_H_