Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 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. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 10 | */ |
| 11 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 12 | #ifndef AOM_DSP_BITWRITER_H_ |
| 13 | #define AOM_DSP_BITWRITER_H_ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 14 | |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 15 | #include <assert.h> |
| 16 | #include "./aom_config.h" |
Nathan E. Egge | baaaa16 | 2016-10-24 09:50:52 -0400 | [diff] [blame] | 17 | #if CONFIG_EC_ADAPT && !CONFIG_EC_MULTISYMBOL |
| 18 | #error "CONFIG_EC_ADAPT is enabled without enabling CONFIG_EC_MULTISYMBOL" |
| 19 | #endif |
| 20 | |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 21 | #if CONFIG_ANS |
| 22 | #include "aom_dsp/buf_ans.h" |
| 23 | #elif CONFIG_DAALA_EC |
| 24 | #include "aom_dsp/daalaboolwriter.h" |
| 25 | #else |
Alex Converse | eb00cb2 | 2016-06-06 15:12:06 -0700 | [diff] [blame] | 26 | #include "aom_dsp/dkboolwriter.h" |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 27 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 28 | #include "aom_dsp/prob.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 29 | |
Angie Chiang | d402282 | 2016-11-02 18:30:25 -0700 | [diff] [blame] | 30 | #if CONFIG_RD_DEBUG |
Angie Chiang | d02001d | 2016-11-06 15:31:49 -0800 | [diff] [blame] | 31 | #include "av1/common/blockd.h" |
Angie Chiang | d402282 | 2016-11-02 18:30:25 -0700 | [diff] [blame] | 32 | #include "av1/encoder/cost.h" |
| 33 | #endif |
| 34 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 35 | #ifdef __cplusplus |
| 36 | extern "C" { |
| 37 | #endif |
| 38 | |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 39 | #if CONFIG_ANS |
| 40 | typedef struct BufAnsCoder aom_writer; |
Nathan E. Egge | 8043cc4 | 2016-03-06 12:42:47 -0500 | [diff] [blame] | 41 | #elif CONFIG_DAALA_EC |
| 42 | typedef struct daala_writer aom_writer; |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 43 | #else |
Alex Converse | eb00cb2 | 2016-06-06 15:12:06 -0700 | [diff] [blame] | 44 | typedef struct aom_dk_writer aom_writer; |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 45 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 46 | |
Angie Chiang | d02001d | 2016-11-06 15:31:49 -0800 | [diff] [blame] | 47 | typedef struct TOKEN_STATS { |
| 48 | int cost; |
| 49 | #if CONFIG_VAR_TX |
| 50 | #if CONFIG_RD_DEBUG |
| 51 | int txb_coeff_cost_map[TXB_COEFF_COST_MAP_SIZE][TXB_COEFF_COST_MAP_SIZE]; |
| 52 | #endif |
| 53 | #endif |
| 54 | } TOKEN_STATS; |
| 55 | |
| 56 | static INLINE void init_token_stats(TOKEN_STATS *token_stats) { |
| 57 | #if CONFIG_VAR_TX |
| 58 | #if CONFIG_RD_DEBUG |
| 59 | int r, c; |
| 60 | for (r = 0; r < TXB_COEFF_COST_MAP_SIZE; ++r) { |
| 61 | for (c = 0; c < TXB_COEFF_COST_MAP_SIZE; ++c) { |
| 62 | token_stats->txb_coeff_cost_map[r][c] = 0; |
| 63 | } |
| 64 | } |
| 65 | #endif |
| 66 | #endif |
| 67 | token_stats->cost = 0; |
| 68 | } |
Angie Chiang | d402282 | 2016-11-02 18:30:25 -0700 | [diff] [blame] | 69 | |
Alex Converse | eb00cb2 | 2016-06-06 15:12:06 -0700 | [diff] [blame] | 70 | static INLINE void aom_start_encode(aom_writer *bc, uint8_t *buffer) { |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 71 | #if CONFIG_ANS |
| 72 | (void)bc; |
| 73 | (void)buffer; |
| 74 | assert(0 && "buf_ans requires a more complicated startup procedure"); |
Nathan E. Egge | 8043cc4 | 2016-03-06 12:42:47 -0500 | [diff] [blame] | 75 | #elif CONFIG_DAALA_EC |
| 76 | aom_daala_start_encode(bc, buffer); |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 77 | #else |
Alex Converse | eb00cb2 | 2016-06-06 15:12:06 -0700 | [diff] [blame] | 78 | aom_dk_start_encode(bc, buffer); |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 79 | #endif |
Alex Converse | eb00cb2 | 2016-06-06 15:12:06 -0700 | [diff] [blame] | 80 | } |
| 81 | |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 82 | static INLINE void aom_stop_encode(aom_writer *bc) { |
| 83 | #if CONFIG_ANS |
| 84 | (void)bc; |
| 85 | assert(0 && "buf_ans requires a more complicated shutdown procedure"); |
Nathan E. Egge | 8043cc4 | 2016-03-06 12:42:47 -0500 | [diff] [blame] | 86 | #elif CONFIG_DAALA_EC |
| 87 | aom_daala_stop_encode(bc); |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 88 | #else |
| 89 | aom_dk_stop_encode(bc); |
| 90 | #endif |
| 91 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 92 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 93 | static INLINE void aom_write(aom_writer *br, int bit, int probability) { |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 94 | #if CONFIG_ANS |
| 95 | buf_uabs_write(br, bit, probability); |
Nathan E. Egge | 8043cc4 | 2016-03-06 12:42:47 -0500 | [diff] [blame] | 96 | #elif CONFIG_DAALA_EC |
| 97 | aom_daala_write(br, bit, probability); |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 98 | #else |
Alex Converse | eb00cb2 | 2016-06-06 15:12:06 -0700 | [diff] [blame] | 99 | aom_dk_write(br, bit, probability); |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 100 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 101 | } |
| 102 | |
Angie Chiang | d402282 | 2016-11-02 18:30:25 -0700 | [diff] [blame] | 103 | static INLINE void aom_write_record(aom_writer *br, int bit, int probability, |
| 104 | TOKEN_STATS *token_stats) { |
| 105 | aom_write(br, bit, probability); |
| 106 | #if CONFIG_RD_DEBUG |
| 107 | token_stats->cost += av1_cost_bit(probability, bit); |
| 108 | #else |
| 109 | (void)token_stats; |
| 110 | #endif |
| 111 | } |
| 112 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 113 | static INLINE void aom_write_bit(aom_writer *w, int bit) { |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 114 | aom_write(w, bit, 128); // aom_prob_half |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 115 | } |
| 116 | |
Angie Chiang | d402282 | 2016-11-02 18:30:25 -0700 | [diff] [blame] | 117 | static INLINE void aom_write_bit_record(aom_writer *w, int bit, |
| 118 | TOKEN_STATS *token_stats) { |
| 119 | aom_write_record(w, bit, 128, token_stats); // aom_prob_half |
| 120 | } |
| 121 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 122 | static INLINE void aom_write_literal(aom_writer *w, int data, int bits) { |
Alex Converse | 080a2cc | 2016-09-20 16:39:01 -0700 | [diff] [blame] | 123 | int bit; |
| 124 | |
| 125 | for (bit = bits - 1; bit >= 0; bit--) aom_write_bit(w, 1 & (data >> bit)); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 126 | } |
| 127 | |
Nathan E. Egge | eeedc63 | 2016-06-19 12:02:33 -0400 | [diff] [blame] | 128 | static INLINE void aom_write_tree_bits(aom_writer *w, const aom_tree_index *tr, |
| 129 | const aom_prob *probs, int bits, int len, |
| 130 | aom_tree_index i) { |
| 131 | do { |
| 132 | const int bit = (bits >> --len) & 1; |
| 133 | aom_write(w, bit, probs[i >> 1]); |
| 134 | i = tr[i + bit]; |
| 135 | } while (len); |
| 136 | } |
| 137 | |
Angie Chiang | d402282 | 2016-11-02 18:30:25 -0700 | [diff] [blame] | 138 | static INLINE void aom_write_tree_bits_record(aom_writer *w, |
| 139 | const aom_tree_index *tr, |
| 140 | const aom_prob *probs, int bits, |
| 141 | int len, aom_tree_index i, |
| 142 | TOKEN_STATS *token_stats) { |
| 143 | do { |
| 144 | const int bit = (bits >> --len) & 1; |
| 145 | aom_write_record(w, bit, probs[i >> 1], token_stats); |
| 146 | i = tr[i + bit]; |
| 147 | } while (len); |
| 148 | } |
| 149 | |
Nathan E. Egge | eeedc63 | 2016-06-19 12:02:33 -0400 | [diff] [blame] | 150 | static INLINE void aom_write_tree(aom_writer *w, const aom_tree_index *tree, |
| 151 | const aom_prob *probs, int bits, int len, |
| 152 | aom_tree_index i) { |
Nathan E. Egge | 43acafd | 2016-03-06 13:41:53 -0500 | [diff] [blame] | 153 | #if CONFIG_DAALA_EC |
| 154 | daala_write_tree_bits(w, tree, probs, bits, len, i); |
| 155 | #else |
Nathan E. Egge | eeedc63 | 2016-06-19 12:02:33 -0400 | [diff] [blame] | 156 | aom_write_tree_bits(w, tree, probs, bits, len, i); |
Nathan E. Egge | 43acafd | 2016-03-06 13:41:53 -0500 | [diff] [blame] | 157 | #endif |
Nathan E. Egge | eeedc63 | 2016-06-19 12:02:33 -0400 | [diff] [blame] | 158 | } |
| 159 | |
Angie Chiang | d402282 | 2016-11-02 18:30:25 -0700 | [diff] [blame] | 160 | static INLINE void aom_write_tree_record(aom_writer *w, |
| 161 | const aom_tree_index *tree, |
| 162 | const aom_prob *probs, int bits, |
| 163 | int len, aom_tree_index i, |
| 164 | TOKEN_STATS *token_stats) { |
| 165 | #if CONFIG_DAALA_EC |
| 166 | (void)token_stats; |
| 167 | daala_write_tree_bits(w, tree, probs, bits, len, i); |
| 168 | #else |
| 169 | aom_write_tree_bits_record(w, tree, probs, bits, len, i, token_stats); |
| 170 | #endif |
| 171 | } |
| 172 | |
Alex Converse | 58c520a | 2016-10-20 14:21:06 -0700 | [diff] [blame] | 173 | #if CONFIG_EC_MULTISYMBOL |
Thomas | 9ac5508 | 2016-09-23 18:04:17 +0100 | [diff] [blame] | 174 | static INLINE void aom_write_symbol(aom_writer *w, int symb, aom_cdf_prob *cdf, |
| 175 | int nsymbs) { |
Alex Converse | 1e4e29f | 2016-11-08 14:12:14 -0800 | [diff] [blame] | 176 | #if CONFIG_ANS |
Alex Converse | a1ac972 | 2016-10-12 15:59:58 -0700 | [diff] [blame] | 177 | struct rans_sym s; |
| 178 | (void)nsymbs; |
| 179 | assert(cdf); |
Alex Converse | e9f70f8 | 2016-08-22 12:44:16 -0700 | [diff] [blame] | 180 | s.cum_prob = symb > 0 ? cdf[symb - 1] : 0; |
| 181 | s.prob = cdf[symb] - s.cum_prob; |
Alex Converse | a1ac972 | 2016-10-12 15:59:58 -0700 | [diff] [blame] | 182 | buf_rans_write(w, &s); |
Nathan E. Egge | 56eeaa5 | 2016-07-25 10:23:33 -0400 | [diff] [blame] | 183 | #elif CONFIG_DAALA_EC |
| 184 | daala_write_symbol(w, symb, cdf, nsymbs); |
Nathan E. Egge | 4446014 | 2016-06-20 13:44:22 -0400 | [diff] [blame] | 185 | #else |
Alex Converse | 58c520a | 2016-10-20 14:21:06 -0700 | [diff] [blame] | 186 | #error \ |
| 187 | "CONFIG_EC_MULTISYMBOL is selected without a valid backing entropy " \ |
| 188 | "coder. Enable daala_ec or ans for a valid configuration." |
Nathan E. Egge | 4446014 | 2016-06-20 13:44:22 -0400 | [diff] [blame] | 189 | #endif |
Thomas | 9ac5508 | 2016-09-23 18:04:17 +0100 | [diff] [blame] | 190 | |
Alex Converse | aca9feb | 2016-10-10 11:08:10 -0700 | [diff] [blame] | 191 | #if CONFIG_EC_ADAPT |
Thomas | 9ac5508 | 2016-09-23 18:04:17 +0100 | [diff] [blame] | 192 | update_cdf(cdf, symb, nsymbs); |
| 193 | #endif |
Nathan E. Egge | 4446014 | 2016-06-20 13:44:22 -0400 | [diff] [blame] | 194 | } |
Alex Converse | 58c520a | 2016-10-20 14:21:06 -0700 | [diff] [blame] | 195 | #endif // CONFIG_EC_MULTISYMBOL |
Nathan E. Egge | 4446014 | 2016-06-20 13:44:22 -0400 | [diff] [blame] | 196 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 197 | #ifdef __cplusplus |
| 198 | } // extern "C" |
| 199 | #endif |
| 200 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 201 | #endif // AOM_DSP_BITWRITER_H_ |