Coverage Report

Created: 2026-10-17 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/avm/avm_dsp/bitwriter.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
3
 *
4
 * This source code is subject to the terms of the BSD 3-Clause Clear License
5
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
6
 * License was not distributed with this source code in the LICENSE file, you
7
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  If the
8
 * Alliance for Open Media Patent License 1.0 was not distributed with this
9
 * source code in the PATENTS file, you can obtain it at
10
 * aomedia.org/license/patent-license/.
11
 */
12
13
#ifndef AVM_AVM_DSP_BITWRITER_H_
14
#define AVM_AVM_DSP_BITWRITER_H_
15
16
#include <assert.h>
17
18
#include "config/avm_config.h"
19
20
#include "avm_dsp/entenc.h"
21
#include "avm_dsp/prob.h"
22
#include "avm_dsp_common.h"
23
#include "avm_dsp/recenter.h"
24
25
#if CONFIG_RD_DEBUG
26
#include "av2/common/blockd.h"
27
#include "av2/common/cost.h"
28
#endif
29
30
#if CONFIG_BITSTREAM_DEBUG
31
#include "avm_util/debug_util.h"
32
#endif  // CONFIG_BITSTREAM_DEBUG
33
34
#ifdef __cplusplus
35
extern "C" {
36
#endif
37
38
struct avm_writer {
39
  unsigned int pos;
40
  uint8_t *buffer;
41
  od_ec_enc ec;
42
  uint8_t allow_update_cdf;
43
  uint64_t frame_symbol_count;
44
};
45
46
typedef struct avm_writer avm_writer;
47
48
typedef struct TOKEN_STATS {
49
  int cost;
50
#if CONFIG_RD_DEBUG
51
  int txb_coeff_cost_map[TXB_COEFF_COST_MAP_SIZE][TXB_COEFF_COST_MAP_SIZE];
52
#endif
53
} TOKEN_STATS;
54
55
0
static INLINE void init_token_stats(TOKEN_STATS *token_stats) {
56
0
#if CONFIG_RD_DEBUG
57
0
  int r, c;
58
0
  for (r = 0; r < TXB_COEFF_COST_MAP_SIZE; ++r) {
59
0
    for (c = 0; c < TXB_COEFF_COST_MAP_SIZE; ++c) {
60
0
      token_stats->txb_coeff_cost_map[r][c] = 0;
61
0
    }
62
0
  }
63
0
#endif
64
0
  token_stats->cost = 0;
65
0
}
Unexecuted instantiation: decodetxb.c:init_token_stats
Unexecuted instantiation: level.c:init_token_stats
Unexecuted instantiation: hr_coding.c:init_token_stats
66
67
void avm_start_encode(avm_writer *w, uint8_t *buffer);
68
69
int avm_stop_encode(avm_writer *w);
70
71
#if CONFIG_BITSTREAM_DEBUG
72
// Push a literal (one or more equi-probably symbols) into
73
// the bitstream debug queue, in the same order it is
74
// encoded into the stream (msb to lsb).
75
static INLINE void bitstream_queue_push_literal(int data, int bits) {
76
  avm_cdf_prob cdf[2] = { 128, 32767 };
77
  for (int bit = bits - 1; bit >= 0; bit--) {
78
    bitstream_queue_push(1 & (data >> bit), cdf, 2);
79
  }
80
}
81
#endif  // CONFIG_BITSTREAM_DEBUG
82
83
0
static INLINE void avm_write(avm_writer *w, int bit, int probability) {
84
0
  int p = (0x7FFFFF - (probability << 15) + probability) >> 8;
85
0
#if CONFIG_BITSTREAM_DEBUG
86
0
  avm_cdf_prob cdf[2] = { (avm_cdf_prob)p, 32767 };
87
0
  bitstream_queue_push(bit, cdf, 2);
88
0
#endif  // CONFIG_BITSTREAM_DEBUG
89
0
90
0
  avm_od_ec_encode_bool_q15(&w->ec, bit, p);
91
0
}
Unexecuted instantiation: decodetxb.c:avm_write
Unexecuted instantiation: level.c:avm_write
Unexecuted instantiation: hr_coding.c:avm_write
92
93
0
static INLINE void avm_write_bit(avm_writer *w, int bit) {
94
0
#if CONFIG_BITSTREAM_DEBUG
95
0
  bitstream_queue_push_literal(bit, 1);
96
0
#endif  // CONFIG_BITSTREAM_DEBUG
97
0
  od_ec_encode_literal_bypass(&w->ec, bit, 1);
98
0
}
Unexecuted instantiation: decodetxb.c:avm_write_bit
Unexecuted instantiation: level.c:avm_write_bit
Unexecuted instantiation: hr_coding.c:avm_write_bit
99
100
0
static INLINE void avm_write_literal(avm_writer *w, int data, int bits) {
101
0
#if CONFIG_BITSTREAM_DEBUG
102
0
  bitstream_queue_push_literal(data, bits);
103
0
#endif  // CONFIG_BITSTREAM_DEBUG
104
0
  int n;
105
0
  w->frame_symbol_count += bits;
106
0
  while (bits > 0) {
107
0
    n = bits >= 8 ? 8 : bits;
108
0
    od_ec_encode_literal_bypass(&w->ec, (data >> (bits - n)), n);
109
0
    bits -= n;
110
0
    data &= ((1 << bits) - 1);
111
0
  }
112
0
}
Unexecuted instantiation: decodetxb.c:avm_write_literal
Unexecuted instantiation: level.c:avm_write_literal
Unexecuted instantiation: hr_coding.c:avm_write_literal
113
114
static INLINE void avm_write_cdf(avm_writer *w, int symb,
115
0
                                 const avm_cdf_prob *cdf, int nsymbs) {
116
0
#if CONFIG_BITSTREAM_DEBUG
117
0
  bitstream_queue_push(symb, cdf, nsymbs);
118
0
#endif  // CONFIG_BITSTREAM_DEBUG
119
0
120
0
  avm_od_ec_encode_cdf_q15(&w->ec, symb, cdf, nsymbs);
121
0
}
Unexecuted instantiation: decodetxb.c:avm_write_cdf
Unexecuted instantiation: level.c:avm_write_cdf
Unexecuted instantiation: hr_coding.c:avm_write_cdf
122
123
static INLINE void avm_write_symbol(avm_writer *w, int symb, avm_cdf_prob *cdf,
124
0
                                    int nsymbs) {
125
0
  w->frame_symbol_count++;
126
0
  avm_write_cdf(w, symb, cdf, nsymbs);
127
0
  if (w->allow_update_cdf) update_cdf(cdf, symb, nsymbs);
128
0
}
Unexecuted instantiation: decodetxb.c:avm_write_symbol
Unexecuted instantiation: level.c:avm_write_symbol
Unexecuted instantiation: hr_coding.c:avm_write_symbol
129
130
// Implements a code where a symbol with an alphabet size a power of 2 with
131
// nsymb_bits bits (with nsymb_bits >= 3), is coded by decomposing the symbol
132
// into 4 parts covering 1/8, 1/8, 1/4, 1/2 of the total number of symbols.
133
// The part is arithmetically coded using the provided cdf of size 4. The
134
// offset within each part is coded using fixed length binary codes with
135
// (nsymb_bits - 3), (nsymb_bits - 3), (nsymb_bits - 2) or (nsymb_bits - 1)
136
// bits, depending on the part.
137
//
138
0
static INLINE int symb_to_part(int symb, int nsymb_bits) {
139
0
  assert(nsymb_bits >= 3);
140
0
  int part_offs[4] = { 0, 1 << (nsymb_bits - 3), 1 << (nsymb_bits - 2),
141
0
                       1 << (nsymb_bits - 1) };
142
0
  if (symb < part_offs[1])
143
0
    return 0;
144
0
  else if (symb < part_offs[2])
145
0
    return 1;
146
0
  else if (symb < part_offs[3])
147
0
    return 2;
148
0
  else
149
0
    return 3;
150
0
}
Unexecuted instantiation: decodetxb.c:symb_to_part
Unexecuted instantiation: level.c:symb_to_part
Unexecuted instantiation: hr_coding.c:symb_to_part
151
152
static INLINE void avm_write_4part(avm_writer *w, int symb, avm_cdf_prob *cdf,
153
0
                                   int nsymb_bits) {
154
0
  assert(nsymb_bits >= 3);
155
0
  int part;
156
0
  int part_bits[4] = { (nsymb_bits - 3), (nsymb_bits - 3), (nsymb_bits - 2),
157
0
                       (nsymb_bits - 1) };
158
0
  int part_offs[4] = { 0, 1 << (nsymb_bits - 3), 1 << (nsymb_bits - 2),
159
0
                       1 << (nsymb_bits - 1) };
160
0
  if (symb < part_offs[1])
161
0
    part = 0;
162
0
  else if (symb < part_offs[2])
163
0
    part = 1;
164
0
  else if (symb < part_offs[3])
165
0
    part = 2;
166
0
  else
167
0
    part = 3;
168
0
  avm_write_symbol(w, part, cdf, 4);
169
0
  avm_write_literal(w, symb - part_offs[part], part_bits[part]);
170
0
}
Unexecuted instantiation: decodetxb.c:avm_write_4part
Unexecuted instantiation: level.c:avm_write_4part
Unexecuted instantiation: hr_coding.c:avm_write_4part
171
172
// Implements a nsymb_bits bit 4-part code that codes a symbol symb given a
173
// reference ref_symb after recentering symb around ref_symb.
174
static INLINE void avm_write_4part_wref(avm_writer *w, int ref_symb, int symb,
175
0
                                        avm_cdf_prob *cdf, int nsymb_bits) {
176
0
  const int recentered_symb =
177
0
      recenter_finite_nonneg(1 << nsymb_bits, ref_symb, symb);
178
0
  avm_write_4part(w, recentered_symb, cdf, nsymb_bits);
179
0
}
Unexecuted instantiation: decodetxb.c:avm_write_4part_wref
Unexecuted instantiation: level.c:avm_write_4part_wref
Unexecuted instantiation: hr_coding.c:avm_write_4part_wref
180
181
static INLINE int64_t avm_count_4part(int symb, const int *part_cost,
182
0
                                      int nsymb_bits, int scale_shift) {
183
0
  assert(nsymb_bits >= 3);
184
0
  int part_bits[4] = { (nsymb_bits - 3), (nsymb_bits - 3), (nsymb_bits - 2),
185
0
                       (nsymb_bits - 1) };
186
0
  int part_offs[4] = { 0, 1 << (nsymb_bits - 3), 1 << (nsymb_bits - 2),
187
0
                       1 << (nsymb_bits - 1) };
188
0
  if (symb < part_offs[1])
189
0
    return part_cost[0] + (part_bits[0] << scale_shift);
190
0
  else if (symb < part_offs[2])
191
0
    return part_cost[1] + (part_bits[1] << scale_shift);
192
0
  else if (symb < part_offs[3])
193
0
    return part_cost[2] + (part_bits[2] << scale_shift);
194
0
  else
195
0
    return part_cost[3] + (part_bits[3] << scale_shift);
196
0
}
Unexecuted instantiation: decodetxb.c:avm_count_4part
Unexecuted instantiation: level.c:avm_count_4part
Unexecuted instantiation: hr_coding.c:avm_count_4part
197
198
static INLINE int64_t avm_count_4part_wref(int ref_symb, int symb,
199
                                           const int *part_cost, int nsymb_bits,
200
0
                                           int scale_shift) {
201
0
  const int recentered_symb =
202
0
      recenter_finite_nonneg(1 << nsymb_bits, ref_symb, symb);
203
0
  return avm_count_4part(recentered_symb, part_cost, nsymb_bits, scale_shift);
204
0
}
Unexecuted instantiation: decodetxb.c:avm_count_4part_wref
Unexecuted instantiation: level.c:avm_count_4part_wref
Unexecuted instantiation: hr_coding.c:avm_count_4part_wref
205
206
#ifdef __cplusplus
207
}  // extern "C"
208
#endif
209
210
#endif  // AVM_AVM_DSP_BITWRITER_H_