blob: 621a5d3aa96ec6b96bd77eb51d46cd640f3c6ee9 [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 Converse346440b2017-01-03 13:47:37 -080075 size_t size, aom_decrypt_cb decrypt_cb,
Alex Converseeb00cb22016-06-06 15:12:06 -070076 void *decrypt_state) {
Alex Converseacef60b2016-09-23 14:21:02 -070077#if CONFIG_ANS
78 (void)decrypt_cb;
79 (void)decrypt_state;
Alex Converse5b5140b2016-12-13 14:00:56 -080080 if (size > INT_MAX) return 1;
Alex Converse346440b2017-01-03 13:47:37 -080081 return ans_read_init(r, buffer, (int)size);
Nathan E. Egge8043cc42016-03-06 12:42:47 -050082#elif CONFIG_DAALA_EC
83 (void)decrypt_cb;
84 (void)decrypt_state;
Yaowu Xufebe9b02016-11-09 10:00:31 -080085 return aom_daala_reader_init(r, buffer, (int)size);
Alex Converseacef60b2016-09-23 14:21:02 -070086#else
Alex Converseeb00cb22016-06-06 15:12:06 -070087 return aom_dk_reader_init(r, buffer, size, decrypt_cb, decrypt_state);
Alex Converseacef60b2016-09-23 14:21:02 -070088#endif
Alex Converseeb00cb22016-06-06 15:12:06 -070089}
Yaowu Xuc27fc142016-08-22 16:08:15 -070090
Alex Converseeb00cb22016-06-06 15:12:06 -070091static INLINE const uint8_t *aom_reader_find_end(aom_reader *r) {
Alex Converseacef60b2016-09-23 14:21:02 -070092#if CONFIG_ANS
93 (void)r;
94 assert(0 && "Use the raw buffer size with ANS");
95 return NULL;
Nathan E. Egge8043cc42016-03-06 12:42:47 -050096#elif CONFIG_DAALA_EC
97 return aom_daala_reader_find_end(r);
Alex Converseacef60b2016-09-23 14:21:02 -070098#else
Alex Converseeb00cb22016-06-06 15:12:06 -070099 return aom_dk_reader_find_end(r);
Alex Converseacef60b2016-09-23 14:21:02 -0700100#endif
Alex Converseeb00cb22016-06-06 15:12:06 -0700101}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700102
Yaowu Xuf883b422016-08-30 14:01:10 -0700103static INLINE int aom_reader_has_error(aom_reader *r) {
Alex Converseacef60b2016-09-23 14:21:02 -0700104#if CONFIG_ANS
105 return ans_reader_has_error(r);
Nathan E. Egge8043cc42016-03-06 12:42:47 -0500106#elif CONFIG_DAALA_EC
107 return aom_daala_reader_has_error(r);
Alex Converseacef60b2016-09-23 14:21:02 -0700108#else
Alex Converseeb00cb22016-06-06 15:12:06 -0700109 return aom_dk_reader_has_error(r);
Alex Converseacef60b2016-09-23 14:21:02 -0700110#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700111}
112
Michael Bebenitad7baf452016-08-25 11:27:56 -0700113// Returns the position in the bit reader in bits.
Nathan E. Eggeb244f392016-09-06 23:48:43 -0400114static INLINE uint32_t aom_reader_tell(const aom_reader *r) {
Michael Bebenita868fc0b2016-08-03 16:13:04 -0700115#if CONFIG_ANS
116 (void)r;
117 assert(0 && "aom_reader_tell() is unimplemented for ANS");
118 return 0;
119#elif CONFIG_DAALA_EC
120 return aom_daala_reader_tell(r);
121#else
122 return aom_dk_reader_tell(r);
123#endif
124}
125
Michael Bebenitad7baf452016-08-25 11:27:56 -0700126// Returns the position in the bit reader in 1/8th bits.
Nathan E. Eggeb244f392016-09-06 23:48:43 -0400127static INLINE uint32_t aom_reader_tell_frac(const aom_reader *r) {
Michael Bebenitad7baf452016-08-25 11:27:56 -0700128#if CONFIG_ANS
129 (void)r;
130 assert(0 && "aom_reader_tell_frac() is unimplemented for ANS");
131 return 0;
132#elif CONFIG_DAALA_EC
133 return aom_daala_reader_tell_frac(r);
134#else
135 return aom_dk_reader_tell_frac(r);
136#endif
137}
138
Michael Bebenita6048d052016-08-25 14:40:54 -0700139#if CONFIG_ACCOUNTING
140static INLINE void aom_process_accounting(const aom_reader *r ACCT_STR_PARAM) {
141 if (r->accounting != NULL) {
142 uint32_t tell_frac;
143 tell_frac = aom_reader_tell_frac(r);
144 aom_accounting_record(r->accounting, ACCT_STR_NAME,
145 tell_frac - r->accounting->last_tell_frac);
146 r->accounting->last_tell_frac = tell_frac;
147 }
148}
149#endif
150
151static INLINE int aom_read_(aom_reader *r, int prob ACCT_STR_PARAM) {
152 int ret;
Alex Converseacef60b2016-09-23 14:21:02 -0700153#if CONFIG_ANS
Alex Conversec54692b2017-01-25 16:41:05 -0800154 ret = rabs_read(r, prob);
Nathan E. Egge8043cc42016-03-06 12:42:47 -0500155#elif CONFIG_DAALA_EC
Michael Bebenita6048d052016-08-25 14:40:54 -0700156 ret = aom_daala_read(r, prob);
Alex Converseacef60b2016-09-23 14:21:02 -0700157#else
Michael Bebenita6048d052016-08-25 14:40:54 -0700158 ret = aom_dk_read(r, prob);
Alex Converseacef60b2016-09-23 14:21:02 -0700159#endif
Michael Bebenita6048d052016-08-25 14:40:54 -0700160#if CONFIG_ACCOUNTING
161 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
162#endif
163 return ret;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700164}
165
Michael Bebenita6048d052016-08-25 14:40:54 -0700166static INLINE int aom_read_bit_(aom_reader *r ACCT_STR_PARAM) {
167 int ret;
Alex Converseacef60b2016-09-23 14:21:02 -0700168#if CONFIG_ANS
Alex Conversec54692b2017-01-25 16:41:05 -0800169 ret = rabs_read_bit(r); // Non trivial optimization at half probability
Nathan E. Egge24f1a902017-02-14 13:29:44 -0500170#elif CONFIG_DAALA_EC && CONFIG_RAWBITS
Nathan E. Egge08c99eb2016-11-09 13:40:26 -0500171 // Note this uses raw bits and is not the same as aom_daala_read(r, 128);
172 ret = aom_daala_read_bit(r);
Alex Converseacef60b2016-09-23 14:21:02 -0700173#else
Michael Bebenita6048d052016-08-25 14:40:54 -0700174 ret = aom_read(r, 128, NULL); // aom_prob_half
Alex Converseacef60b2016-09-23 14:21:02 -0700175#endif
Michael Bebenita6048d052016-08-25 14:40:54 -0700176#if CONFIG_ACCOUNTING
177 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
178#endif
179 return ret;
Alex Converseacef60b2016-09-23 14:21:02 -0700180}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700181
Michael Bebenita6048d052016-08-25 14:40:54 -0700182static INLINE int aom_read_literal_(aom_reader *r, int bits ACCT_STR_PARAM) {
Nathan E. Eggee691a242016-06-16 09:00:39 -0400183 int literal = 0, bit;
184
Michael Bebenita6048d052016-08-25 14:40:54 -0700185 for (bit = bits - 1; bit >= 0; bit--) literal |= aom_read_bit(r, NULL) << bit;
186#if CONFIG_ACCOUNTING
187 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
188#endif
Nathan E. Eggee691a242016-06-16 09:00:39 -0400189 return literal;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700190}
191
Michael Bebenita6048d052016-08-25 14:40:54 -0700192static INLINE int aom_read_tree_bits_(aom_reader *r, const aom_tree_index *tree,
193 const aom_prob *probs ACCT_STR_PARAM) {
Nathan E. Eggee691a242016-06-16 09:00:39 -0400194 aom_tree_index i = 0;
195
Michael Bebenita6048d052016-08-25 14:40:54 -0700196 while ((i = tree[i + aom_read(r, probs[i >> 1], NULL)]) > 0) continue;
197#if CONFIG_ACCOUNTING
198 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
199#endif
Nathan E. Eggee691a242016-06-16 09:00:39 -0400200 return -i;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700201}
202
Michael Bebenita6048d052016-08-25 14:40:54 -0700203static INLINE int aom_read_tree_(aom_reader *r, const aom_tree_index *tree,
204 const aom_prob *probs ACCT_STR_PARAM) {
205 int ret;
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500206#if CONFIG_DAALA_EC
Michael Bebenita6048d052016-08-25 14:40:54 -0700207 ret = daala_read_tree_bits(r, tree, probs);
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500208#else
Michael Bebenita6048d052016-08-25 14:40:54 -0700209 ret = aom_read_tree_bits(r, tree, probs, NULL);
Nathan E. Egge43acafd2016-03-06 13:41:53 -0500210#endif
Michael Bebenita6048d052016-08-25 14:40:54 -0700211#if CONFIG_ACCOUNTING
212 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
213#endif
214 return ret;
Nathan E. Eggeeeedc632016-06-19 12:02:33 -0400215}
216
Alex Converse58c520a2016-10-20 14:21:06 -0700217#if CONFIG_EC_MULTISYMBOL
Nathan E. Egge2d8dd962016-12-23 10:42:43 -0500218static INLINE int aom_read_cdf_(aom_reader *r, const aom_cdf_prob *cdf,
Nathan E. Eggee0698492017-01-06 19:40:36 -0500219 int nsymbs ACCT_STR_PARAM) {
Michael Bebenita6048d052016-08-25 14:40:54 -0700220 int ret;
Alex Converse1e4e29f2016-11-08 14:12:14 -0800221#if CONFIG_ANS
Alex Conversea1ac9722016-10-12 15:59:58 -0700222 (void)nsymbs;
Michael Bebenita6048d052016-08-25 14:40:54 -0700223 ret = rans_read(r, cdf);
224#elif CONFIG_DAALA_EC
225 ret = daala_read_symbol(r, cdf, nsymbs);
Alex Conversea1ac9722016-10-12 15:59:58 -0700226#else
Alex Converse58c520a2016-10-20 14:21:06 -0700227#error \
228 "CONFIG_EC_MULTISYMBOL is selected without a valid backing entropy " \
229 "coder. Enable daala_ec or ans for a valid configuration."
Alex Conversea1ac9722016-10-12 15:59:58 -0700230#endif
Alex Converse58c520a2016-10-20 14:21:06 -0700231
Michael Bebenita6048d052016-08-25 14:40:54 -0700232#if CONFIG_ACCOUNTING
233 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
Nathan E. Egge44460142016-06-20 13:44:22 -0400234#endif
Michael Bebenita6048d052016-08-25 14:40:54 -0700235 return ret;
Nathan E. Egge44460142016-06-20 13:44:22 -0400236}
Nathan E. Eggec98d2862016-12-21 11:30:46 -0500237
Nathan E. Eggee0698492017-01-06 19:40:36 -0500238static INLINE int aom_read_symbol_(aom_reader *r, aom_cdf_prob *cdf,
239 int nsymbs ACCT_STR_PARAM) {
240 int ret;
241 ret = aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME);
242#if CONFIG_EC_ADAPT
243 update_cdf(cdf, ret, nsymbs);
244#endif
245 return ret;
246}
247
Nathan E. Eggec98d2862016-12-21 11:30:46 -0500248#if CONFIG_PVQ
Nathan E. Eggee0698492017-01-06 19:40:36 -0500249static INLINE int aom_read_cdf_unscaled_(aom_reader *r, const aom_cdf_prob *cdf,
250 int nsymbs ACCT_STR_PARAM) {
Nathan E. Eggec98d2862016-12-21 11:30:46 -0500251 int ret;
252#if CONFIG_DAALA_EC
253 ret = od_ec_decode_cdf_unscaled(&r->ec, cdf, nsymbs);
254#else
255#error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
256#endif
257
258#if CONFIG_ACCOUNTING
259 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
260#endif
261 return ret;
262}
263#endif
Alex Converse58c520a2016-10-20 14:21:06 -0700264#endif // CONFIG_EC_MULTISYMBOL
Nathan E. Egge44460142016-06-20 13:44:22 -0400265
Yaowu Xuc27fc142016-08-22 16:08:15 -0700266#ifdef __cplusplus
267} // extern "C"
268#endif
269
Yaowu Xuf883b422016-08-30 14:01:10 -0700270#endif // AOM_DSP_BITREADER_H_