summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
authorYaowu Xu <yaowu@google.com>2014-10-17 12:13:16 -0700
committerYaowu Xu <yaowu@google.com>2014-10-28 09:31:10 -0700
commite5cd51880e75e0c61c12327773287057615257ec (patch)
tree0894419f52700c841f5ea79a1dc4b55004a73d2d /vp9/encoder
parent03a60b78db8ea2b78f2104acd1d4cdebda061a07 (diff)
downloadlibvpx-e5cd51880e75e0c61c12327773287057615257ec.tar
libvpx-e5cd51880e75e0c61c12327773287057615257ec.tar.gz
libvpx-e5cd51880e75e0c61c12327773287057615257ec.tar.bz2
libvpx-e5cd51880e75e0c61c12327773287057615257ec.zip
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
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_pickmode.c4
-rw-r--r--vp9/encoder/vp9_ratectrl.c33
2 files changed, 30 insertions, 7 deletions
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,