// Under a configuration change, where maximum_buffer_size may change, // keep buffer level clipped to the maximum allowed buffer size.
p_rc->bits_off_target =
AOMMIN(p_rc->bits_off_target, p_rc->maximum_buffer_size);
p_rc->buffer_level = AOMMIN(p_rc->buffer_level, p_rc->maximum_buffer_size);
}
/*!\brief Function to test for conditions that indicate we should loop *backandrecodeaframe. * *\ingrouprate_control * *\param[in]cpiTop-levelencoderstructure *\param[in]high_limitUpperratethreshold *\param[in]low_limitLowerratethreshold *\param[in]qCurrentqindex *\param[in]maxqMaximumallowedqindex *\param[in]minqMinimumallowedqindex * *\returnIndicatesifarecodeisrequired. *\retval1RecodeRequired *\retval0NoRecoderequired
*/ static inline int recode_loop_test(AV1_COMP *cpi, int high_limit, int low_limit,
int q, int maxq, int minq) { const RATE_CONTROL *const rc = &cpi->rc; const AV1EncoderConfig *const oxcf = &cpi->oxcf; const int frame_is_kfgfarf = frame_is_kf_gf_arf(cpi);
int force_recode = 0;
if ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
(cpi->sf.hl_sf.recode_loop == ALLOW_RECODE) ||
(frame_is_kfgfarf &&
(cpi->sf.hl_sf.recode_loop == ALLOW_RECODE_KFARFGF))) { // TODO(agrange) high_limit could be greater than the scale-down threshold.
if ((rc->projected_frame_size > high_limit && q < maxq) ||
(rc->projected_frame_size < low_limit && q > minq)) {
force_recode = 1;
} else if (cpi->oxcf.rc_cfg.mode == AOM_CQ) { // Deal with frame undershoot and whether or not we are // below the automatically set cq level.
if (q > oxcf->rc_cfg.cq_level &&
rc->projected_frame_size <
(((int64_t)rc->this_frame_target * 7) >> 3)) {
force_recode = 1;
}
}
} return force_recode;
}
static inline int get_regulated_q_overshoot(AV1_COMP *const cpi,
int is_encode_stage, int q_low,
int q_high, int top_index,
int bottom_index) { const AV1_COMMON *const cm = &cpi->common; const RATE_CONTROL *const rc = &cpi->rc;
static inline int get_regulated_q_undershoot(AV1_COMP *const cpi,
int is_encode_stage, int q_high,
int top_index, int bottom_index) { const AV1_COMMON *const cm = &cpi->common; const RATE_CONTROL *const rc = &cpi->rc;
#if CONFIG_AV1_HIGHBITDEPTH
if (cm->seq_params->use_highbitdepth) {
kf_err = aom_highbd_get_y_sse(cpi->source, &cm->cur_frame->buf);
} else {
kf_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
} #else
kf_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf); #endif // Prevent possible divide by zero error below for perfect KF
kf_err += !kf_err;
// The key frame is not good enough or we can afford // to make it better without undue risk of popping.
if ((kf_err > high_err_target &&
rc->projected_frame_size <= frame_over_shoot_limit) ||
(kf_err > low_err_target &&
rc->projected_frame_size <= frame_under_shoot_limit)) { // Lower q_high
*q_high = AOMMAX(*q - 1, *q_low);
// Adjust Q
*q = (int)((*q * high_err_target) / kf_err);
*q = AOMMIN(*q, (*q_high + *q_low) >> 1);
} else if (kf_err < low_err_target &&
rc->projected_frame_size >= frame_under_shoot_limit) { // The key frame is much better than the previous frame // Raise q_low
*q_low = AOMMIN(*q + 1, *q_high);
// Clamp Q to upper and lower limits:
*q = clamp(*q, *q_low, *q_high);
*loop = (*q != last_q); return;
}
if (recode_loop_test(cpi, frame_over_shoot_limit, frame_under_shoot_limit, *q,
AOMMAX(*q_high, top_index), bottom_index)) { // Is the projected frame size out of range and are we allowed // to attempt to recode.
// Frame size out of permitted range: // Update correction factor & compute new Q to try... // Frame is too large
if (rc->projected_frame_size > rc->this_frame_target) { // Special case if the projected size is > the max allowed.
if (*q == *q_high &&
rc->projected_frame_size >= rc->max_frame_bandwidth) { constdouble q_val_high_current =
av1_convert_qindex_to_q(*q_high, cm->seq_params->bit_depth); constdouble q_val_high_new =
q_val_high_current *
((double)rc->projected_frame_size / rc->max_frame_bandwidth);
*q_high = av1_find_qindex(q_val_high_new, cm->seq_params->bit_depth,
rc->best_quality, rc->worst_quality);
}
// Raise Qlow as to at least the current value
*q_low = AOMMIN(*q + 1, *q_high);
*q = (*q_high + *q_low + 1) / 2;
} else if (loop_count == 2 && frame_is_intra_only(cm)) { const int q_mid = (*q_high + *q_low + 1) / 2; const int q_regulated = get_regulated_q_overshoot(
cpi, 1, *q_low, *q_high, top_index, bottom_index); // Get 'q' in-between 'q_mid' and 'q_regulated' for a smooth // transition between loop_count < 2 and loop_count > 2.
*q = (q_mid + q_regulated + 1) / 2;
} else {
*q = get_regulated_q_overshoot(cpi, 1, *q_low, *q_high, top_index,
bottom_index);
}
*overshoot_seen = 1;
} else { // Frame is too small
*q_high = AOMMAX(*q - 1, *q_low);
if (*overshoot_seen || loop_count > 2 ||
(loop_count == 2 && !frame_is_intra_only(cm))) {
av1_rc_update_rate_correction_factors(cpi, 1, cm->width, cm->height);
*q = (*q_high + *q_low) / 2;
} else if (loop_count == 2 && frame_is_intra_only(cm)) { const int q_mid = (*q_high + *q_low) / 2; const int q_regulated = get_regulated_q_undershoot(
cpi, 1, *q_high, top_index, bottom_index); // Get 'q' in-between 'q_mid' and 'q_regulated' for a smooth // transition between loop_count < 2 and loop_count > 2.
*q = (q_mid + q_regulated) / 2;
// Special case reset for qlow for constrained quality. // This should only trigger where there is very substantial // undershoot on a frame and the auto cq level is above // the user passsed in value.
if (rc_cfg->mode == AOM_CQ && q_regulated < *q_low) {
*q_low = *q;
}
} else {
*q = get_regulated_q_undershoot(cpi, 1, *q_high, top_index,
bottom_index);
// Special case reset for qlow for constrained quality. // This should only trigger where there is very substantial // undershoot on a frame and the auto cq level is above // the user passsed in value.
if (rc_cfg->mode == AOM_CQ && *q < *q_low) {
*q_low = *q;
}
}
*undershoot_seen = 1;
}
// Clamp Q to upper and lower limits:
*q = clamp(*q, *q_low, *q_high);
}
*loop = (*q != last_q);
} #endif
#ifdef __cplusplus
} // extern "C" #endif
#endif// AOM_AV1_ENCODER_RC_UTILS_H_
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet am 2026-08-26)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.