From 8446af7e9a12c5725e845564f40272dd9185c1cc Mon Sep 17 00:00:00 2001 From: Marco Paniconi Date: Wed, 23 May 2018 14:51:00 -0700 Subject: [PATCH] vp9: Rate control adjustments for screen content. For screen content mode: changes to reduce occurence of significant QP decrease (from one frame to next), which can cause large frames (overshoot/delay). -cap the buffer increase to optimal level for frame drop mode where full superframe can drop -reduce the max_adjustment_down due to buffer overflow -reduce qp threshold to trigger re-encode on large frame Change-Id: I3e30e4814192b5f728abff3f7359eb64f561b8f0 --- vp9/encoder/vp9_ratectrl.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index ba09025f0..94d8900c4 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -273,6 +273,14 @@ static void update_buffer_level(VP9_COMP *cpi, int encoded_frame_size) { const VP9_COMMON *const cm = &cpi->common; RATE_CONTROL *const rc = &cpi->rc; + // On dropped frame, don't update buffer if its currently stable + // (above optimal level). This can cause issues when full superframe + // can drop (!= LAYER_DROP), since QP is adjusted downwards with buffer + // overflow, which can cause more frame drops. + if (cpi->svc.framedrop_mode != LAYER_DROP && encoded_frame_size == 0 && + rc->buffer_level > rc->optimal_buffer_level) + return; + // Non-viewable frames are a special case and are treated as pure overhead. if (!cm->show_frame) { rc->bits_off_target -= encoded_frame_size; @@ -770,8 +778,10 @@ static int calc_active_worst_quality_one_pass_cbr(const VP9_COMP *cpi) { active_worst_quality = VPXMIN(rc->worst_quality, ambient_qp * 5 >> 2); if (rc->buffer_level > rc->optimal_buffer_level) { // Adjust down. - // Maximum limit for down adjustment, ~30%. + // Maximum limit for down adjustment ~30%; make it lower for screen content. int max_adjustment_down = active_worst_quality / 3; + if (cpi->oxcf.content == VP9E_CONTENT_SCREEN) + max_adjustment_down = active_worst_quality >> 3; if (max_adjustment_down) { buff_lvl_step = ((rc->maximum_buffer_size - rc->optimal_buffer_level) / max_adjustment_down); @@ -2512,7 +2522,7 @@ void vp9_scene_detection_onepass(VP9_COMP *cpi) { int vp9_encodedframe_overshoot(VP9_COMP *cpi, int frame_size, int *q) { VP9_COMMON *const cm = &cpi->common; RATE_CONTROL *const rc = &cpi->rc; - int thresh_qp = 3 * (rc->worst_quality >> 2); + int thresh_qp = 7 * (rc->worst_quality >> 3); int thresh_rate = rc->avg_frame_bandwidth << 3; // Lower rate threshold for video. if (cpi->oxcf.content != VP9E_CONTENT_SCREEN) -- 2.40.0