/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_ |