From: Yaowu Xu Date: Fri, 17 Oct 2014 19:13:16 +0000 (-0700) Subject: Allow update of golden refernce buffer in CBR mode X-Git-Tag: v1.4.0~557^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e5cd51880e75e0c61c12327773287057615257ec;p=libvpx Allow update of golden refernce buffer in CBR mode This commit changes to allow the usage of golden reference frame in VP9 CBR mode to improve quality. VP9 supports potentially up to 8 reference buffers, it has reference buffers available for this purpose. This was not possible in VP8 as golden and alt-ref buffers were used for temporal scalability purpose in CBR mode in WebRTC. For frames that update golden frame, there can be a quality boost. The amount of allowed bitrate boost can be controlled via parameter rc_max_inter_bitrate_pct. The inital value of the boost ratior is currently based on over_shoot_pct. Further experiments will work out the adaption of this boost value. Change-Id: I0c5f010c8fd8b7b598f69779c1b30e5b2ac30a4d --- diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index 837e6e200..01450d016 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c @@ -616,6 +616,8 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, continue; if (this_mode == NEWMV) { + if (ref_frame > LAST_FRAME) + continue; if (cpi->sf.partition_search_type != VAR_BASED_PARTITION && this_rdc.rdcost < (int64_t)(1 << num_pels_log2_lookup[bsize])) continue; @@ -756,7 +758,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, } // If the current reference frame is valid and we found a usable mode, // we are done. - if (best_rdc.rdcost < INT64_MAX) + if (best_rdc.rdcost < INT64_MAX && ref_frame == GOLDEN_FRAME) break; } diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index f3e900f0c..95f8f733d 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -1333,7 +1333,18 @@ static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { const int64_t diff = rc->optimal_buffer_level - rc->buffer_level; const int64_t one_pct_bits = 1 + rc->optimal_buffer_level / 100; int min_frame_target = MAX(rc->avg_frame_bandwidth >> 4, FRAME_OVERHEAD_BITS); - int target = rc->avg_frame_bandwidth; + int target; + + if (oxcf->gf_cbr_boost_pct) { + const int af_ratio_pct = oxcf->gf_cbr_boost_pct + 100; + target = cpi->refresh_golden_frame ? + (rc->avg_frame_bandwidth * rc->baseline_gf_interval * af_ratio_pct) / + (rc->baseline_gf_interval * 100 + af_ratio_pct - 100) : + (rc->avg_frame_bandwidth * rc->baseline_gf_interval * 100) / + (rc->baseline_gf_interval * 100 + af_ratio_pct - 100); + } else { + target = rc->avg_frame_bandwidth; + } if (svc->number_temporal_layers > 1 && oxcf->rc_mode == VPX_CBR) { // Note that for layers, avg_frame_bandwidth is the cumulative @@ -1447,15 +1458,25 @@ void vp9_rc_get_one_pass_cbr_params(VP9_COMP *cpi) { rc->frames_to_key = cpi->oxcf.key_freq; rc->kf_boost = DEFAULT_KF_BOOST; rc->source_alt_ref_active = 0; - target = calc_iframe_target_size_one_pass_cbr(cpi); } else { cm->frame_type = INTER_FRAME; - target = calc_pframe_target_size_one_pass_cbr(cpi); } + if (rc->frames_till_gf_update_due == 0) { + rc->baseline_gf_interval = DEFAULT_GF_INTERVAL; + rc->frames_till_gf_update_due = rc->baseline_gf_interval; + // NOTE: frames_till_gf_update_due must be <= frames_to_key. + if (rc->frames_till_gf_update_due > rc->frames_to_key) + rc->frames_till_gf_update_due = rc->frames_to_key; + cpi->refresh_golden_frame = 1; + rc->gfu_boost = DEFAULT_GF_BOOST; + } + + if (cm->frame_type == KEY_FRAME) + target = calc_iframe_target_size_one_pass_cbr(cpi); + else + target = calc_pframe_target_size_one_pass_cbr(cpi); + vp9_rc_set_frame_target(cpi, target); - // Don't use gf_update by default in CBR mode. - rc->frames_till_gf_update_due = INT_MAX; - rc->baseline_gf_interval = INT_MAX; } int vp9_compute_qdelta(const RATE_CONTROL *rc, double qstart, double qtarget,