• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020, 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_RC_UTILS_H_
13 #define AOM_AV1_ENCODER_RC_UTILS_H_
14 
15 #include "av1/encoder/encoder.h"
16 #include "aom_dsp/psnr.h"
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
check_reset_rc_flag(AV1_COMP * cpi)22 static AOM_INLINE void check_reset_rc_flag(AV1_COMP *cpi) {
23   RATE_CONTROL *rc = &cpi->rc;
24   PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
25   if (cpi->common.current_frame.frame_number >
26       (unsigned int)cpi->svc.number_spatial_layers) {
27     if (cpi->ppi->use_svc) {
28       av1_svc_check_reset_layer_rc_flag(cpi);
29     } else {
30       if (rc->avg_frame_bandwidth > (3 * rc->prev_avg_frame_bandwidth >> 1) ||
31           rc->avg_frame_bandwidth < (rc->prev_avg_frame_bandwidth >> 1)) {
32         rc->rc_1_frame = 0;
33         rc->rc_2_frame = 0;
34         p_rc->bits_off_target = p_rc->optimal_buffer_level;
35         p_rc->buffer_level = p_rc->optimal_buffer_level;
36       }
37     }
38   }
39 }
40 
set_primary_rc_buffer_sizes(const AV1EncoderConfig * oxcf,AV1_PRIMARY * ppi)41 static AOM_INLINE void set_primary_rc_buffer_sizes(const AV1EncoderConfig *oxcf,
42                                                    AV1_PRIMARY *ppi) {
43   PRIMARY_RATE_CONTROL *p_rc = &ppi->p_rc;
44   const RateControlCfg *const rc_cfg = &oxcf->rc_cfg;
45 
46   const int64_t bandwidth = rc_cfg->target_bandwidth;
47   const int64_t starting = rc_cfg->starting_buffer_level_ms;
48   const int64_t optimal = rc_cfg->optimal_buffer_level_ms;
49   const int64_t maximum = rc_cfg->maximum_buffer_size_ms;
50 
51   p_rc->starting_buffer_level = starting * bandwidth / 1000;
52   p_rc->optimal_buffer_level =
53       (optimal == 0) ? bandwidth / 8 : optimal * bandwidth / 1000;
54   p_rc->maximum_buffer_size =
55       (maximum == 0) ? bandwidth / 8 : maximum * bandwidth / 1000;
56 
57   // Under a configuration change, where maximum_buffer_size may change,
58   // keep buffer level clipped to the maximum allowed buffer size.
59   p_rc->bits_off_target =
60       AOMMIN(p_rc->bits_off_target, p_rc->maximum_buffer_size);
61   p_rc->buffer_level = AOMMIN(p_rc->buffer_level, p_rc->maximum_buffer_size);
62 }
63 
config_target_level(AV1_COMP * const cpi,AV1_LEVEL target_level,int tier)64 static AOM_INLINE void config_target_level(AV1_COMP *const cpi,
65                                            AV1_LEVEL target_level, int tier) {
66   AV1EncoderConfig *const oxcf = &cpi->oxcf;
67   SequenceHeader *const seq_params = cpi->common.seq_params;
68   TileConfig *const tile_cfg = &oxcf->tile_cfg;
69   RateControlCfg *const rc_cfg = &oxcf->rc_cfg;
70 
71   // Adjust target bitrate to be no larger than 70% of level limit.
72   const BITSTREAM_PROFILE profile = seq_params->profile;
73   const double level_bitrate_limit =
74       av1_get_max_bitrate_for_level(target_level, tier, profile);
75   const int64_t max_bitrate = (int64_t)(level_bitrate_limit * 0.70);
76   rc_cfg->target_bandwidth = AOMMIN(rc_cfg->target_bandwidth, max_bitrate);
77   // Also need to update cpi->ppi->twopass.bits_left.
78   TWO_PASS *const twopass = &cpi->ppi->twopass;
79   FIRSTPASS_STATS *stats = twopass->stats_buf_ctx->total_stats;
80   if (stats != NULL)
81     cpi->ppi->twopass.bits_left =
82         (int64_t)(stats->duration * rc_cfg->target_bandwidth / 10000000.0);
83 
84   // Adjust max over-shoot percentage.
85   rc_cfg->over_shoot_pct = 0;
86 
87   // Adjust max quantizer.
88   rc_cfg->worst_allowed_q = 255;
89 
90   // Adjust number of tiles and tile columns to be under level limit.
91   int max_tiles, max_tile_cols;
92   av1_get_max_tiles_for_level(target_level, &max_tiles, &max_tile_cols);
93   while (tile_cfg->tile_columns > 0 &&
94          (1 << tile_cfg->tile_columns) > max_tile_cols) {
95     --tile_cfg->tile_columns;
96   }
97   const int tile_cols = (1 << tile_cfg->tile_columns);
98   while (tile_cfg->tile_rows > 0 &&
99          tile_cols * (1 << tile_cfg->tile_rows) > max_tiles) {
100     --tile_cfg->tile_rows;
101   }
102 
103   // Adjust min compression ratio.
104   const int still_picture = seq_params->still_picture;
105   const double min_cr =
106       av1_get_min_cr_for_level(target_level, tier, still_picture);
107   rc_cfg->min_cr = AOMMAX(rc_cfg->min_cr, (unsigned int)(min_cr * 100));
108 }
109 
110 #if !CONFIG_REALTIME_ONLY
111 
112 /*!\brief Function to test for conditions that indicate we should loop
113  * back and recode a frame.
114  *
115  * \ingroup rate_control
116  *
117  * \param[in]     cpi         Top-level encoder structure
118  * \param[in]     high_limit  Upper rate threshold
119  * \param[in]     low_limit   Lower rate threshold
120  * \param[in]     q           Current q index
121  * \param[in]     maxq        Maximum allowed q index
122  * \param[in]     minq        Minimum allowed q index
123  *
124  * \return        Indicates if a recode is required.
125  * \retval        1           Recode Required
126  * \retval        0           No Recode required
127  */
recode_loop_test(AV1_COMP * cpi,int high_limit,int low_limit,int q,int maxq,int minq)128 static AOM_INLINE int recode_loop_test(AV1_COMP *cpi, int high_limit,
129                                        int low_limit, int q, int maxq,
130                                        int minq) {
131   const RATE_CONTROL *const rc = &cpi->rc;
132   const AV1EncoderConfig *const oxcf = &cpi->oxcf;
133   const int frame_is_kfgfarf = frame_is_kf_gf_arf(cpi);
134   int force_recode = 0;
135 
136   if ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
137       (cpi->sf.hl_sf.recode_loop == ALLOW_RECODE) ||
138       (frame_is_kfgfarf &&
139        (cpi->sf.hl_sf.recode_loop == ALLOW_RECODE_KFARFGF))) {
140     // TODO(agrange) high_limit could be greater than the scale-down threshold.
141     if ((rc->projected_frame_size > high_limit && q < maxq) ||
142         (rc->projected_frame_size < low_limit && q > minq)) {
143       force_recode = 1;
144     } else if (cpi->oxcf.rc_cfg.mode == AOM_CQ) {
145       // Deal with frame undershoot and whether or not we are
146       // below the automatically set cq level.
147       if (q > oxcf->rc_cfg.cq_level &&
148           rc->projected_frame_size < ((rc->this_frame_target * 7) >> 3)) {
149         force_recode = 1;
150       }
151     }
152   }
153   return force_recode;
154 }
155 
av1_get_gfu_boost_projection_factor(double min_factor,double max_factor,int frame_count)156 static AOM_INLINE double av1_get_gfu_boost_projection_factor(double min_factor,
157                                                              double max_factor,
158                                                              int frame_count) {
159   double factor = sqrt((double)frame_count);
160   factor = AOMMIN(factor, max_factor);
161   factor = AOMMAX(factor, min_factor);
162   factor = (200.0 + 10.0 * factor);
163   return factor;
164 }
165 
get_gfu_boost_from_r0_lap(double min_factor,double max_factor,double r0,int frames_to_key)166 static AOM_INLINE int get_gfu_boost_from_r0_lap(double min_factor,
167                                                 double max_factor, double r0,
168                                                 int frames_to_key) {
169   double factor = av1_get_gfu_boost_projection_factor(min_factor, max_factor,
170                                                       frames_to_key);
171   const int boost = (int)rint(factor / r0);
172   return boost;
173 }
174 
av1_get_kf_boost_projection_factor(int frame_count)175 static AOM_INLINE double av1_get_kf_boost_projection_factor(int frame_count) {
176   double factor = sqrt((double)frame_count);
177   factor = AOMMIN(factor, 10.0);
178   factor = AOMMAX(factor, 4.0);
179   factor = (75.0 + 14.0 * factor);
180   return factor;
181 }
182 
get_regulated_q_overshoot(AV1_COMP * const cpi,int is_encode_stage,int q_low,int q_high,int top_index,int bottom_index)183 static AOM_INLINE int get_regulated_q_overshoot(AV1_COMP *const cpi,
184 #if CONFIG_FRAME_PARALLEL_ENCODE
185                                                 int is_encode_stage,
186 #endif
187                                                 int q_low, int q_high,
188                                                 int top_index,
189                                                 int bottom_index) {
190   const AV1_COMMON *const cm = &cpi->common;
191   const RATE_CONTROL *const rc = &cpi->rc;
192 
193   av1_rc_update_rate_correction_factors(cpi,
194 #if CONFIG_FRAME_PARALLEL_ENCODE
195                                         is_encode_stage,
196 #endif
197                                         cm->width, cm->height);
198 
199   int q_regulated =
200       av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
201                         AOMMAX(q_high, top_index), cm->width, cm->height);
202 
203   int retries = 0;
204   while (q_regulated < q_low && retries < 10) {
205     av1_rc_update_rate_correction_factors(cpi,
206 #if CONFIG_FRAME_PARALLEL_ENCODE
207                                           is_encode_stage,
208 #endif
209                                           cm->width, cm->height);
210     q_regulated =
211         av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
212                           AOMMAX(q_high, top_index), cm->width, cm->height);
213     retries++;
214   }
215   return q_regulated;
216 }
217 
get_regulated_q_undershoot(AV1_COMP * const cpi,int is_encode_stage,int q_high,int top_index,int bottom_index)218 static AOM_INLINE int get_regulated_q_undershoot(AV1_COMP *const cpi,
219 #if CONFIG_FRAME_PARALLEL_ENCODE
220                                                  int is_encode_stage,
221 #endif
222                                                  int q_high, int top_index,
223                                                  int bottom_index) {
224   const AV1_COMMON *const cm = &cpi->common;
225   const RATE_CONTROL *const rc = &cpi->rc;
226 
227   av1_rc_update_rate_correction_factors(cpi,
228 #if CONFIG_FRAME_PARALLEL_ENCODE
229                                         is_encode_stage,
230 #endif
231                                         cm->width, cm->height);
232   int q_regulated = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
233                                       top_index, cm->width, cm->height);
234 
235   int retries = 0;
236   while (q_regulated > q_high && retries < 10) {
237     av1_rc_update_rate_correction_factors(cpi,
238 #if CONFIG_FRAME_PARALLEL_ENCODE
239                                           is_encode_stage,
240 #endif
241                                           cm->width, cm->height);
242     q_regulated = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
243                                     top_index, cm->width, cm->height);
244     retries++;
245   }
246   return q_regulated;
247 }
248 
249 /*!\brief Called after encode_with_recode_loop() has just encoded a frame.
250  * This function works out whether we undershot or overshot our bitrate
251  *  target and adjusts q as appropriate. It also decides whether or not
252  *  we need to recode the frame to get closer to the target rate.
253  *
254  * \ingroup rate_control
255  *
256  * \param[in]     cpi             Top-level encoder structure
257  * \param[out]    loop            Should we go around the recode loop again
258  * \param[in,out] q               New q index value
259  * \param[in,out] q_low           Low q index limit for this loop itteration
260  * \param[in,out] q_high          High q index limit for this loop itteration
261  * \param[in]     top_index       Max permited new value for q index
262  * \param[in]     bottom_index    Min permited new value for q index
263  * \param[in,out] undershoot_seen Have we seen undershoot on this frame
264  * \param[in,out] overshoot_seen  Have we seen overshoot on this frame
265  * \param[in,out] low_cr_seen     Have we previously trriggered recode
266  *                                because the compression ration was less
267  *                                than a given minimum threshold.
268  * \param[in]     loop_count      Loop itterations so far.
269  *
270  */
recode_loop_update_q(AV1_COMP * const cpi,int * const loop,int * const q,int * const q_low,int * const q_high,const int top_index,const int bottom_index,int * const undershoot_seen,int * const overshoot_seen,int * const low_cr_seen,const int loop_count)271 static AOM_INLINE void recode_loop_update_q(
272     AV1_COMP *const cpi, int *const loop, int *const q, int *const q_low,
273     int *const q_high, const int top_index, const int bottom_index,
274     int *const undershoot_seen, int *const overshoot_seen,
275     int *const low_cr_seen, const int loop_count) {
276   AV1_COMMON *const cm = &cpi->common;
277   RATE_CONTROL *const rc = &cpi->rc;
278   PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
279   const RateControlCfg *const rc_cfg = &cpi->oxcf.rc_cfg;
280   *loop = 0;
281 
282   // Special case for overlay frame.
283   if (rc->is_src_frame_alt_ref &&
284       rc->projected_frame_size < rc->max_frame_bandwidth)
285     return;
286 
287   const int min_cr = rc_cfg->min_cr;
288   if (min_cr > 0) {
289     const double compression_ratio =
290         av1_get_compression_ratio(cm, rc->projected_frame_size >> 3);
291     const double target_cr = min_cr / 100.0;
292     if (compression_ratio < target_cr) {
293       *low_cr_seen = 1;
294       if (*q < rc->worst_quality) {
295         const double cr_ratio = target_cr / compression_ratio;
296         const int projected_q = AOMMAX(*q + 1, (int)(*q * cr_ratio * cr_ratio));
297         *q = AOMMIN(AOMMIN(projected_q, *q + 32), rc->worst_quality);
298         *q_low = AOMMAX(*q, *q_low);
299         *q_high = AOMMAX(*q, *q_high);
300         *loop = 1;
301       }
302     }
303     if (*low_cr_seen) return;
304   }
305 
306   if (rc_cfg->mode == AOM_Q) return;
307 
308   const int last_q = *q;
309   int frame_over_shoot_limit = 0, frame_under_shoot_limit = 0;
310   av1_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
311                                    &frame_under_shoot_limit,
312                                    &frame_over_shoot_limit);
313   if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1;
314 
315   if (cm->current_frame.frame_type == KEY_FRAME &&
316       p_rc->this_key_frame_forced &&
317       rc->projected_frame_size < rc->max_frame_bandwidth) {
318     int64_t kf_err;
319     const int64_t high_err_target = cpi->ambient_err;
320     const int64_t low_err_target = cpi->ambient_err >> 1;
321 
322 #if CONFIG_AV1_HIGHBITDEPTH
323     if (cm->seq_params->use_highbitdepth) {
324       kf_err = aom_highbd_get_y_sse(cpi->source, &cm->cur_frame->buf);
325     } else {
326       kf_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
327     }
328 #else
329     kf_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
330 #endif
331     // Prevent possible divide by zero error below for perfect KF
332     kf_err += !kf_err;
333 
334     // The key frame is not good enough or we can afford
335     // to make it better without undue risk of popping.
336     if ((kf_err > high_err_target &&
337          rc->projected_frame_size <= frame_over_shoot_limit) ||
338         (kf_err > low_err_target &&
339          rc->projected_frame_size <= frame_under_shoot_limit)) {
340       // Lower q_high
341       *q_high = AOMMAX(*q - 1, *q_low);
342 
343       // Adjust Q
344       *q = (int)((*q * high_err_target) / kf_err);
345       *q = AOMMIN(*q, (*q_high + *q_low) >> 1);
346     } else if (kf_err < low_err_target &&
347                rc->projected_frame_size >= frame_under_shoot_limit) {
348       // The key frame is much better than the previous frame
349       // Raise q_low
350       *q_low = AOMMIN(*q + 1, *q_high);
351 
352       // Adjust Q
353       *q = (int)((*q * low_err_target) / kf_err);
354       *q = AOMMIN(*q, (*q_high + *q_low + 1) >> 1);
355     }
356 
357     // Clamp Q to upper and lower limits:
358     *q = clamp(*q, *q_low, *q_high);
359     *loop = (*q != last_q);
360     return;
361   }
362 
363   if (recode_loop_test(cpi, frame_over_shoot_limit, frame_under_shoot_limit, *q,
364                        AOMMAX(*q_high, top_index), bottom_index)) {
365     // Is the projected frame size out of range and are we allowed
366     // to attempt to recode.
367 
368     // Frame size out of permitted range:
369     // Update correction factor & compute new Q to try...
370     // Frame is too large
371     if (rc->projected_frame_size > rc->this_frame_target) {
372       // Special case if the projected size is > the max allowed.
373       if (*q == *q_high &&
374           rc->projected_frame_size >= rc->max_frame_bandwidth) {
375         const double q_val_high_current =
376             av1_convert_qindex_to_q(*q_high, cm->seq_params->bit_depth);
377         const double q_val_high_new =
378             q_val_high_current *
379             ((double)rc->projected_frame_size / rc->max_frame_bandwidth);
380         *q_high = av1_find_qindex(q_val_high_new, cm->seq_params->bit_depth,
381                                   rc->best_quality, rc->worst_quality);
382       }
383 
384       // Raise Qlow as to at least the current value
385       *q_low = AOMMIN(*q + 1, *q_high);
386 
387       if (*undershoot_seen || loop_count > 2 ||
388           (loop_count == 2 && !frame_is_intra_only(cm))) {
389         av1_rc_update_rate_correction_factors(cpi,
390 #if CONFIG_FRAME_PARALLEL_ENCODE
391                                               1,
392 #endif
393                                               cm->width, cm->height);
394 
395         *q = (*q_high + *q_low + 1) / 2;
396       } else if (loop_count == 2 && frame_is_intra_only(cm)) {
397         const int q_mid = (*q_high + *q_low + 1) / 2;
398         const int q_regulated =
399             get_regulated_q_overshoot(cpi,
400 #if CONFIG_FRAME_PARALLEL_ENCODE
401                                       1,
402 #endif
403                                       *q_low, *q_high, top_index, bottom_index);
404         // Get 'q' in-between 'q_mid' and 'q_regulated' for a smooth
405         // transition between loop_count < 2 and loop_count > 2.
406         *q = (q_mid + q_regulated + 1) / 2;
407       } else {
408         *q =
409             get_regulated_q_overshoot(cpi,
410 #if CONFIG_FRAME_PARALLEL_ENCODE
411                                       1,
412 #endif
413                                       *q_low, *q_high, top_index, bottom_index);
414       }
415 
416       *overshoot_seen = 1;
417     } else {
418       // Frame is too small
419       *q_high = AOMMAX(*q - 1, *q_low);
420 
421       if (*overshoot_seen || loop_count > 2 ||
422           (loop_count == 2 && !frame_is_intra_only(cm))) {
423         av1_rc_update_rate_correction_factors(cpi,
424 #if CONFIG_FRAME_PARALLEL_ENCODE
425                                               1,
426 #endif
427                                               cm->width, cm->height);
428         *q = (*q_high + *q_low) / 2;
429       } else if (loop_count == 2 && frame_is_intra_only(cm)) {
430         const int q_mid = (*q_high + *q_low) / 2;
431         const int q_regulated =
432             get_regulated_q_undershoot(cpi,
433 #if CONFIG_FRAME_PARALLEL_ENCODE
434                                        1,
435 #endif
436                                        *q_high, top_index, bottom_index);
437         // Get 'q' in-between 'q_mid' and 'q_regulated' for a smooth
438         // transition between loop_count < 2 and loop_count > 2.
439         *q = (q_mid + q_regulated) / 2;
440 
441         // Special case reset for qlow for constrained quality.
442         // This should only trigger where there is very substantial
443         // undershoot on a frame and the auto cq level is above
444         // the user passsed in value.
445         if (rc_cfg->mode == AOM_CQ && q_regulated < *q_low) {
446           *q_low = *q;
447         }
448       } else {
449         *q = get_regulated_q_undershoot(cpi,
450 #if CONFIG_FRAME_PARALLEL_ENCODE
451                                         1,
452 #endif
453                                         *q_high, top_index, bottom_index);
454 
455         // Special case reset for qlow for constrained quality.
456         // This should only trigger where there is very substantial
457         // undershoot on a frame and the auto cq level is above
458         // the user passsed in value.
459         if (rc_cfg->mode == AOM_CQ && *q < *q_low) {
460           *q_low = *q;
461         }
462       }
463 
464       *undershoot_seen = 1;
465     }
466 
467     // Clamp Q to upper and lower limits:
468     *q = clamp(*q, *q_low, *q_high);
469   }
470 
471   *loop = (*q != last_q);
472 }
473 #endif
474 
475 #ifdef __cplusplus
476 }  // extern "C"
477 #endif
478 
479 #endif  // AOM_AV1_ENCODER_RC_UTILS_H_
480