From 1d293253612352e4c68d8ecbea4fb0bcfe2ddbea Mon Sep 17 00:00:00 2001 From: Marco Paniconi Date: Mon, 28 May 2018 21:08:57 -0700 Subject: [PATCH] vp9: Adjust cyclic refresh and limit frame-level q. For CBR mode with aq-mode=3: reduce delta-q for second segment and limit how much the frame-level q can decreae from one frame to the next. Reduces bitrate spikes in slide/sreen content. Change-Id: Id9ac4b7270f07e09690380755cfbef4aec5c26dc --- vp9/encoder/vp9_aq_cyclicrefresh.c | 17 +++++++++++++++ vp9/encoder/vp9_aq_cyclicrefresh.h | 2 ++ vp9/encoder/vp9_ratectrl.c | 35 +++++++++++++++++------------- 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/vp9/encoder/vp9_aq_cyclicrefresh.c b/vp9/encoder/vp9_aq_cyclicrefresh.c index b8c557275..3aaec2e29 100644 --- a/vp9/encoder/vp9_aq_cyclicrefresh.c +++ b/vp9/encoder/vp9_aq_cyclicrefresh.c @@ -459,6 +459,15 @@ void vp9_cyclic_refresh_update_parameters(VP9_COMP *const cpi) { cr->rate_boost_fac = 13; } } + // For screen-content: keep rate_ratio_qdelta to 2.0 (segment#1 boost) and + // percent_refresh (refresh rate) to 10. But reduce rate boost for segment#2 + // (rate_boost_fac = 10 disables segment#2). + // TODO(marpan): Consider increasing refresh rate after slide change. + if (cpi->oxcf.content == VP9E_CONTENT_SCREEN) { + cr->percent_refresh = 10; + cr->rate_ratio_qdelta = 2.0; + cr->rate_boost_fac = 10; + } // Adjust some parameters for low resolutions. if (cm->width <= 352 && cm->height <= 288) { if (rc->avg_frame_bandwidth < 3000) { @@ -589,3 +598,11 @@ void vp9_cyclic_refresh_reset_resize(VP9_COMP *const cpi) { cpi->refresh_golden_frame = 1; cpi->refresh_alt_ref_frame = 1; } + +void vp9_cyclic_refresh_limit_q(CYCLIC_REFRESH *const cr, int prev_q, int *q) { + // For now apply hard limit to frame-level decrease in q, if the cyclic + // refresh is active (percent_refresh > 0). + if (cr->percent_refresh > 0 && prev_q - *q > 8) { + *q = prev_q - 8; + } +} diff --git a/vp9/encoder/vp9_aq_cyclicrefresh.h b/vp9/encoder/vp9_aq_cyclicrefresh.h index 77fa67c9e..ce72fcb33 100644 --- a/vp9/encoder/vp9_aq_cyclicrefresh.h +++ b/vp9/encoder/vp9_aq_cyclicrefresh.h @@ -139,6 +139,8 @@ static INLINE int cyclic_refresh_segment_id(int segment_id) { return CR_SEGMENT_ID_BASE; } +void vp9_cyclic_refresh_limit_q(CYCLIC_REFRESH *const cr, int prev_q, int *q); + #ifdef __cplusplus } // extern "C" #endif diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 2c339ae25..01c1ab466 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -712,21 +712,26 @@ int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame, } } while (++i <= active_worst_quality); - // In CBR mode, this makes sure q is between oscillating Qs to prevent - // resonance. - if (cpi->oxcf.rc_mode == VPX_CBR && !cpi->rc.reset_high_source_sad && - (!cpi->oxcf.gf_cbr_boost_pct || - !(cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame)) && - (cpi->rc.rc_1_frame * cpi->rc.rc_2_frame == -1) && - cpi->rc.q_1_frame != cpi->rc.q_2_frame) { - int qclamp = clamp(q, VPXMIN(cpi->rc.q_1_frame, cpi->rc.q_2_frame), - VPXMAX(cpi->rc.q_1_frame, cpi->rc.q_2_frame)); - // If the previous had overshoot and the current q needs to increase above - // the clamped value, reduce the clamp for faster reaction to overshoot. - if (cpi->rc.rc_1_frame == -1 && q > qclamp) - q = (q + qclamp) >> 1; - else - q = qclamp; + // Adjustment to q for CBR mode. + if (cpi->oxcf.rc_mode == VPX_CBR) { + // This makes sure q is between oscillating Qs to prevent resonance. + if (!cpi->rc.reset_high_source_sad && + (!cpi->oxcf.gf_cbr_boost_pct || + !(cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame)) && + (cpi->rc.rc_1_frame * cpi->rc.rc_2_frame == -1) && + cpi->rc.q_1_frame != cpi->rc.q_2_frame) { + int qclamp = clamp(q, VPXMIN(cpi->rc.q_1_frame, cpi->rc.q_2_frame), + VPXMAX(cpi->rc.q_1_frame, cpi->rc.q_2_frame)); + // If the previous frame had overshoot and the current q needs to increase + // above the clamped value, reduce the clamp for faster reaction to + // overshoot. + if (cpi->rc.rc_1_frame == -1 && q > qclamp) + q = (q + qclamp) >> 1; + else + q = qclamp; + } + if (cpi->oxcf.content == VP9E_CONTENT_SCREEN) + vp9_cyclic_refresh_limit_q(cr, cpi->rc.q_1_frame, &q); } return q; } -- 2.40.0