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