Line data Source code
1 : /*
2 : * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 : *
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.
10 : */
11 :
12 : #ifndef AOM_DSP_BITREADER_H_
13 : #define AOM_DSP_BITREADER_H_
14 :
15 : #include <assert.h>
16 : #include <limits.h>
17 :
18 : #include "./aom_config.h"
19 :
20 : #include "aom/aomdx.h"
21 : #include "aom/aom_integer.h"
22 : #if CONFIG_ANS
23 : #include "aom_dsp/ansreader.h"
24 : #else
25 : #include "aom_dsp/daalaboolreader.h"
26 : #endif
27 : #include "aom_dsp/prob.h"
28 : #include "av1/common/odintrin.h"
29 :
30 : #if CONFIG_ACCOUNTING
31 : #include "av1/decoder/accounting.h"
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))
48 : #define aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME) \
49 : aom_read_cdf_(r, cdf, nsymbs ACCT_STR_ARG(ACCT_STR_NAME))
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 :
53 : #ifdef __cplusplus
54 : extern "C" {
55 : #endif
56 :
57 : #if CONFIG_ANS
58 : typedef struct AnsDecoder aom_reader;
59 : #else
60 : typedef struct daala_reader aom_reader;
61 : #endif
62 :
63 0 : static INLINE int aom_reader_init(aom_reader *r, const uint8_t *buffer,
64 : size_t size, aom_decrypt_cb decrypt_cb,
65 : void *decrypt_state) {
66 : (void)decrypt_cb;
67 : (void)decrypt_state;
68 : #if CONFIG_ANS
69 : if (size > INT_MAX) return 1;
70 : return ans_read_init(r, buffer, (int)size);
71 : #else
72 0 : return aom_daala_reader_init(r, buffer, (int)size);
73 : #endif
74 : }
75 :
76 0 : static INLINE const uint8_t *aom_reader_find_end(aom_reader *r) {
77 : #if CONFIG_ANS
78 : (void)r;
79 : assert(0 && "Use the raw buffer size with ANS");
80 : return NULL;
81 : #else
82 0 : return aom_daala_reader_find_end(r);
83 : #endif
84 : }
85 :
86 0 : static INLINE int aom_reader_has_error(aom_reader *r) {
87 : #if CONFIG_ANS
88 : return ans_reader_has_error(r);
89 : #else
90 0 : return aom_daala_reader_has_error(r);
91 : #endif
92 : }
93 :
94 : // Returns the position in the bit reader in bits.
95 : static INLINE uint32_t aom_reader_tell(const aom_reader *r) {
96 : #if CONFIG_ANS
97 : (void)r;
98 : assert(0 && "aom_reader_tell() is unimplemented for ANS");
99 : return 0;
100 : #else
101 : return aom_daala_reader_tell(r);
102 : #endif
103 : }
104 :
105 : // Returns the position in the bit reader in 1/8th bits.
106 : static INLINE uint32_t aom_reader_tell_frac(const aom_reader *r) {
107 : #if CONFIG_ANS
108 : (void)r;
109 : assert(0 && "aom_reader_tell_frac() is unimplemented for ANS");
110 : return 0;
111 : #else
112 : return aom_daala_reader_tell_frac(r);
113 : #endif
114 : }
115 :
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 : }
126 :
127 : static INLINE void aom_update_symb_counts(const aom_reader *r, int is_binary) {
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 : }
133 : #endif
134 :
135 0 : static INLINE int aom_read_(aom_reader *r, int prob ACCT_STR_PARAM) {
136 : int ret;
137 : #if CONFIG_ANS
138 : ret = rabs_read(r, prob);
139 : #else
140 0 : ret = aom_daala_read(r, prob);
141 : #endif
142 : #if CONFIG_ACCOUNTING
143 : if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
144 : aom_update_symb_counts(r, 1);
145 : #endif
146 0 : return ret;
147 : }
148 :
149 0 : static INLINE int aom_read_bit_(aom_reader *r ACCT_STR_PARAM) {
150 : int ret;
151 : #if CONFIG_ANS
152 : ret = rabs_read_bit(r); // Non trivial optimization at half probability
153 : #elif CONFIG_RAWBITS
154 : // Note this uses raw bits and is not the same as aom_daala_read(r, 128);
155 : // Calls to this function are omitted from raw symbol accounting.
156 : ret = aom_daala_read_bit(r);
157 : #else
158 0 : ret = aom_read(r, 128, NULL); // aom_prob_half
159 : #endif
160 : #if CONFIG_ACCOUNTING
161 : if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
162 : #endif
163 0 : return ret;
164 : }
165 :
166 0 : static INLINE int aom_read_literal_(aom_reader *r, int bits ACCT_STR_PARAM) {
167 0 : int literal = 0, bit;
168 :
169 0 : 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
173 0 : return literal;
174 : }
175 :
176 0 : static INLINE int aom_read_cdf_(aom_reader *r, const aom_cdf_prob *cdf,
177 : int nsymbs ACCT_STR_PARAM) {
178 : int ret;
179 : #if CONFIG_ANS
180 : (void)nsymbs;
181 : ret = rans_read(r, cdf);
182 : #else
183 0 : ret = daala_read_symbol(r, cdf, nsymbs);
184 : #endif
185 :
186 : #if CONFIG_ACCOUNTING
187 : if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
188 : aom_update_symb_counts(r, (nsymbs == 2));
189 : #endif
190 0 : return ret;
191 : }
192 :
193 0 : static INLINE int aom_read_symbol_(aom_reader *r, aom_cdf_prob *cdf,
194 : int nsymbs ACCT_STR_PARAM) {
195 : int ret;
196 0 : ret = aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME);
197 : #if CONFIG_EC_ADAPT
198 0 : update_cdf(cdf, ret, nsymbs);
199 : #endif
200 0 : return ret;
201 : }
202 :
203 0 : static INLINE int aom_read_tree_as_cdf(aom_reader *r,
204 : const aom_tree_index *tree,
205 : const aom_prob *probs) {
206 0 : aom_tree_index i = 0;
207 : do {
208 : aom_cdf_prob cdf[16];
209 : aom_tree_index index[16];
210 : int path[16];
211 : int dist[16];
212 : int nsymbs;
213 : int symb;
214 0 : nsymbs = tree_to_cdf(tree, probs, i, cdf, index, path, dist);
215 0 : symb = aom_read_cdf(r, cdf, nsymbs, NULL);
216 0 : OD_ASSERT(symb >= 0 && symb < nsymbs);
217 0 : i = index[symb];
218 0 : } while (i > 0);
219 0 : return -i;
220 : }
221 :
222 0 : static INLINE int aom_read_tree_(aom_reader *r, const aom_tree_index *tree,
223 : const aom_prob *probs ACCT_STR_PARAM) {
224 : int ret;
225 0 : ret = aom_read_tree_as_cdf(r, tree, probs);
226 : #if CONFIG_ACCOUNTING
227 : if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
228 : #endif
229 0 : return ret;
230 : }
231 :
232 : #ifdef __cplusplus
233 : } // extern "C"
234 : #endif
235 :
236 : #endif // AOM_DSP_BITREADER_H_
|