ref: 2626b1545e4b5493729850d14185b0ec00a21383
parent: e32f0bf2399bfba4cda1f04f56bc2b05a2d34354
author: Marco Paniconi <marpan@google.com>
date: Thu Jun 7 11:07:57 EDT 2018
vp9-svc: Adjust some logic on gf temporal reference. For the feature of using second temporal reference (when inter-layer is off): move the buffer_idx assignement and refresh flag settings further down to vp9_rc_get_svc_params(), since is_key_frame is set there for every frame/layer. Otherwise it was using the setting from the previous frame/layer. This makes the refresh more consistent for both layers for 2 spatial layers case. Small/negligible change in metrics. Change-Id: I88279243bc27898448e8891dba38143d936cf6d5
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -1873,27 +1873,42 @@
}
}
// If long term termporal feature is enabled, set the period of the update.
- // The update/refresh of this reference frame is always on base temporal
+ // The update/refresh of this reference frame is always on base temporal
// layer frame.
- if (svc->use_gf_temporal_ref_current_layer && svc->temporal_layer_id == 0) {
- if (svc->layer_context[svc->temporal_layer_id].is_key_frame) {
- // On key frame we update the buffer index used for long term reference.
- // Use the alt_ref since it is not used or updated on key frames.
+ if (svc->use_gf_temporal_ref_current_layer) {
+ // Only use gf long-term prediction on non-key superframes.
+ if (!svc->layer_context[svc->temporal_layer_id].is_key_frame) {
+ // Use golden for this reference, which will be used for prediction.
int index = svc->spatial_layer_id;
- cpi->ext_refresh_alt_ref_frame = 1;
if (svc->number_spatial_layers == 3) index = svc->spatial_layer_id - 1;
assert(index >= 0);
- cpi->alt_fb_idx = svc->buffer_gf_temporal_ref[index].idx;
- } else if (rc->frames_till_gf_update_due == 0) {
- // Set perdiod of next update. Make it a multiple of 10, as the cyclic
- // refresh is typically ~10%, and we'd like the update to happen after
- // a few cylces of the refresh (so it better quality frame). Note the
- // cyclic refresh for SVC only operates on base temporal layer frames.
- // Choose 20 as perdiod for now (2 cycles).
- rc->baseline_gf_interval = 20;
- rc->frames_till_gf_update_due = rc->baseline_gf_interval;
- cpi->ext_refresh_golden_frame = 1;
- rc->gfu_boost = DEFAULT_GF_BOOST;
+ cpi->gld_fb_idx = svc->buffer_gf_temporal_ref[index].idx;
+ // Enable prediction off LAST (last reference) and golden (which will
+ // generally be further behind/long-term reference).
+ cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
+ }
+ // Check for update/refresh of reference: only refresh on base temporal
+ // layer.
+ if (svc->temporal_layer_id == 0) {
+ if (svc->layer_context[svc->temporal_layer_id].is_key_frame) {
+ // On key frame we update the buffer index used for long term reference.
+ // Use the alt_ref since it is not used or updated on key frames.
+ int index = svc->spatial_layer_id;
+ if (svc->number_spatial_layers == 3) index = svc->spatial_layer_id - 1;
+ assert(index >= 0);
+ cpi->alt_fb_idx = svc->buffer_gf_temporal_ref[index].idx;
+ cpi->ext_refresh_alt_ref_frame = 1;
+ } else if (rc->frames_till_gf_update_due == 0) {
+ // Set perdiod of next update. Make it a multiple of 10, as the cyclic
+ // refresh is typically ~10%, and we'd like the update to happen after
+ // a few cylces of the refresh (so it better quality frame). Note the
+ // cyclic refresh for SVC only operates on base temporal layer frames.
+ // Choose 20 as perdiod for now (2 cycles).
+ rc->baseline_gf_interval = 20;
+ rc->frames_till_gf_update_due = rc->baseline_gf_interval;
+ cpi->ext_refresh_golden_frame = 1;
+ rc->gfu_boost = DEFAULT_GF_BOOST;
+ }
}
} else if (!svc->use_gf_temporal_ref) {
rc->frames_till_gf_update_due = INT_MAX;
--- a/vp9/encoder/vp9_svc_layercontext.c
+++ b/vp9/encoder/vp9_svc_layercontext.c
@@ -744,16 +744,6 @@
svc->spatial_layer_id >= svc->number_spatial_layers - 2) {
// Enable the second (long-term) temporal reference at the frame-level.
svc->use_gf_temporal_ref_current_layer = 1;
- // Only used for prediction for on non-key superframes.
- if (!svc->layer_context[svc->temporal_layer_id].is_key_frame) {
- // Use golden for this reference which will be used for prediction.
- int index = svc->spatial_layer_id;
- if (svc->number_spatial_layers == 3) index = svc->spatial_layer_id - 1;
- cpi->gld_fb_idx = svc->buffer_gf_temporal_ref[index].idx;
- // Enable prediction off LAST (last reference) and golden (which will
- // generally be further behind/long-term reference).
- cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
- }
}
// Reset the drop flags for all spatial layers, on the base layer.