tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rc_utils.h (18629B)


      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 
     22 static 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 
     41 static 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 
     64 static 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 */
    128 static inline int recode_loop_test(AV1_COMP *cpi, int high_limit, int low_limit,
    129                                   int q, int maxq, int minq) {
    130  const RATE_CONTROL *const rc = &cpi->rc;
    131  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
    132  const int frame_is_kfgfarf = frame_is_kf_gf_arf(cpi);
    133  int force_recode = 0;
    134 
    135  if ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
    136      (cpi->sf.hl_sf.recode_loop == ALLOW_RECODE) ||
    137      (frame_is_kfgfarf &&
    138       (cpi->sf.hl_sf.recode_loop == ALLOW_RECODE_KFARFGF))) {
    139    // TODO(agrange) high_limit could be greater than the scale-down threshold.
    140    if ((rc->projected_frame_size > high_limit && q < maxq) ||
    141        (rc->projected_frame_size < low_limit && q > minq)) {
    142      force_recode = 1;
    143    } else if (cpi->oxcf.rc_cfg.mode == AOM_CQ) {
    144      // Deal with frame undershoot and whether or not we are
    145      // below the automatically set cq level.
    146      if (q > oxcf->rc_cfg.cq_level &&
    147          rc->projected_frame_size <
    148              (((int64_t)rc->this_frame_target * 7) >> 3)) {
    149        force_recode = 1;
    150      }
    151    }
    152  }
    153  return force_recode;
    154 }
    155 
    156 static 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 
    166 static 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 
    175 static 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 
    183 static inline int get_regulated_q_overshoot(AV1_COMP *const cpi,
    184                                            int is_encode_stage, int q_low,
    185                                            int q_high, int top_index,
    186                                            int bottom_index) {
    187  const AV1_COMMON *const cm = &cpi->common;
    188  const RATE_CONTROL *const rc = &cpi->rc;
    189 
    190  av1_rc_update_rate_correction_factors(cpi, is_encode_stage, cm->width,
    191                                        cm->height);
    192 
    193  int q_regulated =
    194      av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
    195                        AOMMAX(q_high, top_index), cm->width, cm->height);
    196 
    197  int retries = 0;
    198  while (q_regulated < q_low && retries < 10) {
    199    av1_rc_update_rate_correction_factors(cpi, is_encode_stage, cm->width,
    200                                          cm->height);
    201    q_regulated =
    202        av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
    203                          AOMMAX(q_high, top_index), cm->width, cm->height);
    204    retries++;
    205  }
    206  return q_regulated;
    207 }
    208 
    209 static inline int get_regulated_q_undershoot(AV1_COMP *const cpi,
    210                                             int is_encode_stage, int q_high,
    211                                             int top_index, int bottom_index) {
    212  const AV1_COMMON *const cm = &cpi->common;
    213  const RATE_CONTROL *const rc = &cpi->rc;
    214 
    215  av1_rc_update_rate_correction_factors(cpi, is_encode_stage, cm->width,
    216                                        cm->height);
    217  int q_regulated = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
    218                                      top_index, cm->width, cm->height);
    219 
    220  int retries = 0;
    221  while (q_regulated > q_high && retries < 10) {
    222    av1_rc_update_rate_correction_factors(cpi, is_encode_stage, cm->width,
    223                                          cm->height);
    224    q_regulated = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
    225                                    top_index, cm->width, cm->height);
    226    retries++;
    227  }
    228  return q_regulated;
    229 }
    230 
    231 /*!\brief Called after encode_with_recode_loop() has just encoded a frame.
    232 * This function works out whether we undershot or overshot our bitrate
    233 *  target and adjusts q as appropriate. It also decides whether or not
    234 *  we need to recode the frame to get closer to the target rate.
    235 *
    236 * \ingroup rate_control
    237 *
    238 * \param[in]     cpi             Top-level encoder structure
    239 * \param[out]    loop            Should we go around the recode loop again
    240 * \param[in,out] q               New q index value
    241 * \param[in,out] q_low           Low q index limit for this loop itteration
    242 * \param[in,out] q_high          High q index limit for this loop itteration
    243 * \param[in]     top_index       Max permited new value for q index
    244 * \param[in]     bottom_index    Min permited new value for q index
    245 * \param[in,out] undershoot_seen Have we seen undershoot on this frame
    246 * \param[in,out] overshoot_seen  Have we seen overshoot on this frame
    247 * \param[in,out] low_cr_seen     Have we previously trriggered recode
    248 *                                because the compression ration was less
    249 *                                than a given minimum threshold.
    250 * \param[in]     loop_count      Loop itterations so far.
    251 *
    252 */
    253 static inline void recode_loop_update_q(
    254    AV1_COMP *const cpi, int *const loop, int *const q, int *const q_low,
    255    int *const q_high, const int top_index, const int bottom_index,
    256    int *const undershoot_seen, int *const overshoot_seen,
    257    int *const low_cr_seen, const int loop_count) {
    258  AV1_COMMON *const cm = &cpi->common;
    259  RATE_CONTROL *const rc = &cpi->rc;
    260  PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
    261  const RateControlCfg *const rc_cfg = &cpi->oxcf.rc_cfg;
    262  *loop = 0;
    263 
    264  // Special case for overlay frame.
    265  if (rc->is_src_frame_alt_ref &&
    266      rc->projected_frame_size < rc->max_frame_bandwidth)
    267    return;
    268 
    269  const int min_cr = rc_cfg->min_cr;
    270  if (min_cr > 0) {
    271    const double compression_ratio =
    272        av1_get_compression_ratio(cm, rc->projected_frame_size >> 3);
    273    const double target_cr = min_cr / 100.0;
    274    if (compression_ratio < target_cr) {
    275      *low_cr_seen = 1;
    276      if (*q < rc->worst_quality) {
    277        const double cr_ratio = target_cr / compression_ratio;
    278        const int projected_q = AOMMAX(*q + 1, (int)(*q * cr_ratio * cr_ratio));
    279        *q = AOMMIN(AOMMIN(projected_q, *q + 32), rc->worst_quality);
    280        *q_low = AOMMAX(*q, *q_low);
    281        *q_high = AOMMAX(*q, *q_high);
    282        *loop = 1;
    283      }
    284    }
    285    if (*low_cr_seen) return;
    286  }
    287 
    288  if (cpi->ppi->level_params.keep_level_stats &&
    289      !is_stat_generation_stage(cpi)) {
    290    // Initialize level info. at the beginning of each sequence.
    291    if (cm->current_frame.frame_type == KEY_FRAME &&
    292        cpi->ppi->gf_group.refbuf_state[cpi->gf_frame_index] == REFBUF_RESET) {
    293      av1_init_level_info(cpi);
    294    }
    295    const AV1LevelParams *const level_params = &cpi->ppi->level_params;
    296    // TODO(any): currently only checking operating point 0
    297    const AV1LevelInfo *const level_info = level_params->level_info[0];
    298    const DECODER_MODEL *const decoder_models = level_info->decoder_models;
    299    const AV1_LEVEL target_level = level_params->target_seq_level_idx[0];
    300 
    301    if (target_level < SEQ_LEVELS &&
    302        decoder_models[target_level].status == DECODER_MODEL_OK) {
    303      DECODER_MODEL_STATUS status = av1_decoder_model_try_smooth_buf(
    304          cpi, rc->projected_frame_size, &decoder_models[target_level]);
    305 
    306      if ((status == SMOOTHING_BUFFER_UNDERFLOW ||
    307           status == SMOOTHING_BUFFER_OVERFLOW) &&
    308          *q < rc->worst_quality) {
    309        *q = AOMMIN(*q + 10, rc->worst_quality);
    310        *q_low = AOMMAX(*q, *q_low);
    311        *q_high = AOMMAX(*q, *q_high);
    312        *loop = 1;
    313        return;
    314      }
    315    }
    316  }
    317 
    318  if (rc_cfg->mode == AOM_Q) return;
    319 
    320  const int last_q = *q;
    321  int frame_over_shoot_limit = 0, frame_under_shoot_limit = 0;
    322  av1_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
    323                                   &frame_under_shoot_limit,
    324                                   &frame_over_shoot_limit);
    325  if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1;
    326 
    327  if (cm->current_frame.frame_type == KEY_FRAME &&
    328      p_rc->this_key_frame_forced &&
    329      rc->projected_frame_size < rc->max_frame_bandwidth) {
    330    int64_t kf_err;
    331    const int64_t high_err_target = cpi->ambient_err;
    332    const int64_t low_err_target = cpi->ambient_err >> 1;
    333 
    334 #if CONFIG_AV1_HIGHBITDEPTH
    335    if (cm->seq_params->use_highbitdepth) {
    336      kf_err = aom_highbd_get_y_sse(cpi->source, &cm->cur_frame->buf);
    337    } else {
    338      kf_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
    339    }
    340 #else
    341    kf_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
    342 #endif
    343    // Prevent possible divide by zero error below for perfect KF
    344    kf_err += !kf_err;
    345 
    346    // The key frame is not good enough or we can afford
    347    // to make it better without undue risk of popping.
    348    if ((kf_err > high_err_target &&
    349         rc->projected_frame_size <= frame_over_shoot_limit) ||
    350        (kf_err > low_err_target &&
    351         rc->projected_frame_size <= frame_under_shoot_limit)) {
    352      // Lower q_high
    353      *q_high = AOMMAX(*q - 1, *q_low);
    354 
    355      // Adjust Q
    356      *q = (int)((*q * high_err_target) / kf_err);
    357      *q = AOMMIN(*q, (*q_high + *q_low) >> 1);
    358    } else if (kf_err < low_err_target &&
    359               rc->projected_frame_size >= frame_under_shoot_limit) {
    360      // The key frame is much better than the previous frame
    361      // Raise q_low
    362      *q_low = AOMMIN(*q + 1, *q_high);
    363 
    364      // Adjust Q
    365      *q = (int)((*q * low_err_target) / kf_err);
    366      *q = AOMMIN(*q, (*q_high + *q_low + 1) >> 1);
    367    }
    368 
    369    // Clamp Q to upper and lower limits:
    370    *q = clamp(*q, *q_low, *q_high);
    371    *loop = (*q != last_q);
    372    return;
    373  }
    374 
    375  if (recode_loop_test(cpi, frame_over_shoot_limit, frame_under_shoot_limit, *q,
    376                       AOMMAX(*q_high, top_index), bottom_index)) {
    377    // Is the projected frame size out of range and are we allowed
    378    // to attempt to recode.
    379 
    380    // Frame size out of permitted range:
    381    // Update correction factor & compute new Q to try...
    382    // Frame is too large
    383    if (rc->projected_frame_size > rc->this_frame_target) {
    384      // Special case if the projected size is > the max allowed.
    385      if (*q == *q_high &&
    386          rc->projected_frame_size >= rc->max_frame_bandwidth) {
    387        const double q_val_high_current =
    388            av1_convert_qindex_to_q(*q_high, cm->seq_params->bit_depth);
    389        const double q_val_high_new =
    390            q_val_high_current *
    391            ((double)rc->projected_frame_size / rc->max_frame_bandwidth);
    392        *q_high = av1_find_qindex(q_val_high_new, cm->seq_params->bit_depth,
    393                                  rc->best_quality, rc->worst_quality);
    394      }
    395 
    396      // Raise Qlow as to at least the current value
    397      *q_low = AOMMIN(*q + 1, *q_high);
    398 
    399      if (*undershoot_seen || loop_count > 2 ||
    400          (loop_count == 2 && !frame_is_intra_only(cm))) {
    401        av1_rc_update_rate_correction_factors(cpi, 1, cm->width, cm->height);
    402 
    403        *q = (*q_high + *q_low + 1) / 2;
    404      } else if (loop_count == 2 && frame_is_intra_only(cm)) {
    405        const int q_mid = (*q_high + *q_low + 1) / 2;
    406        const int q_regulated = get_regulated_q_overshoot(
    407            cpi, 1, *q_low, *q_high, top_index, bottom_index);
    408        // Get 'q' in-between 'q_mid' and 'q_regulated' for a smooth
    409        // transition between loop_count < 2 and loop_count > 2.
    410        *q = (q_mid + q_regulated + 1) / 2;
    411      } else {
    412        *q = get_regulated_q_overshoot(cpi, 1, *q_low, *q_high, top_index,
    413                                       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, 1, cm->width, cm->height);
    424        *q = (*q_high + *q_low) / 2;
    425      } else if (loop_count == 2 && frame_is_intra_only(cm)) {
    426        const int q_mid = (*q_high + *q_low) / 2;
    427        const int q_regulated = get_regulated_q_undershoot(
    428            cpi, 1, *q_high, top_index, bottom_index);
    429        // Get 'q' in-between 'q_mid' and 'q_regulated' for a smooth
    430        // transition between loop_count < 2 and loop_count > 2.
    431        *q = (q_mid + q_regulated) / 2;
    432 
    433        // Special case reset for qlow for constrained quality.
    434        // This should only trigger where there is very substantial
    435        // undershoot on a frame and the auto cq level is above
    436        // the user passsed in value.
    437        if (rc_cfg->mode == AOM_CQ && q_regulated < *q_low) {
    438          *q_low = *q;
    439        }
    440      } else {
    441        *q = get_regulated_q_undershoot(cpi, 1, *q_high, top_index,
    442                                        bottom_index);
    443 
    444        // Special case reset for qlow for constrained quality.
    445        // This should only trigger where there is very substantial
    446        // undershoot on a frame and the auto cq level is above
    447        // the user passsed in value.
    448        if (rc_cfg->mode == AOM_CQ && *q < *q_low) {
    449          *q_low = *q;
    450        }
    451      }
    452 
    453      *undershoot_seen = 1;
    454    }
    455 
    456    // Clamp Q to upper and lower limits:
    457    *q = clamp(*q, *q_low, *q_high);
    458  }
    459 
    460  *loop = (*q != last_q);
    461 }
    462 #endif
    463 
    464 #ifdef __cplusplus
    465 }  // extern "C"
    466 #endif
    467 
    468 #endif  // AOM_AV1_ENCODER_RC_UTILS_H_