/src/aom/aom_dsp/bitreader.h
Line | Count | Source (jump to first uncovered line) |
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_AOM_DSP_BITREADER_H_ |
13 | | #define AOM_AOM_DSP_BITREADER_H_ |
14 | | |
15 | | #include <assert.h> |
16 | | #include <limits.h> |
17 | | |
18 | | #include "config/aom_config.h" |
19 | | |
20 | | #include "aom/aomdx.h" |
21 | | #include "aom/aom_integer.h" |
22 | | #include "aom_dsp/entdec.h" |
23 | | #include "aom_dsp/odintrin.h" |
24 | | #include "aom_dsp/prob.h" |
25 | | |
26 | | #if CONFIG_BITSTREAM_DEBUG |
27 | | #include "aom_util/debug_util.h" |
28 | | #endif // CONFIG_BITSTREAM_DEBUG |
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 | 0 | aom_read_(r, prob ACCT_STR_ARG(ACCT_STR_NAME)) |
42 | | #define aom_read_bit(r, ACCT_STR_NAME) \ |
43 | 0 | 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 | 0 | aom_read_literal_(r, bits ACCT_STR_ARG(ACCT_STR_NAME)) |
48 | | #define aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME) \ |
49 | 0 | aom_read_cdf_(r, cdf, nsymbs ACCT_STR_ARG(ACCT_STR_NAME)) |
50 | | #define aom_read_symbol(r, cdf, nsymbs, ACCT_STR_NAME) \ |
51 | 0 | aom_read_symbol_(r, cdf, nsymbs ACCT_STR_ARG(ACCT_STR_NAME)) |
52 | | |
53 | | #ifdef __cplusplus |
54 | | extern "C" { |
55 | | #endif |
56 | | |
57 | | struct aom_reader { |
58 | | const uint8_t *buffer; |
59 | | const uint8_t *buffer_end; |
60 | | od_ec_dec ec; |
61 | | #if CONFIG_ACCOUNTING |
62 | | Accounting *accounting; |
63 | | #endif |
64 | | uint8_t allow_update_cdf; |
65 | | }; |
66 | | |
67 | | typedef struct aom_reader aom_reader; |
68 | | |
69 | | int aom_reader_init(aom_reader *r, const uint8_t *buffer, size_t size); |
70 | | |
71 | | const uint8_t *aom_reader_find_begin(aom_reader *r); |
72 | | |
73 | | const uint8_t *aom_reader_find_end(aom_reader *r); |
74 | | |
75 | | // Returns true if the bit reader has tried to decode more data from the buffer |
76 | | // than was actually provided. |
77 | | int aom_reader_has_overflowed(const aom_reader *r); |
78 | | |
79 | | // Returns the position in the bit reader in bits. |
80 | | uint32_t aom_reader_tell(const aom_reader *r); |
81 | | |
82 | | // Returns the position in the bit reader in 1/8th bits. |
83 | | uint32_t aom_reader_tell_frac(const aom_reader *r); |
84 | | |
85 | | #if CONFIG_ACCOUNTING |
86 | | static INLINE void aom_process_accounting(const aom_reader *r ACCT_STR_PARAM) { |
87 | | if (r->accounting != NULL) { |
88 | | uint32_t tell_frac; |
89 | | tell_frac = aom_reader_tell_frac(r); |
90 | | aom_accounting_record(r->accounting, ACCT_STR_NAME, |
91 | | tell_frac - r->accounting->last_tell_frac); |
92 | | r->accounting->last_tell_frac = tell_frac; |
93 | | } |
94 | | } |
95 | | |
96 | | static INLINE void aom_update_symb_counts(const aom_reader *r, int is_binary) { |
97 | | if (r->accounting != NULL) { |
98 | | r->accounting->syms.num_multi_syms += !is_binary; |
99 | | r->accounting->syms.num_binary_syms += !!is_binary; |
100 | | } |
101 | | } |
102 | | #endif |
103 | | |
104 | 0 | static INLINE int aom_read_(aom_reader *r, int prob ACCT_STR_PARAM) { |
105 | 0 | int p = (0x7FFFFF - (prob << 15) + prob) >> 8; |
106 | 0 | int bit = od_ec_decode_bool_q15(&r->ec, p); |
107 | |
|
108 | | #if CONFIG_BITSTREAM_DEBUG |
109 | | { |
110 | | int i; |
111 | | int ref_bit, ref_nsymbs; |
112 | | aom_cdf_prob ref_cdf[16]; |
113 | | const int queue_r = bitstream_queue_get_read(); |
114 | | const int frame_idx = aom_bitstream_queue_get_frame_read(); |
115 | | bitstream_queue_pop(&ref_bit, ref_cdf, &ref_nsymbs); |
116 | | if (ref_nsymbs != 2) { |
117 | | fprintf(stderr, |
118 | | "\n *** [bit] nsymbs error, frame_idx_r %d nsymbs %d ref_nsymbs " |
119 | | "%d queue_r %d\n", |
120 | | frame_idx, 2, ref_nsymbs, queue_r); |
121 | | assert(0); |
122 | | } |
123 | | if ((ref_nsymbs != 2) || (ref_cdf[0] != (aom_cdf_prob)p) || |
124 | | (ref_cdf[1] != 32767)) { |
125 | | fprintf(stderr, |
126 | | "\n *** [bit] cdf error, frame_idx_r %d cdf {%d, %d} ref_cdf {%d", |
127 | | frame_idx, p, 32767, ref_cdf[0]); |
128 | | for (i = 1; i < ref_nsymbs; ++i) fprintf(stderr, ", %d", ref_cdf[i]); |
129 | | fprintf(stderr, "} queue_r %d\n", queue_r); |
130 | | assert(0); |
131 | | } |
132 | | if (bit != ref_bit) { |
133 | | fprintf(stderr, |
134 | | "\n *** [bit] symb error, frame_idx_r %d symb %d ref_symb %d " |
135 | | "queue_r %d\n", |
136 | | frame_idx, bit, ref_bit, queue_r); |
137 | | assert(0); |
138 | | } |
139 | | } |
140 | | #endif |
141 | |
|
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 bit; |
147 | 0 | } Unexecuted instantiation: av1_dx_iface.c:aom_read_ Unexecuted instantiation: decodeframe.c:aom_read_ Unexecuted instantiation: decodemv.c:aom_read_ Unexecuted instantiation: decoder.c:aom_read_ Unexecuted instantiation: decodetxb.c:aom_read_ Unexecuted instantiation: detokenize.c:aom_read_ Unexecuted instantiation: obu.c:aom_read_ Unexecuted instantiation: binary_codes_reader.c:aom_read_ Unexecuted instantiation: bitreader.c:aom_read_ |
148 | | |
149 | 0 | static INLINE int aom_read_bit_(aom_reader *r ACCT_STR_PARAM) { |
150 | 0 | int ret; |
151 | 0 | ret = aom_read(r, 128, NULL); // aom_prob_half |
152 | | #if CONFIG_ACCOUNTING |
153 | | if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME); |
154 | | #endif |
155 | 0 | return ret; |
156 | 0 | } Unexecuted instantiation: av1_dx_iface.c:aom_read_bit_ Unexecuted instantiation: decodeframe.c:aom_read_bit_ Unexecuted instantiation: decodemv.c:aom_read_bit_ Unexecuted instantiation: decoder.c:aom_read_bit_ Unexecuted instantiation: decodetxb.c:aom_read_bit_ Unexecuted instantiation: detokenize.c:aom_read_bit_ Unexecuted instantiation: obu.c:aom_read_bit_ Unexecuted instantiation: binary_codes_reader.c:aom_read_bit_ Unexecuted instantiation: bitreader.c:aom_read_bit_ |
157 | | |
158 | 0 | static INLINE int aom_read_literal_(aom_reader *r, int bits ACCT_STR_PARAM) { |
159 | 0 | int literal = 0, bit; |
160 | |
|
161 | 0 | for (bit = bits - 1; bit >= 0; bit--) literal |= aom_read_bit(r, NULL) << bit; |
162 | | #if CONFIG_ACCOUNTING |
163 | | if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME); |
164 | | #endif |
165 | 0 | return literal; |
166 | 0 | } Unexecuted instantiation: av1_dx_iface.c:aom_read_literal_ Unexecuted instantiation: decodeframe.c:aom_read_literal_ Unexecuted instantiation: decodemv.c:aom_read_literal_ Unexecuted instantiation: decoder.c:aom_read_literal_ Unexecuted instantiation: decodetxb.c:aom_read_literal_ Unexecuted instantiation: detokenize.c:aom_read_literal_ Unexecuted instantiation: obu.c:aom_read_literal_ Unexecuted instantiation: binary_codes_reader.c:aom_read_literal_ Unexecuted instantiation: bitreader.c:aom_read_literal_ |
167 | | |
168 | | static INLINE int aom_read_cdf_(aom_reader *r, const aom_cdf_prob *cdf, |
169 | 0 | int nsymbs ACCT_STR_PARAM) { |
170 | 0 | int symb; |
171 | 0 | assert(cdf != NULL); |
172 | 0 | symb = od_ec_decode_cdf_q15(&r->ec, cdf, nsymbs); |
173 | |
|
174 | | #if CONFIG_BITSTREAM_DEBUG |
175 | | { |
176 | | int i; |
177 | | int cdf_error = 0; |
178 | | int ref_symb, ref_nsymbs; |
179 | | aom_cdf_prob ref_cdf[16]; |
180 | | const int queue_r = bitstream_queue_get_read(); |
181 | | const int frame_idx = aom_bitstream_queue_get_frame_read(); |
182 | | bitstream_queue_pop(&ref_symb, ref_cdf, &ref_nsymbs); |
183 | | if (nsymbs != ref_nsymbs) { |
184 | | fprintf(stderr, |
185 | | "\n *** nsymbs error, frame_idx_r %d nsymbs %d ref_nsymbs %d " |
186 | | "queue_r %d\n", |
187 | | frame_idx, nsymbs, ref_nsymbs, queue_r); |
188 | | cdf_error = 0; |
189 | | assert(0); |
190 | | } else { |
191 | | for (i = 0; i < nsymbs; ++i) |
192 | | if (cdf[i] != ref_cdf[i]) cdf_error = 1; |
193 | | } |
194 | | if (cdf_error) { |
195 | | fprintf(stderr, "\n *** cdf error, frame_idx_r %d cdf {%d", frame_idx, |
196 | | cdf[0]); |
197 | | for (i = 1; i < nsymbs; ++i) fprintf(stderr, ", %d", cdf[i]); |
198 | | fprintf(stderr, "} ref_cdf {%d", ref_cdf[0]); |
199 | | for (i = 1; i < ref_nsymbs; ++i) fprintf(stderr, ", %d", ref_cdf[i]); |
200 | | fprintf(stderr, "} queue_r %d\n", queue_r); |
201 | | assert(0); |
202 | | } |
203 | | if (symb != ref_symb) { |
204 | | fprintf( |
205 | | stderr, |
206 | | "\n *** symb error, frame_idx_r %d symb %d ref_symb %d queue_r %d\n", |
207 | | frame_idx, symb, ref_symb, queue_r); |
208 | | assert(0); |
209 | | } |
210 | | } |
211 | | #endif |
212 | |
|
213 | | #if CONFIG_ACCOUNTING |
214 | | if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME); |
215 | | aom_update_symb_counts(r, (nsymbs == 2)); |
216 | | #endif |
217 | 0 | return symb; |
218 | 0 | } Unexecuted instantiation: av1_dx_iface.c:aom_read_cdf_ Unexecuted instantiation: decodeframe.c:aom_read_cdf_ Unexecuted instantiation: decodemv.c:aom_read_cdf_ Unexecuted instantiation: decoder.c:aom_read_cdf_ Unexecuted instantiation: decodetxb.c:aom_read_cdf_ Unexecuted instantiation: detokenize.c:aom_read_cdf_ Unexecuted instantiation: obu.c:aom_read_cdf_ Unexecuted instantiation: binary_codes_reader.c:aom_read_cdf_ Unexecuted instantiation: bitreader.c:aom_read_cdf_ |
219 | | |
220 | | static INLINE int aom_read_symbol_(aom_reader *r, aom_cdf_prob *cdf, |
221 | 0 | int nsymbs ACCT_STR_PARAM) { |
222 | 0 | int ret; |
223 | 0 | ret = aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME); |
224 | 0 | if (r->allow_update_cdf) update_cdf(cdf, ret, nsymbs); |
225 | 0 | return ret; |
226 | 0 | } Unexecuted instantiation: av1_dx_iface.c:aom_read_symbol_ Unexecuted instantiation: decodeframe.c:aom_read_symbol_ Unexecuted instantiation: decodemv.c:aom_read_symbol_ Unexecuted instantiation: decoder.c:aom_read_symbol_ Unexecuted instantiation: decodetxb.c:aom_read_symbol_ Unexecuted instantiation: detokenize.c:aom_read_symbol_ Unexecuted instantiation: obu.c:aom_read_symbol_ Unexecuted instantiation: binary_codes_reader.c:aom_read_symbol_ Unexecuted instantiation: bitreader.c:aom_read_symbol_ |
227 | | |
228 | | #ifdef __cplusplus |
229 | | } // extern "C" |
230 | | #endif |
231 | | |
232 | | #endif // AOM_AOM_DSP_BITREADER_H_ |