From: Marco Paniconi Date: Thu, 7 Jun 2018 22:07:57 +0000 (-0700) Subject: vp9-svc: Adjust some logic on gf temporal reference. X-Git-Tag: v1.8.0~631 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2626b1545e4b5493729850d14185b0ec00a21383;p=libvpx 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 --- diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 4b30ca7a8..452e4d3cd 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -1873,27 +1873,42 @@ void vp9_rc_get_svc_params(VP9_COMP *cpi) { } } // 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; diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c index ed65463c2..c35ed8454 100644 --- a/vp9/encoder/vp9_svc_layercontext.c +++ b/vp9/encoder/vp9_svc_layercontext.c @@ -744,16 +744,6 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) { 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.