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_BITWRITER_H_
13 : #define AOM_DSP_BITWRITER_H_
14 :
15 : #include <assert.h>
16 : #include "./aom_config.h"
17 :
18 : #if CONFIG_ANS
19 : #include "aom_dsp/buf_ans.h"
20 : #else
21 : #include "aom_dsp/daalaboolwriter.h"
22 : #endif
23 : #include "aom_dsp/prob.h"
24 :
25 : #if CONFIG_RD_DEBUG
26 : #include "av1/common/blockd.h"
27 : #include "av1/encoder/cost.h"
28 : #endif
29 :
30 : #ifdef __cplusplus
31 : extern "C" {
32 : #endif
33 :
34 : #if CONFIG_ANS
35 : typedef struct BufAnsCoder aom_writer;
36 : #else
37 : typedef struct daala_writer aom_writer;
38 : #endif
39 :
40 : typedef struct TOKEN_STATS {
41 : int cost;
42 : #if CONFIG_VAR_TX
43 : #if CONFIG_RD_DEBUG
44 : int txb_coeff_cost_map[TXB_COEFF_COST_MAP_SIZE][TXB_COEFF_COST_MAP_SIZE];
45 : #endif
46 : #endif
47 : } TOKEN_STATS;
48 :
49 0 : static INLINE void init_token_stats(TOKEN_STATS *token_stats) {
50 : #if CONFIG_VAR_TX
51 : #if CONFIG_RD_DEBUG
52 : int r, c;
53 : for (r = 0; r < TXB_COEFF_COST_MAP_SIZE; ++r) {
54 : for (c = 0; c < TXB_COEFF_COST_MAP_SIZE; ++c) {
55 : token_stats->txb_coeff_cost_map[r][c] = 0;
56 : }
57 : }
58 : #endif
59 : #endif
60 0 : token_stats->cost = 0;
61 0 : }
62 :
63 0 : static INLINE void aom_start_encode(aom_writer *bc, uint8_t *buffer) {
64 : #if CONFIG_ANS
65 : (void)bc;
66 : (void)buffer;
67 : assert(0 && "buf_ans requires a more complicated startup procedure");
68 : #else
69 0 : aom_daala_start_encode(bc, buffer);
70 : #endif
71 0 : }
72 :
73 0 : static INLINE void aom_stop_encode(aom_writer *bc) {
74 : #if CONFIG_ANS
75 : (void)bc;
76 : assert(0 && "buf_ans requires a more complicated shutdown procedure");
77 : #else
78 0 : aom_daala_stop_encode(bc);
79 : #endif
80 0 : }
81 :
82 0 : static INLINE void aom_write(aom_writer *br, int bit, int probability) {
83 : #if CONFIG_ANS
84 : buf_rabs_write(br, bit, probability);
85 : #else
86 0 : aom_daala_write(br, bit, probability);
87 : #endif
88 0 : }
89 :
90 0 : static INLINE void aom_write_record(aom_writer *br, int bit, int probability,
91 : TOKEN_STATS *token_stats) {
92 0 : aom_write(br, bit, probability);
93 : #if CONFIG_RD_DEBUG
94 : token_stats->cost += av1_cost_bit(probability, bit);
95 : #else
96 : (void)token_stats;
97 : #endif
98 0 : }
99 :
100 0 : static INLINE void aom_write_bit(aom_writer *w, int bit) {
101 : #if CONFIG_ANS
102 : buf_rabs_write_bit(w, bit);
103 : #elif CONFIG_RAWBITS
104 : // Note this uses raw bits and is not the same as aom_daala_write(r, 128);
105 : aom_daala_write_bit(w, bit);
106 : #else
107 0 : aom_write(w, bit, 128); // aom_prob_half
108 : #endif
109 0 : }
110 :
111 0 : static INLINE void aom_write_bit_record(aom_writer *w, int bit,
112 : TOKEN_STATS *token_stats) {
113 0 : aom_write_bit(w, bit);
114 : #if CONFIG_RD_DEBUG
115 : token_stats->cost += av1_cost_bit(128, bit); // aom_prob_half
116 : #else
117 : (void)token_stats;
118 : #endif
119 0 : }
120 :
121 0 : static INLINE void aom_write_literal(aom_writer *w, int data, int bits) {
122 : int bit;
123 :
124 0 : for (bit = bits - 1; bit >= 0; bit--) aom_write_bit(w, 1 & (data >> bit));
125 0 : }
126 :
127 0 : static INLINE void aom_write_cdf(aom_writer *w, int symb,
128 : const aom_cdf_prob *cdf, int nsymbs) {
129 : #if CONFIG_ANS
130 : (void)nsymbs;
131 : assert(cdf);
132 : const aom_cdf_prob cum_prob = symb > 0 ? cdf[symb - 1] : 0;
133 : const aom_cdf_prob prob = cdf[symb] - cum_prob;
134 : buf_rans_write(w, cum_prob, prob);
135 : #else
136 0 : daala_write_symbol(w, symb, cdf, nsymbs);
137 : #endif
138 0 : }
139 :
140 0 : static INLINE void aom_write_symbol(aom_writer *w, int symb, aom_cdf_prob *cdf,
141 : int nsymbs) {
142 0 : aom_write_cdf(w, symb, cdf, nsymbs);
143 : #if CONFIG_EC_ADAPT
144 0 : update_cdf(cdf, symb, nsymbs);
145 : #endif
146 0 : }
147 :
148 0 : static INLINE void aom_write_tree_as_cdf(aom_writer *w,
149 : const aom_tree_index *tree,
150 : const aom_prob *probs, int bits,
151 : int len, aom_tree_index i) {
152 : aom_tree_index root;
153 0 : root = i;
154 : do {
155 : aom_cdf_prob cdf[16];
156 : aom_tree_index index[16];
157 : int path[16];
158 : int dist[16];
159 : int nsymbs;
160 : int symb;
161 : int j;
162 : /* Compute the CDF of the binary tree using the given probabilities. */
163 0 : nsymbs = tree_to_cdf(tree, probs, root, cdf, index, path, dist);
164 : /* Find the symbol to code. */
165 0 : symb = -1;
166 0 : for (j = 0; j < nsymbs; j++) {
167 : /* If this symbol codes a leaf node, */
168 0 : if (index[j] <= 0) {
169 0 : if (len == dist[j] && path[j] == bits) {
170 0 : symb = j;
171 0 : break;
172 : }
173 : } else {
174 0 : if (len > dist[j] && path[j] == bits >> (len - dist[j])) {
175 0 : symb = j;
176 0 : break;
177 : }
178 : }
179 : }
180 0 : OD_ASSERT(symb != -1);
181 0 : aom_write_cdf(w, symb, cdf, nsymbs);
182 0 : bits &= (1 << (len - dist[symb])) - 1;
183 0 : len -= dist[symb];
184 0 : } while (len);
185 0 : }
186 :
187 0 : static INLINE void aom_write_tree(aom_writer *w, const aom_tree_index *tree,
188 : const aom_prob *probs, int bits, int len,
189 : aom_tree_index i) {
190 0 : aom_write_tree_as_cdf(w, tree, probs, bits, len, i);
191 0 : }
192 :
193 : static INLINE void aom_write_tree_record(aom_writer *w,
194 : const aom_tree_index *tree,
195 : const aom_prob *probs, int bits,
196 : int len, aom_tree_index i,
197 : TOKEN_STATS *token_stats) {
198 : (void)token_stats;
199 : aom_write_tree_as_cdf(w, tree, probs, bits, len, i);
200 : }
201 :
202 : #ifdef __cplusplus
203 : } // extern "C"
204 : #endif
205 :
206 : #endif // AOM_DSP_BITWRITER_H_
|