From 704028d435d0e9ba445f961502e2083da8ed80f4 Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Mon, 7 Oct 2013 19:20:10 +0100 Subject: [PATCH] Experimental rate control change. When the codec in VBR (or cq) mode hits its max q limits and is struggling to hit a target bandwidth, the bit target per frame collapses. In the first instance normal frames cap out at the maximum allowed Q and then the ARF and GFs do the same. This latter behavior is not generally desirable as GFs and ARFs are only effective from a quality and data rate perspective if they have at lease some level of -Q delta compared to the surrounding frames. In this patch I define a separate max Q for GFs and ARFs that is derived from but somewhat lower than that defined for normal frames. In effect there is a minimum Q delta that will always be available for GFs and ARFs regardless of the target rate and MAXQ setting. This may of course mean that the absolute lowest rate obtainable for a given clip is somewhat higher. Change-Id: I268868b28401900d0cd87e51e609cd3b784ab54a --- vp9/encoder/vp9_onyx_if.c | 49 +++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index cd142149a..a979a4b5e 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -787,6 +787,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) { sf->adaptive_motion_search = 1; sf->auto_mv_step_size = 1; sf->adaptive_rd_thresh = 2; + sf->recode_loop = 2; } if (speed == 2) { sf->use_square_partition_only = !(cpi->common.frame_type == KEY_FRAME || @@ -2610,14 +2611,15 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) { } #endif -static int pick_q_and_adjust_q_bounds(VP9_COMP *cpi) { +static int pick_q_and_adjust_q_bounds(VP9_COMP *cpi, + int * bottom_index, int * top_index) { // Set an active best quality and if necessary active worst quality int q = cpi->active_worst_quality; VP9_COMMON *const cm = &cpi->common; if (cm->frame_type == KEY_FRAME) { #if !CONFIG_MULTIPLE_ARF - // Handle the special case for key frames forced when we have reached + // Handle the special case for key frames forced when we have75 reached // the maximum key frame interval. Here force the Q to a range // based on the ambient Q to reduce the risk of popping. if (cpi->this_key_frame_forced) { @@ -2663,12 +2665,13 @@ static int pick_q_and_adjust_q_bounds(VP9_COMP *cpi) { cpi->active_best_quality = cpi->active_worst_quality + compute_qdelta(cpi, current_q, current_q * 0.3); #endif - } else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) { + } else if (!cpi->is_src_frame_alt_ref && + (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { int high = 2000; int low = 400; // Use the lower of cpi->active_worst_quality and recent - // average Q as basis for GF/ARF Q limit unless last frame was + // average Q as basis for GF/ARF best Q limit unless last frame was // a key frame. if (cpi->frames_since_key > 1 && cpi->avg_frame_qindex < cpi->active_worst_quality) { @@ -2709,14 +2712,10 @@ static int pick_q_and_adjust_q_bounds(VP9_COMP *cpi) { } } } else { - if (!cpi->refresh_alt_ref_frame) { - cpi->active_best_quality = inter_minq[q]; - } else { cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost, low, high, gf_low_motion_minq, gf_high_motion_minq); - } } } else { if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { @@ -2732,7 +2731,7 @@ static int pick_q_and_adjust_q_bounds(VP9_COMP *cpi) { cpi->active_best_quality = inter_minq[q]; #endif - // For the constant/constrained quality mode we don't want + // For the constrained quality mode we don't want // q to fall below the cq level. if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && (cpi->active_best_quality < cpi->cq_target_quality)) { @@ -2760,14 +2759,28 @@ static int pick_q_and_adjust_q_bounds(VP9_COMP *cpi) { if (cpi->active_worst_quality < cpi->active_best_quality) cpi->active_worst_quality = cpi->active_best_quality; - // Special case code to try and match quality with forced key frames + // Limit Q range for the adaptive loop. + if (cm->frame_type == KEY_FRAME && !cpi->this_key_frame_forced) { + *top_index = cpi->active_best_quality; + } else if (!cpi->is_src_frame_alt_ref && + (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { + *top_index = + (cpi->active_worst_quality + cpi->active_best_quality * 3) / 4; + } else { + *top_index = cpi->active_worst_quality; + } + *bottom_index = cpi->active_best_quality; + if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { q = cpi->active_best_quality; + // Special case code to try and match quality with forced key frames } else if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) { q = cpi->last_boosted_qindex; } else { // Determine initial Q to try q = vp9_regulate_q(cpi, cpi->this_frame_target); + if (q > *top_index) + q = *top_index; } return q; @@ -2906,7 +2919,10 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, vp9_clear_system_state(); - q = pick_q_and_adjust_q_bounds(cpi); + q = pick_q_and_adjust_q_bounds(cpi, &bottom_index, &top_index); + + q_high = top_index; + q_low = bottom_index; vp9_compute_frame_size_bounds(cpi, &frame_under_shoot_limit, &frame_over_shoot_limit); @@ -2930,16 +2946,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, q_high = q; printf("frame:%d q:%d\n", cm->current_video_frame, q); - } else { -#endif - // Limit Q range for the adaptive loop. - bottom_index = cpi->active_best_quality; - top_index = cpi->active_worst_quality; - q_low = cpi->active_best_quality; - q_high = cpi->active_worst_quality; -#if CONFIG_MULTIPLE_ARF } #endif + loop_count = 0; vp9_zero(cpi->rd_tx_select_threshes); @@ -3030,10 +3039,10 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, frame_over_shoot_limit = 1; active_worst_qchanged = 0; - // Special case handling for forced key frames if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { loop = 0; } else { + // Special case handling for forced key frames if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) { int last_q = q; int kf_err = vp9_calc_ss_err(cpi->Source, -- 2.40.0