Commit e5cd5188 authored by Yaowu Xu's avatar Yaowu Xu
Browse files

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
parent 03a60b78
...@@ -616,6 +616,8 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, ...@@ -616,6 +616,8 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
continue; continue;
if (this_mode == NEWMV) { if (this_mode == NEWMV) {
if (ref_frame > LAST_FRAME)
continue;
if (cpi->sf.partition_search_type != VAR_BASED_PARTITION && if (cpi->sf.partition_search_type != VAR_BASED_PARTITION &&
this_rdc.rdcost < (int64_t)(1 << num_pels_log2_lookup[bsize])) this_rdc.rdcost < (int64_t)(1 << num_pels_log2_lookup[bsize]))
continue; continue;
...@@ -756,7 +758,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, ...@@ -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, // If the current reference frame is valid and we found a usable mode,
// we are done. // we are done.
if (best_rdc.rdcost < INT64_MAX) if (best_rdc.rdcost < INT64_MAX && ref_frame == GOLDEN_FRAME)
break; break;
} }
......
...@@ -1333,7 +1333,18 @@ static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { ...@@ -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 diff = rc->optimal_buffer_level - rc->buffer_level;
const int64_t one_pct_bits = 1 + rc->optimal_buffer_level / 100; 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 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 && if (svc->number_temporal_layers > 1 &&
oxcf->rc_mode == VPX_CBR) { oxcf->rc_mode == VPX_CBR) {
// Note that for layers, avg_frame_bandwidth is the cumulative // 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) { ...@@ -1447,15 +1458,25 @@ void vp9_rc_get_one_pass_cbr_params(VP9_COMP *cpi) {
rc->frames_to_key = cpi->oxcf.key_freq; rc->frames_to_key = cpi->oxcf.key_freq;
rc->kf_boost = DEFAULT_KF_BOOST; rc->kf_boost = DEFAULT_KF_BOOST;
rc->source_alt_ref_active = 0; rc->source_alt_ref_active = 0;
target = calc_iframe_target_size_one_pass_cbr(cpi);
} else { } else {
cm->frame_type = INTER_FRAME; 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); 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, int vp9_compute_qdelta(const RATE_CONTROL *rc, double qstart, double qtarget,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment