Coverage Report

Created: 2026-10-17 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/avm/av2/encoder/aq_cyclicrefresh.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_AV2_ENCODER_AQ_CYCLICREFRESH_H_
14
#define AVM_AV2_ENCODER_AQ_CYCLICREFRESH_H_
15
16
#include "av2/common/blockd.h"
17
18
#ifdef __cplusplus
19
extern "C" {
20
#endif
21
22
// The segment ids used in cyclic refresh: from base (no boost) to increasing
23
// boost (higher delta-qp).
24
#define CR_SEGMENT_ID_BASE 0
25
#define CR_SEGMENT_ID_BOOST1 1
26
#define CR_SEGMENT_ID_BOOST2 2
27
28
// Maximum rate target ratio for setting segment delta-qp.
29
#define CR_MAX_RATE_TARGET_RATIO 4.0
30
31
/*!
32
 * \brief The stucture of CYCLIC_REFRESH.
33
 * \ingroup cyclic_refresh
34
 */
35
struct CYCLIC_REFRESH {
36
  /*!
37
   * Percentage of blocks per frame that are targeted as candidates
38
   * for cyclic refresh.
39
   */
40
  int percent_refresh;
41
  /*!
42
   * Maximum q-delta as percentage of base q.
43
   */
44
  int max_qdelta_perc;
45
  /*!
46
   *Superblock starting index for cycling through the frame.
47
   */
48
  int sb_index;
49
  /*!
50
   * Controls how long block will need to wait to be refreshed again, in
51
   * excess of the cycle time, i.e., in the case of all zero motion, block
52
   * will be refreshed every (100/percent_refresh + time_for_refresh) frames.
53
   */
54
  int time_for_refresh;
55
  /*!
56
   * Target number of (4x4) blocks that are set for delta-q.
57
   */
58
  int target_num_seg_blocks;
59
  /*!
60
   * Actual number of (4x4) blocks that were applied delta-q,
61
   * for segment 1.
62
   */
63
  int actual_num_seg1_blocks;
64
  /*!
65
   * Actual number of (4x4) blocks that were applied delta-q,
66
   * for segment 2.
67
   */
68
  int actual_num_seg2_blocks;
69
  /*!
70
   * RD mult. parameters for segment 1.
71
   */
72
  int rdmult;
73
  /*!
74
   * Cyclic refresh map.
75
   */
76
  int8_t *map;
77
  /*!
78
   * Map of the last q a block was coded at.
79
   */
80
  uint16_t *last_coded_q_map;
81
  /*!
82
   * Threshold applied to the projected rate of the coding block,
83
   * when deciding whether block should be refreshed.
84
   */
85
  int64_t thresh_rate_sb;
86
  /*!
87
   * Threshold applied to the projected distortion of the coding block,
88
   * when deciding whether block should be refreshed.
89
   */
90
  int64_t thresh_dist_sb;
91
  /*!
92
   * Threshold applied to the motion vector (in units of 1/8 pel) of the
93
   * coding block, when deciding whether block should be refreshed.
94
   */
95
  int16_t motion_thresh;
96
  /*!
97
   * Rate target ratio to set q delta.
98
   */
99
  double rate_ratio_qdelta;
100
  /*!
101
   * Boost factor for rate target ratio, for segment CR_SEGMENT_ID_BOOST2.
102
   */
103
  int rate_boost_fac;
104
105
  /*!\cond */
106
  double low_content_avg;
107
  int qindex_delta[3];
108
  double weight_segment;
109
  int apply_cyclic_refresh;
110
  int cnt_zeromv;
111
  double avg_frame_low_motion;
112
  /*!\endcond */
113
};
114
115
struct AV2_COMP;
116
117
typedef struct CYCLIC_REFRESH CYCLIC_REFRESH;
118
119
CYCLIC_REFRESH *av2_cyclic_refresh_alloc(int mi_rows, int mi_cols,
120
                                         avm_bit_depth_t bit_depth);
121
122
void av2_cyclic_refresh_free(CYCLIC_REFRESH *cr);
123
124
/*!\brief Estimate the bits, incorporating the delta-q from the segments.
125
 *
126
 * For the just encoded frame, estimate the bits, incorporating the delta-q
127
 * from non-base segment(s). Note this function is called in the postencode
128
 * (called from rc_update_rate_correction_factors()).
129
 *
130
 * \ingroup cyclic_refresh
131
 * \callgraph
132
 * \callergraph
133
 *
134
 * \param[in]       cpi               Top level encoder structure
135
 * \param[in]       correction_factor rate correction factor
136
 *
137
 * \return Return the estimated bits at given q.
138
 */
139
int av2_cyclic_refresh_estimate_bits_at_q(const struct AV2_COMP *cpi,
140
                                          double correction_factor);
141
142
/*!\brief Estimate the bits per mb, for given q = i and delta-q.
143
 *
144
 * Prior to encoding the frame, estimate the bits per mb, for a given q = i and
145
 * a corresponding delta-q (for segment 1). This function is called in the
146
 * rc_regulate_q() to set the base qp index. Note: the segment map is set to
147
 * either 0/CR_SEGMENT_ID_BASE (no refresh) or to 1/CR_SEGMENT_ID_BOOST1
148
 * (refresh) for each superblock, prior to encoding.
149
 *
150
 * \ingroup cyclic_refresh
151
 * \callgraph
152
 * \callergraph
153
 *
154
 * \param[in]       cpi               Top level encoder structure
155
 * \param[in]       i                 q index
156
 * \param[in]       correction_factor rate correction factor
157
 *
158
 * \return Return the estimated bits for q = i and delta-q (segment 1).
159
 */
160
int av2_cyclic_refresh_rc_bits_per_mb(const struct AV2_COMP *cpi, int i,
161
                                      double correction_factor);
162
163
/*!\brief Update segment_id for block based on mode selected.
164
 *
165
 * Prior to coding a given prediction block, of size bsize at (mi_row, mi_col),
166
 * check if we should reset the segment_id (based on mode/motion/skip selected
167
 * for that block) and update the cyclic_refresh map and segmentation map.
168
 *
169
 * \ingroup cyclic_refresh
170
 * \callgraph
171
 * \callergraph
172
 *
173
 * \param[in]   cpi       Top level encoder structure
174
 * \param[in]   mbmi      MB_MODE_INFO pointer for mi block
175
 * \param[in]   mi_row    Row coordinate of the block in a step size of MI_SIZE
176
 * \param[in]   mi_col    Col coordinate of the block in a step size of MI_SIZE
177
 * \param[in]   bsize     Block size
178
 * \param[in]   rate      Projected block rate from pickmode
179
 * \param[in]   dist      Projected block dist from pickmode
180
 * \param[in]   skip      Skip flag set from pickmode
181
 * \param[in]   lossless  Pointer to the lossless flags of all segments
182
 *
183
 * Updates the \c mbmi->segment_id, the \c cpi->cyclic_refresh and
184
 * the \c cm->cpi->enc_seg.map.
185
 */
186
void av2_cyclic_refresh_update_segment(const struct AV2_COMP *cpi,
187
                                       MB_MODE_INFO *const mbmi, int mi_row,
188
                                       int mi_col, BLOCK_SIZE bsize,
189
                                       int64_t rate, int64_t dist, int skip,
190
                                       const uint8_t *lossless);
191
192
/*!\brief Update stats after encoding frame.
193
 *
194
 * Update the number of block encoded with segment 1 and 2,
195
 * and update the number of blocks encoded with small/zero motion.
196
 *
197
 * \ingroup cyclic_refresh
198
 * \callgraph
199
 * \callergraph
200
 *
201
 * \param[in]   cpi       Top level encoder structure
202
 *
203
 * Updates the \c cpi->cyclic_refresh with the new stats.
204
 */
205
void av2_cyclic_refresh_postencode(struct AV2_COMP *const cpi);
206
207
/*!\brief Set golden frame update interval nased on cyclic refresh.
208
 *
209
 * \ingroup cyclic_refresh
210
 * \callgraph
211
 * \callergraph
212
 *
213
 * \param[in]   cpi       Top level encoder structure
214
 *
215
 * Populates the interval in \c cpi->rc.baseline_gf_interval.
216
 */
217
void av2_cyclic_refresh_set_golden_update(struct AV2_COMP *const cpi);
218
219
/*!\brief Set the global/frame level parameters for cyclic refresh.
220
 *
221
 * First call to the cyclic refresh, before encoding the frame.
222
 * Sets the flag on whether cyclic refresh should be applied, sets
223
 * the amount/percent of refresh, and the amount of boost applied to
224
 * the two segments (set by rate_ratio_qdelta and rate_boost_fac).
225
 *
226
 * \ingroup cyclic_refresh
227
 * \callgraph
228
 * \callergraph
229
 *
230
 * \param[in]       cpi          Top level encoder structure
231
 * \param[in]       frame_type   Frame type encoder parameter
232
 *
233
 * Updates the \c cpi->cyclic_refresh with the settings.
234
 */
235
void av2_cyclic_refresh_update_parameters(struct AV2_COMP *const cpi,
236
                                          FRAME_TYPE frame_type);
237
238
/*!\brief Setup the cyclic background refresh.
239
 *
240
 * Set the delta q for the segment(s), and set the segmentation map.
241
 *
242
 * \ingroup cyclic_refresh
243
 * \callgraph
244
 * \callergraph
245
 *
246
 * \param[in]       cpi          Top level encoder structure
247
 *
248
 * Updates the \c cpi->cyclic_refresh with the cyclic refresh
249
 * parameters and the \c cm->seg with the segmentation data.
250
 */
251
void av2_cyclic_refresh_setup(struct AV2_COMP *const cpi);
252
253
int av2_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr);
254
255
void av2_cyclic_refresh_reset_resize(struct AV2_COMP *const cpi);
256
257
0
static INLINE int cyclic_refresh_segment_id_boosted(int segment_id) {
258
0
  return segment_id == CR_SEGMENT_ID_BOOST1 ||
259
0
         segment_id == CR_SEGMENT_ID_BOOST2;
260
0
}
261
262
0
static INLINE int cyclic_refresh_segment_id(int segment_id) {
263
0
  if (segment_id == CR_SEGMENT_ID_BOOST1)
264
0
    return CR_SEGMENT_ID_BOOST1;
265
0
  else if (segment_id == CR_SEGMENT_ID_BOOST2)
266
0
    return CR_SEGMENT_ID_BOOST2;
267
0
  else
268
0
    return CR_SEGMENT_ID_BASE;
269
0
}
270
271
#ifdef __cplusplus
272
}  // extern "C"
273
#endif
274
275
#endif  // AVM_AV2_ENCODER_AQ_CYCLICREFRESH_H_