/src/aom/av1/encoder/aq_cyclicrefresh.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 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_AV1_ENCODER_AQ_CYCLICREFRESH_H_ |
13 | | #define AOM_AV1_ENCODER_AQ_CYCLICREFRESH_H_ |
14 | | |
15 | | #include "av1/common/blockd.h" |
16 | | #include "av1/encoder/block.h" |
17 | | #include "av1/encoder/tokenize.h" |
18 | | |
19 | | #ifdef __cplusplus |
20 | | extern "C" { |
21 | | #endif |
22 | | |
23 | | // The segment ids used in cyclic refresh: from base (no boost) to increasing |
24 | | // boost (higher delta-qp). |
25 | 0 | #define CR_SEGMENT_ID_BASE 0 |
26 | 0 | #define CR_SEGMENT_ID_BOOST1 1 |
27 | 0 | #define CR_SEGMENT_ID_BOOST2 2 |
28 | | |
29 | | // Maximum rate target ratio for setting segment delta-qp. |
30 | | #define CR_MAX_RATE_TARGET_RATIO 4.0 |
31 | | |
32 | | /*! |
33 | | * \brief The stucture of CYCLIC_REFRESH. |
34 | | * \ingroup cyclic_refresh |
35 | | */ |
36 | | struct CYCLIC_REFRESH { |
37 | | /*! |
38 | | * Percentage of blocks per frame that are targeted as candidates |
39 | | * for cyclic refresh. |
40 | | */ |
41 | | int percent_refresh; |
42 | | |
43 | | /*! |
44 | | * Active adjustment delta for cyclic refresh for rate control. |
45 | | */ |
46 | | int percent_refresh_adjustment; |
47 | | |
48 | | /*! |
49 | | * Maximum q-delta as percentage of base q. |
50 | | */ |
51 | | int max_qdelta_perc; |
52 | | /*! |
53 | | *Superblock starting index for cycling through the frame. |
54 | | */ |
55 | | int sb_index; |
56 | | /*! |
57 | | *Superblock index cyclic refresh index last frame |
58 | | */ |
59 | | int last_sb_index; |
60 | | /*! |
61 | | * Controls how long block will need to wait to be refreshed again, in |
62 | | * excess of the cycle time, i.e., in the case of all zero motion, block |
63 | | * will be refreshed every (100/percent_refresh + time_for_refresh) frames. |
64 | | */ |
65 | | int time_for_refresh; |
66 | | /*! |
67 | | * Target number of (4x4) blocks that are set for delta-q. |
68 | | */ |
69 | | int target_num_seg_blocks; |
70 | | /*! |
71 | | * Actual number of (4x4) blocks that were applied delta-q, |
72 | | * for segment 1. |
73 | | */ |
74 | | int actual_num_seg1_blocks; |
75 | | /*! |
76 | | * Actual number of (4x4) blocks that were applied delta-q, |
77 | | * for segment 2. |
78 | | */ |
79 | | int actual_num_seg2_blocks; |
80 | | /*! |
81 | | * RD mult. parameters for segment 1. |
82 | | */ |
83 | | int rdmult; |
84 | | /*! |
85 | | * Cyclic refresh map. |
86 | | */ |
87 | | int8_t *map; |
88 | | /*! |
89 | | * Threshold applied to the projected rate of the coding block, |
90 | | * when deciding whether block should be refreshed. |
91 | | */ |
92 | | int64_t thresh_rate_sb; |
93 | | /*! |
94 | | * Threshold applied to the projected distortion of the coding block, |
95 | | * when deciding whether block should be refreshed. |
96 | | */ |
97 | | int64_t thresh_dist_sb; |
98 | | /*! |
99 | | * Threshold applied to the motion vector (in units of 1/8 pel) of the |
100 | | * coding block, when deciding whether block should be refreshed. |
101 | | */ |
102 | | int16_t motion_thresh; |
103 | | /*! |
104 | | * Rate target ratio to set q delta. |
105 | | */ |
106 | | double rate_ratio_qdelta; |
107 | | |
108 | | /*! |
109 | | * Active adjustment of qdelta rate ratio for enhanced rate control |
110 | | */ |
111 | | double rate_ratio_qdelta_adjustment; |
112 | | |
113 | | /*! |
114 | | * Boost factor for rate target ratio, for segment CR_SEGMENT_ID_BOOST2. |
115 | | */ |
116 | | int rate_boost_fac; |
117 | | |
118 | | /*!\cond */ |
119 | | int qindex_delta[3]; |
120 | | int apply_cyclic_refresh; |
121 | | int skip_over4x4; |
122 | | int counter_encode_maxq_scene_change; |
123 | | int use_block_sad_scene_det; |
124 | | /*!\endcond */ |
125 | | }; |
126 | | |
127 | | struct AV1_COMP; |
128 | | |
129 | | typedef struct CYCLIC_REFRESH CYCLIC_REFRESH; |
130 | | |
131 | | CYCLIC_REFRESH *av1_cyclic_refresh_alloc(int mi_rows, int mi_cols); |
132 | | |
133 | | void av1_cyclic_refresh_free(CYCLIC_REFRESH *cr); |
134 | | |
135 | | /*!\brief Estimate the bits, incorporating the delta-q from the segments. |
136 | | * |
137 | | * For the just encoded frame, estimate the bits, incorporating the delta-q |
138 | | * from non-base segment(s). Note this function is called in the postencode |
139 | | * (called from rc_update_rate_correction_factors()). |
140 | | * |
141 | | * \ingroup cyclic_refresh |
142 | | * \callgraph |
143 | | * \callergraph |
144 | | * |
145 | | * \param[in] cpi Top level encoder structure |
146 | | * \param[in] correction_factor rate correction factor |
147 | | * |
148 | | * \return Return the estimated bits at given q. |
149 | | */ |
150 | | int av1_cyclic_refresh_estimate_bits_at_q(const struct AV1_COMP *cpi, |
151 | | double correction_factor); |
152 | | |
153 | | /*!\brief Estimate the bits per mb, for given q = i and delta-q. |
154 | | * |
155 | | * Prior to encoding the frame, estimate the bits per mb, for a given q = i and |
156 | | * a corresponding delta-q (for segment 1). This function is called in the |
157 | | * rc_regulate_q() to set the base qp index. Note: the segment map is set to |
158 | | * either 0/CR_SEGMENT_ID_BASE (no refresh) or to 1/CR_SEGMENT_ID_BOOST1 |
159 | | * (refresh) for each superblock, prior to encoding. |
160 | | * |
161 | | * \ingroup cyclic_refresh |
162 | | * \callgraph |
163 | | * \callergraph |
164 | | * |
165 | | * \param[in] cpi Top level encoder structure |
166 | | * \param[in] i q index |
167 | | * \param[in] correction_factor rate correction factor |
168 | | * |
169 | | * \return Return the estimated bits for q = i and delta-q (segment 1). |
170 | | */ |
171 | | int av1_cyclic_refresh_rc_bits_per_mb(const struct AV1_COMP *cpi, int i, |
172 | | double correction_factor); |
173 | | |
174 | | /*!\brief Update segment_id for blocks are skipped. |
175 | | * |
176 | | * After encoding a given prediction block, of size bsize at (mi_row, mi_col), |
177 | | * check if we should reset the segment_id based on skip_txfm, |
178 | | * and update the cyclic_refresh map and segmentation counters. |
179 | | * |
180 | | * \ingroup cyclic_refresh |
181 | | * \callgraph |
182 | | * \callergraph |
183 | | * |
184 | | * \param[in] cpi Top level encoder structure |
185 | | * \param[in] x Pointer to MACROBLOCK structure |
186 | | * \param[in] mi_row Row coordinate of the block in a step size of MI_SIZE |
187 | | * \param[in] mi_col Col coordinate of the block in a step size of MI_SIZE |
188 | | * \param[in] bsize Block size |
189 | | * \param[in] dry_run A code indicating whether it is part of the final |
190 | | * pass for reconstructing the superblock |
191 | | * |
192 | | * \remark Update the \c mbmi->segment_id, the \c cpi->cyclic_refresh and |
193 | | * the \c cm->cpi->enc_seg.map. |
194 | | */ |
195 | | |
196 | | void av1_cyclic_reset_segment_skip(const struct AV1_COMP *cpi, |
197 | | MACROBLOCK *const x, int mi_row, int mi_col, |
198 | | BLOCK_SIZE bsize, RUN_TYPE dry_run); |
199 | | |
200 | | /*!\brief Update segment_id for block based on mode selected. |
201 | | * |
202 | | * Prior to coding a given prediction block, of size bsize at (mi_row, mi_col), |
203 | | * check if we should reset the segment_id (based on mode/motion/skip selected |
204 | | * for that block) and update the cyclic_refresh map and segmentation map. |
205 | | * |
206 | | * \ingroup cyclic_refresh |
207 | | * \callgraph |
208 | | * \callergraph |
209 | | * |
210 | | * \param[in] cpi Top level encoder structure |
211 | | * \param[in] x Pointer to MACROBLOCK structure |
212 | | * \param[in] mi_row Row coordinate of the block in a step size of MI_SIZE |
213 | | * \param[in] mi_col Col coordinate of the block in a step size of MI_SIZE |
214 | | * \param[in] bsize Block size |
215 | | * \param[in] rate Projected block rate from pickmode |
216 | | * \param[in] dist Projected block dist from pickmode |
217 | | * \param[in] skip Skip flag set from picmode |
218 | | * \param[in] dry_run A code indicating whether it is part of the final |
219 | | * pass for reconstructing the superblock |
220 | | * |
221 | | * \remark Update the \c mbmi->segment_id, the \c cpi->cyclic_refresh and |
222 | | * the \c cm->cpi->enc_seg.map. |
223 | | */ |
224 | | void av1_cyclic_refresh_update_segment(const struct AV1_COMP *cpi, |
225 | | MACROBLOCK *const x, int mi_row, |
226 | | int mi_col, BLOCK_SIZE bsize, |
227 | | int64_t rate, int64_t dist, int skip, |
228 | | RUN_TYPE dry_run); |
229 | | |
230 | | /*!\brief Initialize counters used for cyclic refresh. |
231 | | * |
232 | | * Initializes cyclic refresh counters actual_num_seg1_blocks and |
233 | | * actual_num_seg2_blocks. |
234 | | * |
235 | | * \ingroup cyclic_refresh |
236 | | * \callgraph |
237 | | * \callergraph |
238 | | * |
239 | | * \param[in] x Pointer to MACROBLOCK structure |
240 | | * |
241 | | * \remark Update the \c x->actual_num_seg1_blocks and the |
242 | | * \c x->actual_num_seg2_blocks. |
243 | | */ |
244 | | void av1_init_cyclic_refresh_counters(MACROBLOCK *const x); |
245 | | |
246 | | /*!\brief Accumulate cyclic refresh counters. |
247 | | * |
248 | | * Accumulates cyclic refresh counters actual_num_seg1_blocks and |
249 | | * actual_num_seg2_blocks from MACROBLOCK strcture to CYCLIC_REFRESH strcture. |
250 | | * |
251 | | * \ingroup cyclic_refresh |
252 | | * \callgraph |
253 | | * \callergraph |
254 | | * |
255 | | * \param[in] cyclic_refresh Pointer to CYCLIC_REFRESH structure |
256 | | * \param[in] x Pointer to MACROBLOCK structure |
257 | | * |
258 | | * \remark Update the \c cyclic_refresh->actual_num_seg1_blocks and the |
259 | | * \c cyclic_refresh->actual_num_seg2_blocks. |
260 | | */ |
261 | | void av1_accumulate_cyclic_refresh_counters( |
262 | | CYCLIC_REFRESH *const cyclic_refresh, const MACROBLOCK *const x); |
263 | | |
264 | | /*!\brief Set golden frame update interval nased on cyclic refresh. |
265 | | * |
266 | | * \ingroup cyclic_refresh |
267 | | * \callgraph |
268 | | * \callergraph |
269 | | * |
270 | | * \param[in] cpi Top level encoder structure |
271 | | * |
272 | | * \remark Returns the interval in \c cpi->rc.baseline_gf_interval. |
273 | | */ |
274 | | void av1_cyclic_refresh_set_golden_update(struct AV1_COMP *const cpi); |
275 | | |
276 | | /*!\brief Set the global/frame level parameters for cyclic refresh. |
277 | | * |
278 | | * First call to the cyclic refresh, before encoding the frame. |
279 | | * Sets the flag on whether cyclic refresh should be applied, sets |
280 | | * the amount/percent of refresh, and the amount of boost applied to |
281 | | * the two segments (set by rate_ratio_qdelta and rate_boost_fac). |
282 | | * |
283 | | * \ingroup cyclic_refresh |
284 | | * \callgraph |
285 | | * \callergraph |
286 | | * |
287 | | * \param[in] cpi Top level encoder structure |
288 | | * |
289 | | * \remark Updates the \c cpi->cyclic_refresh with the settings. |
290 | | */ |
291 | | void av1_cyclic_refresh_update_parameters(struct AV1_COMP *const cpi); |
292 | | |
293 | | /*!\brief Setup the cyclic background refresh. |
294 | | * |
295 | | * Set the delta q for the segment(s), and set the segmentation map. |
296 | | * |
297 | | * \ingroup cyclic_refresh |
298 | | * \callgraph |
299 | | * \callergraph |
300 | | * |
301 | | * \param[in] cpi Top level encoder structure |
302 | | * |
303 | | * \remark Updates the \c cpi->cyclic_refresh with the cyclic refresh |
304 | | * parameters and the \c cm->seg with the segmentation data. |
305 | | */ |
306 | | void av1_cyclic_refresh_setup(struct AV1_COMP *const cpi); |
307 | | |
308 | | int av1_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr); |
309 | | |
310 | | int av1_cyclic_refresh_disable_lf_cdef(struct AV1_COMP *const cpi); |
311 | | |
312 | 0 | static inline int cyclic_refresh_segment_id_boosted(int segment_id) { |
313 | 0 | return segment_id == CR_SEGMENT_ID_BOOST1 || |
314 | 0 | segment_id == CR_SEGMENT_ID_BOOST2; |
315 | 0 | } Unexecuted instantiation: av1_cx_iface.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: allintra_vis.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: av1_quantize.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: bitstream.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: context_tree.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: encodeframe.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: encodeframe_utils.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: encodemb.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: encodemv.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: encoder.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: encoder_utils.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: encodetxb.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: ethread.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: firstpass.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: global_motion_facade.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: level.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: lookahead.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: mcomp.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: mv_prec.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: palette.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: partition_search.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: partition_strategy.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: pass2_strategy.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: pickcdef.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: picklpf.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: pickrst.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: ratectrl.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: rd.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: rdopt.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: nonrd_pickmode.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: nonrd_opt.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: segmentation.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: speed_features.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: superres_scale.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: svc_layercontext.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: temporal_filter.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: tokenize.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: tpl_model.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: tx_search.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: txb_rdopt.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: intra_mode_search.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: var_based_part.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: av1_noise_estimate.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: aq_complexity.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: aq_cyclicrefresh.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: aq_variance.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: compound_type.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: encode_strategy.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: global_motion.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: gop_structure.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: interp_search.c:cyclic_refresh_segment_id_boosted Unexecuted instantiation: motion_search_facade.c:cyclic_refresh_segment_id_boosted |
316 | | |
317 | 0 | static inline int cyclic_refresh_segment_id(int segment_id) { |
318 | 0 | if (segment_id == CR_SEGMENT_ID_BOOST1) |
319 | 0 | return CR_SEGMENT_ID_BOOST1; |
320 | 0 | else if (segment_id == CR_SEGMENT_ID_BOOST2) |
321 | 0 | return CR_SEGMENT_ID_BOOST2; |
322 | 0 | else |
323 | 0 | return CR_SEGMENT_ID_BASE; |
324 | 0 | } Unexecuted instantiation: av1_cx_iface.c:cyclic_refresh_segment_id Unexecuted instantiation: allintra_vis.c:cyclic_refresh_segment_id Unexecuted instantiation: av1_quantize.c:cyclic_refresh_segment_id Unexecuted instantiation: bitstream.c:cyclic_refresh_segment_id Unexecuted instantiation: context_tree.c:cyclic_refresh_segment_id Unexecuted instantiation: encodeframe.c:cyclic_refresh_segment_id Unexecuted instantiation: encodeframe_utils.c:cyclic_refresh_segment_id Unexecuted instantiation: encodemb.c:cyclic_refresh_segment_id Unexecuted instantiation: encodemv.c:cyclic_refresh_segment_id Unexecuted instantiation: encoder.c:cyclic_refresh_segment_id Unexecuted instantiation: encoder_utils.c:cyclic_refresh_segment_id Unexecuted instantiation: encodetxb.c:cyclic_refresh_segment_id Unexecuted instantiation: ethread.c:cyclic_refresh_segment_id Unexecuted instantiation: firstpass.c:cyclic_refresh_segment_id Unexecuted instantiation: global_motion_facade.c:cyclic_refresh_segment_id Unexecuted instantiation: level.c:cyclic_refresh_segment_id Unexecuted instantiation: lookahead.c:cyclic_refresh_segment_id Unexecuted instantiation: mcomp.c:cyclic_refresh_segment_id Unexecuted instantiation: mv_prec.c:cyclic_refresh_segment_id Unexecuted instantiation: palette.c:cyclic_refresh_segment_id Unexecuted instantiation: partition_search.c:cyclic_refresh_segment_id Unexecuted instantiation: partition_strategy.c:cyclic_refresh_segment_id Unexecuted instantiation: pass2_strategy.c:cyclic_refresh_segment_id Unexecuted instantiation: pickcdef.c:cyclic_refresh_segment_id Unexecuted instantiation: picklpf.c:cyclic_refresh_segment_id Unexecuted instantiation: pickrst.c:cyclic_refresh_segment_id Unexecuted instantiation: ratectrl.c:cyclic_refresh_segment_id Unexecuted instantiation: rd.c:cyclic_refresh_segment_id Unexecuted instantiation: rdopt.c:cyclic_refresh_segment_id Unexecuted instantiation: nonrd_pickmode.c:cyclic_refresh_segment_id Unexecuted instantiation: nonrd_opt.c:cyclic_refresh_segment_id Unexecuted instantiation: segmentation.c:cyclic_refresh_segment_id Unexecuted instantiation: speed_features.c:cyclic_refresh_segment_id Unexecuted instantiation: superres_scale.c:cyclic_refresh_segment_id Unexecuted instantiation: svc_layercontext.c:cyclic_refresh_segment_id Unexecuted instantiation: temporal_filter.c:cyclic_refresh_segment_id Unexecuted instantiation: tokenize.c:cyclic_refresh_segment_id Unexecuted instantiation: tpl_model.c:cyclic_refresh_segment_id Unexecuted instantiation: tx_search.c:cyclic_refresh_segment_id Unexecuted instantiation: txb_rdopt.c:cyclic_refresh_segment_id Unexecuted instantiation: intra_mode_search.c:cyclic_refresh_segment_id Unexecuted instantiation: var_based_part.c:cyclic_refresh_segment_id Unexecuted instantiation: av1_noise_estimate.c:cyclic_refresh_segment_id Unexecuted instantiation: aq_complexity.c:cyclic_refresh_segment_id Unexecuted instantiation: aq_cyclicrefresh.c:cyclic_refresh_segment_id Unexecuted instantiation: aq_variance.c:cyclic_refresh_segment_id Unexecuted instantiation: compound_type.c:cyclic_refresh_segment_id Unexecuted instantiation: encode_strategy.c:cyclic_refresh_segment_id Unexecuted instantiation: global_motion.c:cyclic_refresh_segment_id Unexecuted instantiation: gop_structure.c:cyclic_refresh_segment_id Unexecuted instantiation: interp_search.c:cyclic_refresh_segment_id Unexecuted instantiation: motion_search_facade.c:cyclic_refresh_segment_id |
325 | | |
326 | | #ifdef __cplusplus |
327 | | } // extern "C" |
328 | | #endif |
329 | | |
330 | | #endif // AOM_AV1_ENCODER_AQ_CYCLICREFRESH_H_ |