blob: 297395d8532196867fcda703cdbe350ec36b63d7 [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
Yaowu Xuf883b422016-08-30 14:01:10 -070020#include "aom/aomdx.h"
21#include "aom/aom_integer.h"
Alex Converseacef60b2016-09-23 14:21:02 -070022#if CONFIG_ANS
Alex Converse7fe2ae82016-09-28 11:33:20 -070023#include "aom_dsp/ansreader.h"
Alex Converseacef60b2016-09-23 14:21:02 -070024#else
Nathan E. Egge476c63c2017-05-18 18:35:16 -040025#include "aom_dsp/daalaboolreader.h"
Alex Converseacef60b2016-09-23 14:21:02 -070026#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070027#include "aom_dsp/prob.h"
Nathan E. Egge44460142016-06-20 13:44:22 -040028#include "av1/common/odintrin.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070029
Michael Bebenita6048d052016-08-25 14:40:54 -070030#if CONFIG_ACCOUNTING
Luc Trudeau83fbd572017-04-21 11:24:34 -040031#include "av1/decoder/accounting.h"
Michael Bebenita6048d052016-08-25 14:40:54 -070032#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. Eggee0698492017-01-06 19:40:36 -050048#define aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME) \
49 aom_read_cdf_(r, cdf, nsymbs ACCT_STR_ARG(ACCT_STR_NAME))
Michael Bebenita6048d052016-08-25 14:40:54 -070050#define aom_read_symbol(r, cdf, nsymbs, ACCT_STR_NAME) \
51 aom_read_symbol_(r, cdf, nsymbs ACCT_STR_ARG(ACCT_STR_NAME))
52
Jingning Han94cea4a2017-09-30 14:13:23 -070053#if CONFIG_LV_MAP
54#define aom_read_bin(r, cdf, nsymbs, ACCT_STR_NAME) \
55 aom_read_bin_(r, cdf, nsymbs ACCT_STR_ARG(ACCT_STR_NAME))
56#endif
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;
64#else
Nathan E. Egge476c63c2017-05-18 18:35:16 -040065typedef struct daala_reader aom_reader;
Alex Converseacef60b2016-09-23 14:21:02 -070066#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070067
Alex Converseeb00cb22016-06-06 15:12:06 -070068static INLINE int aom_reader_init(aom_reader *r, const uint8_t *buffer,
Alex Converse346440b2017-01-03 13:47:37 -080069 size_t size, aom_decrypt_cb decrypt_cb,
Alex Converseeb00cb22016-06-06 15:12:06 -070070 void *decrypt_state) {
Alex Converseacef60b2016-09-23 14:21:02 -070071 (void)decrypt_cb;
72 (void)decrypt_state;
Nathan E. Egge476c63c2017-05-18 18:35:16 -040073#if CONFIG_ANS
Alex Converse5b5140b2016-12-13 14:00:56 -080074 if (size > INT_MAX) return 1;
Alex Converse346440b2017-01-03 13:47:37 -080075 return ans_read_init(r, buffer, (int)size);
Alex Converseacef60b2016-09-23 14:21:02 -070076#else
Nathan E. Egge476c63c2017-05-18 18:35:16 -040077 return aom_daala_reader_init(r, buffer, (int)size);
Alex Converseacef60b2016-09-23 14:21:02 -070078#endif
Alex Converseeb00cb22016-06-06 15:12:06 -070079}
Yaowu Xuc27fc142016-08-22 16:08:15 -070080
Alex Converseeb00cb22016-06-06 15:12:06 -070081static INLINE const uint8_t *aom_reader_find_end(aom_reader *r) {
Alex Converseacef60b2016-09-23 14:21:02 -070082#if CONFIG_ANS
83 (void)r;
84 assert(0 && "Use the raw buffer size with ANS");
85 return NULL;
86#else
Nathan E. Egge476c63c2017-05-18 18:35:16 -040087 return aom_daala_reader_find_end(r);
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
Yaowu Xuf883b422016-08-30 14:01:10 -070091static INLINE int aom_reader_has_error(aom_reader *r) {
Alex Converseacef60b2016-09-23 14:21:02 -070092#if CONFIG_ANS
93 return ans_reader_has_error(r);
94#else
Nathan E. Egge476c63c2017-05-18 18:35:16 -040095 return aom_daala_reader_has_error(r);
Alex Converseacef60b2016-09-23 14:21:02 -070096#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070097}
98
Michael Bebenitad7baf452016-08-25 11:27:56 -070099// Returns the position in the bit reader in bits.
Nathan E. Eggeb244f392016-09-06 23:48:43 -0400100static INLINE uint32_t aom_reader_tell(const aom_reader *r) {
Michael Bebenita868fc0b2016-08-03 16:13:04 -0700101#if CONFIG_ANS
102 (void)r;
103 assert(0 && "aom_reader_tell() is unimplemented for ANS");
104 return 0;
Michael Bebenita868fc0b2016-08-03 16:13:04 -0700105#else
Nathan E. Egge476c63c2017-05-18 18:35:16 -0400106 return aom_daala_reader_tell(r);
Michael Bebenita868fc0b2016-08-03 16:13:04 -0700107#endif
108}
109
Michael Bebenitad7baf452016-08-25 11:27:56 -0700110// Returns the position in the bit reader in 1/8th bits.
Nathan E. Eggeb244f392016-09-06 23:48:43 -0400111static INLINE uint32_t aom_reader_tell_frac(const aom_reader *r) {
Michael Bebenitad7baf452016-08-25 11:27:56 -0700112#if CONFIG_ANS
113 (void)r;
114 assert(0 && "aom_reader_tell_frac() is unimplemented for ANS");
115 return 0;
Michael Bebenitad7baf452016-08-25 11:27:56 -0700116#else
Nathan E. Egge476c63c2017-05-18 18:35:16 -0400117 return aom_daala_reader_tell_frac(r);
Michael Bebenitad7baf452016-08-25 11:27:56 -0700118#endif
119}
120
Michael Bebenita6048d052016-08-25 14:40:54 -0700121#if CONFIG_ACCOUNTING
122static INLINE void aom_process_accounting(const aom_reader *r ACCT_STR_PARAM) {
123 if (r->accounting != NULL) {
124 uint32_t tell_frac;
125 tell_frac = aom_reader_tell_frac(r);
126 aom_accounting_record(r->accounting, ACCT_STR_NAME,
127 tell_frac - r->accounting->last_tell_frac);
128 r->accounting->last_tell_frac = tell_frac;
129 }
130}
Thomas Daviesf7f87ff2017-03-01 16:24:56 +0000131
Yaowu Xu4ff59b52017-04-24 12:41:56 -0700132static INLINE void aom_update_symb_counts(const aom_reader *r, int is_binary) {
Thomas Daviesf7f87ff2017-03-01 16:24:56 +0000133 if (r->accounting != NULL) {
134 r->accounting->syms.num_multi_syms += !is_binary;
135 r->accounting->syms.num_binary_syms += !!is_binary;
136 }
137}
Michael Bebenita6048d052016-08-25 14:40:54 -0700138#endif
139
140static INLINE int aom_read_(aom_reader *r, int prob ACCT_STR_PARAM) {
141 int ret;
Alex Converseacef60b2016-09-23 14:21:02 -0700142#if CONFIG_ANS
Alex Conversec54692b2017-01-25 16:41:05 -0800143 ret = rabs_read(r, prob);
Alex Converseacef60b2016-09-23 14:21:02 -0700144#else
Nathan E. Egge476c63c2017-05-18 18:35:16 -0400145 ret = aom_daala_read(r, prob);
Alex Converseacef60b2016-09-23 14:21:02 -0700146#endif
Michael Bebenita6048d052016-08-25 14:40:54 -0700147#if CONFIG_ACCOUNTING
148 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
Thomas Daviesf7f87ff2017-03-01 16:24:56 +0000149 aom_update_symb_counts(r, 1);
Michael Bebenita6048d052016-08-25 14:40:54 -0700150#endif
151 return ret;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700152}
153
Michael Bebenita6048d052016-08-25 14:40:54 -0700154static INLINE int aom_read_bit_(aom_reader *r 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_bit(r); // Non trivial optimization at half probability
Nathan E. Egge476c63c2017-05-18 18:35:16 -0400158#elif CONFIG_RAWBITS
Nathan E. Egge08c99eb2016-11-09 13:40:26 -0500159 // Note this uses raw bits and is not the same as aom_daala_read(r, 128);
Thomas Daviesf7f87ff2017-03-01 16:24:56 +0000160 // Calls to this function are omitted from raw symbol accounting.
Nathan E. Egge08c99eb2016-11-09 13:40:26 -0500161 ret = aom_daala_read_bit(r);
Alex Converseacef60b2016-09-23 14:21:02 -0700162#else
Michael Bebenita6048d052016-08-25 14:40:54 -0700163 ret = aom_read(r, 128, NULL); // aom_prob_half
Alex Converseacef60b2016-09-23 14:21:02 -0700164#endif
Michael Bebenita6048d052016-08-25 14:40:54 -0700165#if CONFIG_ACCOUNTING
166 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
167#endif
168 return ret;
Alex Converseacef60b2016-09-23 14:21:02 -0700169}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700170
Michael Bebenita6048d052016-08-25 14:40:54 -0700171static INLINE int aom_read_literal_(aom_reader *r, int bits ACCT_STR_PARAM) {
Nathan E. Eggee691a242016-06-16 09:00:39 -0400172 int literal = 0, bit;
173
Michael Bebenita6048d052016-08-25 14:40:54 -0700174 for (bit = bits - 1; bit >= 0; bit--) literal |= aom_read_bit(r, NULL) << bit;
175#if CONFIG_ACCOUNTING
176 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
177#endif
Nathan E. Eggee691a242016-06-16 09:00:39 -0400178 return literal;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700179}
180
Nathan E. Egge2d8dd962016-12-23 10:42:43 -0500181static INLINE int aom_read_cdf_(aom_reader *r, const aom_cdf_prob *cdf,
Nathan E. Eggee0698492017-01-06 19:40:36 -0500182 int nsymbs ACCT_STR_PARAM) {
Michael Bebenita6048d052016-08-25 14:40:54 -0700183 int ret;
Alex Converse1e4e29f2016-11-08 14:12:14 -0800184#if CONFIG_ANS
Alex Conversea1ac9722016-10-12 15:59:58 -0700185 (void)nsymbs;
Michael Bebenita6048d052016-08-25 14:40:54 -0700186 ret = rans_read(r, cdf);
Alex Conversea1ac9722016-10-12 15:59:58 -0700187#else
Nathan E. Eggecd539512017-05-16 12:00:36 -0400188 ret = daala_read_symbol(r, cdf, nsymbs);
Alex Conversea1ac9722016-10-12 15:59:58 -0700189#endif
Alex Converse58c520a2016-10-20 14:21:06 -0700190
Michael Bebenita6048d052016-08-25 14:40:54 -0700191#if CONFIG_ACCOUNTING
192 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
Thomas Daviesf7f87ff2017-03-01 16:24:56 +0000193 aom_update_symb_counts(r, (nsymbs == 2));
Nathan E. Egge44460142016-06-20 13:44:22 -0400194#endif
Michael Bebenita6048d052016-08-25 14:40:54 -0700195 return ret;
Nathan E. Egge44460142016-06-20 13:44:22 -0400196}
Nathan E. Eggec98d2862016-12-21 11:30:46 -0500197
Nathan E. Eggee0698492017-01-06 19:40:36 -0500198static INLINE int aom_read_symbol_(aom_reader *r, aom_cdf_prob *cdf,
199 int nsymbs ACCT_STR_PARAM) {
200 int ret;
201 ret = aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME);
Nathan E. Eggee0698492017-01-06 19:40:36 -0500202 update_cdf(cdf, ret, nsymbs);
Nathan E. Eggee0698492017-01-06 19:40:36 -0500203 return ret;
204}
205
Jingning Han94cea4a2017-09-30 14:13:23 -0700206#if CONFIG_LV_MAP
207static INLINE int aom_read_bin_(aom_reader *r, aom_cdf_prob *cdf,
208 int nsymbs ACCT_STR_PARAM) {
209 int ret;
Jingning Han1c077a42017-10-11 08:49:15 -0700210 aom_cdf_prob this_cdf[3] = { (aom_cdf_prob)((cdf[0] >> 8) << 8), 0, 0 };
211 this_cdf[0] = clamp(this_cdf[0], (1 << 8), (127 << 8));
Jingning Han31122f52017-10-02 09:06:40 -0700212 ret = aom_read_cdf(r, this_cdf, nsymbs, ACCT_STR_NAME);
213 update_bin(cdf, ret, nsymbs);
Jingning Han94cea4a2017-09-30 14:13:23 -0700214 return ret;
215}
216#endif
217
Nathan E. Egge0f11c782017-02-12 19:04:04 -0500218static INLINE int aom_read_tree_as_cdf(aom_reader *r,
219 const aom_tree_index *tree,
220 const aom_prob *probs) {
221 aom_tree_index i = 0;
222 do {
223 aom_cdf_prob cdf[16];
224 aom_tree_index index[16];
225 int path[16];
226 int dist[16];
227 int nsymbs;
228 int symb;
229 nsymbs = tree_to_cdf(tree, probs, i, cdf, index, path, dist);
230 symb = aom_read_cdf(r, cdf, nsymbs, NULL);
231 OD_ASSERT(symb >= 0 && symb < nsymbs);
232 i = index[symb];
233 } while (i > 0);
234 return -i;
235}
Nathan E. Egge44460142016-06-20 13:44:22 -0400236
Nathan E. Egge0f11c782017-02-12 19:04:04 -0500237static INLINE int aom_read_tree_(aom_reader *r, const aom_tree_index *tree,
238 const aom_prob *probs ACCT_STR_PARAM) {
239 int ret;
Nathan E. Egge0f11c782017-02-12 19:04:04 -0500240 ret = aom_read_tree_as_cdf(r, tree, probs);
Nathan E. Egge0f11c782017-02-12 19:04:04 -0500241#if CONFIG_ACCOUNTING
242 if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
243#endif
244 return ret;
245}
246
Yaowu Xuc27fc142016-08-22 16:08:15 -0700247#ifdef __cplusplus
248} // extern "C"
249#endif
250
Yaowu Xuf883b422016-08-30 14:01:10 -0700251#endif // AOM_DSP_BITREADER_H_