rtc: Fixes to rate control for CBR mode For 1 pass CBR mode: constrain the active_best for gf/arf refresh frames on the gf_cbr_boost_pct flag, as this logic was intended only for boosted gf/arf frames. Also move the QP adjustmemnt to separate function and fix the conditions for the adjustment/clamping. Neutral/negligible change in bdrate for speed >= 6 rtc. Change helps to reduce excessive overshoot in some cases. Change-Id: I981c452752c7bde61a25c24dfa52d4cfaae48ed1
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c index de96e97..7f96b24 100644 --- a/av1/encoder/ratectrl.c +++ b/av1/encoder/ratectrl.c
@@ -369,6 +369,36 @@ } } +static int adjust_q_cbr(const AV1_COMP *cpi, int q) { + const RATE_CONTROL *const rc = &cpi->rc; + const AV1_COMMON *const cm = &cpi->common; + const int max_delta = 16; + const int change_avg_frame_bandwidth = + abs(rc->avg_frame_bandwidth - rc->prev_avg_frame_bandwidth) > + 0.1 * (rc->avg_frame_bandwidth); + // If resolution changes or avg_frame_bandwidth significantly changed, + // then set this flag to indicate change in target bits per macroblock. + const int change_target_bits_mb = + cm->prev_frame && + (cm->width != cm->prev_frame->width || + cm->height != cm->prev_frame->height || change_avg_frame_bandwidth); + // Apply some control/clamp to QP under certain conditions. + if (cm->current_frame.frame_type != KEY_FRAME && !cpi->use_svc && + rc->frames_since_key > 1 && !change_target_bits_mb && + (!cpi->oxcf.gf_cbr_boost_pct || + !(cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame))) { + // Make sure q is between oscillating Qs to prevent resonance. + if (rc->rc_1_frame * rc->rc_2_frame == -1 && + rc->q_1_frame != rc->q_2_frame) { + q = clamp(q, AOMMIN(rc->q_1_frame, rc->q_2_frame), + AOMMAX(rc->q_1_frame, rc->q_2_frame)); + } + // Limit the decrease in Q from previous frame. + if (rc->q_1_frame - q > max_delta) q = rc->q_1_frame - max_delta; + } + return AOMMAX(AOMMIN(q, cpi->rc.worst_quality), cpi->rc.best_quality); +} + static const RATE_FACTOR_LEVEL rate_factor_levels[FRAME_UPDATE_TYPES] = { KF_STD, // KF_UPDATE INTER_NORMAL, // LF_UPDATE @@ -582,14 +612,9 @@ find_closest_qindex_by_rate(target_bits_per_mb, cpi, correction_factor, active_best_quality, active_worst_quality); - // In CBR mode, this makes sure q is between oscillating Qs to prevent - // resonance. - if (cpi->oxcf.rc_mode == AOM_CBR && !cpi->use_svc && - (cpi->rc.rc_1_frame * cpi->rc.rc_2_frame == -1) && - cpi->rc.q_1_frame != cpi->rc.q_2_frame) { - q = clamp(q, AOMMIN(cpi->rc.q_1_frame, cpi->rc.q_2_frame), - AOMMAX(cpi->rc.q_1_frame, cpi->rc.q_2_frame)); - } + if (cpi->oxcf.rc_mode == AOM_CBR && cpi->oxcf.pass == 0) + return adjust_q_cbr(cpi, q); + return q; } @@ -756,6 +781,7 @@ av1_compute_qdelta(rc, q_val, q_val * q_adj_factor, bit_depth); } } else if (!rc->is_src_frame_alt_ref && !cpi->use_svc && + cpi->oxcf.gf_cbr_boost_pct && (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { // Use the lower of active_worst_quality and recent // average Q as basis for GF/ARF best Q limit unless last frame was @@ -1515,6 +1541,7 @@ if (current_frame->frame_type == KEY_FRAME) rc->last_kf_qindex = qindex; update_buffer_level(cpi, rc->projected_frame_size); + rc->prev_avg_frame_bandwidth = rc->avg_frame_bandwidth; // Rolling monitors of whether we are over or underspending used to help // regulate min and Max Q in two pass.
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h index 0c92af6..530c02a 100644 --- a/av1/encoder/ratectrl.h +++ b/av1/encoder/ratectrl.h
@@ -108,6 +108,7 @@ int avg_frame_bandwidth; // Average frame size target for clip int min_frame_bandwidth; // Minimum allocation used for any frame int max_frame_bandwidth; // Maximum burst rate allowed for a frame. + int prev_avg_frame_bandwidth; int ni_av_qi; int ni_tot_qi;