/* * Copyright (c) 2020, Alliance for Open Media. All rights reserved. * * This source code is subject to the terms of the BSD 2 Clause License and * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License * was not distributed with this source code in the LICENSE file, you can * obtain it at www.aomedia.org/license/software. If the Alliance for Open * Media Patent License 1.0 was not distributed with this source code in the * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
// 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 * back and recode a frame. * * \ingroup rate_control * * \param[in] cpi Top-level encoder structure * \param[in] high_limit Upper rate threshold * \param[in] low_limit Lower rate threshold * \param[in] q Current q index * \param[in] maxq Maximum allowed q index * \param[in] minq Minimum allowed q index * * \return Indicates if a recode is required. * \retval 1 Recode Required * \retval 0 No Recode required
*/ staticinlineint 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; constint 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;
} elseif (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;
}
staticinlineint 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;
staticinlineint 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;
/*!\brief Called after encode_with_recode_loop() has just encoded a frame. * This function works out whether we undershot or overshot our bitrate * target and adjusts q as appropriate. It also decides whether or not * we need to recode the frame to get closer to the target rate. * * \ingroup rate_control * * \param[in] cpi Top-level encoder structure * \param[out] loop Should we go around the recode loop again * \param[in,out] q New q index value * \param[in,out] q_low Low q index limit for this loop itteration * \param[in,out] q_high High q index limit for this loop itteration * \param[in] top_index Max permited new value for q index * \param[in] bottom_index Min permited new value for q index * \param[in,out] undershoot_seen Have we seen undershoot on this frame * \param[in,out] overshoot_seen Have we seen overshoot on this frame * \param[in,out] low_cr_seen Have we previously trriggered recode * because the compression ration was less * than a given minimum threshold. * \param[in] loop_count Loop itterations so far. *
*/ staticinlinevoid recode_loop_update_q(
AV1_COMP *const cpi, int *const loop, int *const q, int *const q_low, int *const q_high, constint top_index, constint bottom_index, int *const undershoot_seen, int *const overshoot_seen, int *const low_cr_seen, constint loop_count) {
AV1_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc; const RateControlCfg *const rc_cfg = &cpi->oxcf.rc_cfg;
*loop = 0;
// Special case for overlay frame. if (rc->is_src_frame_alt_ref &&
rc->projected_frame_size < rc->max_frame_bandwidth) return;
#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);
} elseif (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);
// 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
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet)
¤
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.