ref: e32f0bf2399bfba4cda1f04f56bc2b05a2d34354
parent: 76cc69f884a5261880396a3d93664455a1dff3ff
author: Jerome Jiang <jianj@google.com>
date: Wed Jun 6 19:02:26 EDT 2018
vp9 svc: add control to set using second temporal ref. Bump up ABI version. Change-Id: I4498d7ea4ed72994c5f847aa98e75b0150dd7f82
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1318,7 +1318,7 @@
assert(yv12 != NULL);
if (!(is_one_pass_cbr_svc(cpi) && cpi->svc.spatial_layer_id) ||
- cpi->svc.use_longterm_ref_current_layer) {
+ cpi->svc.use_gf_temporal_ref_current_layer) {
// For now, GOLDEN will not be used for non-zero spatial layers, since
// it may not be a temporal reference.
yv12_g = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -1540,7 +1540,7 @@
thresh_svc_skip_golden = 1000;
if (!cpi->use_svc ||
- (svc->use_longterm_ref_current_layer &&
+ (svc->use_gf_temporal_ref_current_layer &&
!svc->layer_context[svc->temporal_layer_id].is_key_frame))
gf_is_longterm_ref = 1;
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -1599,7 +1599,7 @@
// If second (long term) temporal reference is used for SVC,
// update the golden frame counter, only for base temporal layer.
- if (cpi->use_svc && cpi->svc.use_longterm_ref_current_layer &&
+ if (cpi->use_svc && cpi->svc.use_gf_temporal_ref_current_layer &&
cpi->svc.temporal_layer_id == 0) {
if (cpi->refresh_golden_frame)
rc->frames_since_golden = 0;
@@ -1875,7 +1875,7 @@
// 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
// layer frame.
- if (svc->use_longterm_ref_current_layer && svc->temporal_layer_id == 0) {
+ 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.
@@ -1883,7 +1883,7 @@
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_longterm_ref[index].idx;
+ 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
@@ -1895,7 +1895,7 @@
cpi->ext_refresh_golden_frame = 1;
rc->gfu_boost = DEFAULT_GF_BOOST;
}
- } else if (!svc->use_longterm_ref) {
+ } else if (!svc->use_gf_temporal_ref) {
rc->frames_till_gf_update_due = INT_MAX;
rc->baseline_gf_interval = INT_MAX;
}
--- a/vp9/encoder/vp9_svc_layercontext.c
+++ b/vp9/encoder/vp9_svc_layercontext.c
@@ -33,8 +33,8 @@
svc->force_zero_mode_spatial_ref = 0;
svc->use_base_mv = 0;
svc->use_partition_reuse = 0;
- svc->use_longterm_ref = 1;
- svc->use_longterm_ref_current_layer = 0;
+ svc->use_gf_temporal_ref = 1;
+ svc->use_gf_temporal_ref_current_layer = 0;
svc->scaled_temp_is_alloc = 0;
svc->scaled_one_half = 0;
svc->current_superframe = 0;
@@ -62,10 +62,10 @@
}
svc->max_consec_drop = INT_MAX;
- svc->buffer_longterm_ref[1].idx = 7;
- svc->buffer_longterm_ref[0].idx = 6;
- svc->buffer_longterm_ref[1].is_used = 0;
- svc->buffer_longterm_ref[0].is_used = 0;
+ svc->buffer_gf_temporal_ref[1].idx = 7;
+ svc->buffer_gf_temporal_ref[0].idx = 6;
+ svc->buffer_gf_temporal_ref[1].is_used = 0;
+ svc->buffer_gf_temporal_ref[0].is_used = 0;
if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) {
if (vpx_realloc_frame_buffer(&cpi->svc.empty_frame.img, SMALL_FRAME_WIDTH,
@@ -716,40 +716,40 @@
}
}
- if (cpi->lst_fb_idx == svc->buffer_longterm_ref[0].idx ||
- cpi->gld_fb_idx == svc->buffer_longterm_ref[0].idx ||
- cpi->alt_fb_idx == svc->buffer_longterm_ref[0].idx)
- svc->buffer_longterm_ref[0].is_used = 1;
- if (cpi->lst_fb_idx == svc->buffer_longterm_ref[1].idx ||
- cpi->gld_fb_idx == svc->buffer_longterm_ref[1].idx ||
- cpi->alt_fb_idx == svc->buffer_longterm_ref[1].idx)
- svc->buffer_longterm_ref[1].is_used = 1;
+ if (cpi->lst_fb_idx == svc->buffer_gf_temporal_ref[0].idx ||
+ cpi->gld_fb_idx == svc->buffer_gf_temporal_ref[0].idx ||
+ cpi->alt_fb_idx == svc->buffer_gf_temporal_ref[0].idx)
+ svc->buffer_gf_temporal_ref[0].is_used = 1;
+ if (cpi->lst_fb_idx == svc->buffer_gf_temporal_ref[1].idx ||
+ cpi->gld_fb_idx == svc->buffer_gf_temporal_ref[1].idx ||
+ cpi->alt_fb_idx == svc->buffer_gf_temporal_ref[1].idx)
+ svc->buffer_gf_temporal_ref[1].is_used = 1;
// For the fixed (non-flexible/bypass) SVC mode:
// If long term temporal reference is enabled at the sequence level
- // (use_longterm_ref == 1), and inter_layer is disabled (on inter-frames),
+ // (use_gf_temporal_ref == 1), and inter_layer is disabled (on inter-frames),
// we can use golden as a second temporal reference
// (since the spatial/inter-layer reference is disabled).
- // We check that the fb_idx for this reference (buffer_longterm_ref.idx) is
+ // We check that the fb_idx for this reference (buffer_gf_temporal_ref.idx) is
// unused (slot 7 and 6 should be available for 3-3 layer system).
// For now usage of this second temporal reference will only be used for
// highest and next to highest spatial layer (i.e., top and middle layer for
// 3 spatial layers).
- svc->use_longterm_ref_current_layer = 0;
- if (svc->use_longterm_ref && !svc->buffer_longterm_ref[0].is_used &&
- !svc->buffer_longterm_ref[1].is_used &&
+ svc->use_gf_temporal_ref_current_layer = 0;
+ if (svc->use_gf_temporal_ref && !svc->buffer_gf_temporal_ref[0].is_used &&
+ !svc->buffer_gf_temporal_ref[1].is_used &&
svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS &&
svc->disable_inter_layer_pred != INTER_LAYER_PRED_ON &&
svc->number_spatial_layers <= 3 && svc->number_temporal_layers <= 3 &&
svc->spatial_layer_id >= svc->number_spatial_layers - 2) {
// Enable the second (long-term) temporal reference at the frame-level.
- svc->use_longterm_ref_current_layer = 1;
+ 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_longterm_ref[index].idx;
+ 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;
@@ -1032,7 +1032,7 @@
svc->temporal_layer_id);
}
}
- } else if (svc->use_longterm_ref_current_layer &&
+ } else if (svc->use_gf_temporal_ref_current_layer &&
!svc->layer_context[svc->temporal_layer_id].is_key_frame) {
// If the usage of golden as second long term reference is enabled for this
// layer, then temporal_layer_id of that reference must be base temporal
--- a/vp9/encoder/vp9_svc_layercontext.h
+++ b/vp9/encoder/vp9_svc_layercontext.h
@@ -103,11 +103,11 @@
int alt_fb_idx[VPX_MAX_LAYERS];
int force_zero_mode_spatial_ref;
// Sequence level flag to enable second (long term) temporal reference.
- int use_longterm_ref;
+ int use_gf_temporal_ref;
// Frame level flag to enable second (long term) temporal reference.
- int use_longterm_ref_current_layer;
+ int use_gf_temporal_ref_current_layer;
// Allow second reference for at most 2 top highest resolution layers.
- BUFFER_LONGTERM_REF buffer_longterm_ref[2];
+ BUFFER_LONGTERM_REF buffer_gf_temporal_ref[2];
int current_superframe;
int non_reference_frame;
int use_base_mv;
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -1543,6 +1543,14 @@
return VPX_CODEC_OK;
}
+static vpx_codec_err_t ctrl_set_svc_gf_temporal_ref(vpx_codec_alg_priv_t *ctx,
+ va_list args) {
+ VP9_COMP *const cpi = ctx->cpi;
+ const unsigned int data = va_arg(args, unsigned int);
+ cpi->svc.use_gf_temporal_ref = data;
+ return VPX_CODEC_OK;
+}
+
static vpx_codec_err_t ctrl_register_cx_callback(vpx_codec_alg_priv_t *ctx,
va_list args) {
vpx_codec_priv_output_cx_pkt_cb_pair_t *cbp =
@@ -1628,6 +1636,7 @@
{ VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test },
{ VP9E_SET_SVC_INTER_LAYER_PRED, ctrl_set_svc_inter_layer_pred },
{ VP9E_SET_SVC_FRAME_DROP_LAYER, ctrl_set_svc_frame_drop_layer },
+ { VP9E_SET_SVC_GF_TEMPORAL_REF, ctrl_set_svc_gf_temporal_ref },
// Getters
{ VP8E_GET_LAST_QUANTIZER, ctrl_get_quantizer },
--- a/vpx/vp8cx.h
+++ b/vpx/vp8cx.h
@@ -627,6 +627,16 @@
* Supported in codecs: VP9
*/
VP9E_GET_SVC_REF_FRAME_CONFIG,
+
+ /*!\brief Codec control function to enable/disable use of golden reference as
+ * a second temporal reference for SVC. Only used when inter-layer prediction
+ * is disabled on INTER frames.
+ *
+ * 0: Off, 1: Enabled (default)
+ *
+ * Supported in codecs: VP9
+ */
+ VP9E_SET_SVC_GF_TEMPORAL_REF,
};
/*!\brief vpx 1-D scaling mode
@@ -946,6 +956,9 @@
VPX_CTRL_USE_TYPE(VP9E_GET_SVC_REF_FRAME_CONFIG, vpx_svc_ref_frame_config_t *)
#define VPX_CTRL_VP9E_GET_SVC_REF_FRAME_CONFIG
+
+VPX_CTRL_USE_TYPE(VP9E_SET_SVC_GF_TEMPORAL_REF, unsigned int)
+#define VPX_CTRL_VP9E_SET_SVC_GF_TEMPORAL_REF
/*!\endcond */
/*! @} - end defgroup vp8_encoder */
--- a/vpx/vpx_encoder.h
+++ b/vpx/vpx_encoder.h
@@ -63,7 +63,7 @@
* fields to structures
*/
#define VPX_ENCODER_ABI_VERSION \
- (12 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/
+ (13 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/
/*! \brief Encoder capabilities bitfield
*