1 /*
2 * Copyright (c) 2001-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_ENTENC_H_
13 #define AOM_AOM_DSP_ENTENC_H_
14 #include <stddef.h>
15 #include "aom_dsp/entcode.h"
16 #include "aom_util/endian_inl.h"
17
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21
22 typedef uint64_t od_ec_enc_window;
23
24 typedef struct od_ec_enc od_ec_enc;
25
26 #define OD_MEASURE_EC_OVERHEAD (0)
27
28 /*The entropy encoder context.*/
29 struct od_ec_enc {
30 /*Buffered output.
31 This contains only the raw bits until the final call to od_ec_enc_done(),
32 where all the arithmetic-coded data gets prepended to it.*/
33 unsigned char *buf;
34 /*The size of the buffer.*/
35 uint32_t storage;
36 /*The offset at which the next entropy-coded byte will be written.*/
37 uint32_t offs;
38 /*The low end of the current range.*/
39 od_ec_enc_window low;
40 /*The number of values in the current range.*/
41 uint16_t rng;
42 /*The number of bits of data in the current value.*/
43 int16_t cnt;
44 /*Nonzero if an error occurred.*/
45 int error;
46 #if OD_MEASURE_EC_OVERHEAD
47 double entropy;
48 int nb_symbols;
49 #endif
50 };
51
52 /*See entenc.c for further documentation.*/
53
54 void od_ec_enc_init(od_ec_enc *enc, uint32_t size) OD_ARG_NONNULL(1);
55 void od_ec_enc_reset(od_ec_enc *enc) OD_ARG_NONNULL(1);
56 void od_ec_enc_clear(od_ec_enc *enc) OD_ARG_NONNULL(1);
57
58 void od_ec_encode_bool_q15(od_ec_enc *enc, int val, unsigned f_q15)
59 OD_ARG_NONNULL(1);
60 void od_ec_encode_cdf_q15(od_ec_enc *enc, int s, const uint16_t *cdf, int nsyms)
61 OD_ARG_NONNULL(1) OD_ARG_NONNULL(3);
62
63 void od_ec_enc_bits(od_ec_enc *enc, uint32_t fl, unsigned ftb)
64 OD_ARG_NONNULL(1);
65
66 void od_ec_enc_patch_initial_bits(od_ec_enc *enc, unsigned val, int nbits)
67 OD_ARG_NONNULL(1);
68 OD_WARN_UNUSED_RESULT unsigned char *od_ec_enc_done(od_ec_enc *enc,
69 uint32_t *nbytes)
70 OD_ARG_NONNULL(1) OD_ARG_NONNULL(2);
71
72 OD_WARN_UNUSED_RESULT int od_ec_enc_tell(const od_ec_enc *enc)
73 OD_ARG_NONNULL(1);
74 OD_WARN_UNUSED_RESULT uint32_t od_ec_enc_tell_frac(const od_ec_enc *enc)
75 OD_ARG_NONNULL(1);
76
77 // buf is the frame bitbuffer, offs is where carry to be added
propagate_carry_bwd(unsigned char * buf,uint32_t offs)78 static inline void propagate_carry_bwd(unsigned char *buf, uint32_t offs) {
79 uint16_t sum, carry = 1;
80 do {
81 sum = (uint16_t)buf[offs] + 1;
82 buf[offs--] = (unsigned char)sum;
83 carry = sum >> 8;
84 } while (carry);
85 }
86
87 // Convert to big-endian byte order and write data to buffer adding the
88 // carry-bit
write_enc_data_to_out_buf(unsigned char * out,uint32_t offs,uint64_t output,uint64_t carry,uint32_t * enc_offs,uint8_t num_bytes_ready)89 static inline void write_enc_data_to_out_buf(unsigned char *out, uint32_t offs,
90 uint64_t output, uint64_t carry,
91 uint32_t *enc_offs,
92 uint8_t num_bytes_ready) {
93 const uint64_t reg = HToBE64(output << ((8 - num_bytes_ready) << 3));
94 memcpy(&out[offs], ®, 8);
95 // Propagate carry backwards if exists
96 if (carry) {
97 assert(offs > 0);
98 propagate_carry_bwd(out, offs - 1);
99 }
100 *enc_offs = offs + num_bytes_ready;
101 }
102
103 #ifdef __cplusplus
104 } // extern "C"
105 #endif
106
107 #endif // AOM_AOM_DSP_ENTENC_H_
108