summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
Diffstat (limited to 'vp9')
-rw-r--r--vp9/encoder/vp9_encoder.c34
-rw-r--r--vp9/encoder/vp9_svc_layercontext.c1
-rw-r--r--vp9/encoder/vp9_svc_layercontext.h8
-rw-r--r--vp9/vp9_cx_iface.c9
4 files changed, 38 insertions, 14 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index 128574adf..a0feb8e92 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -3751,20 +3751,26 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
suppress_active_map(cpi);
- // For SVC on non-zero spatial layer: if the previous spatial layer
- // was dropped then disable the prediciton from this (scaled) reference.
- if (cpi->use_svc && cpi->svc.spatial_layer_id > 0 &&
- cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id - 1]) {
- MV_REFERENCE_FRAME ref_frame;
- static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
- VP9_ALT_FLAG };
- for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
- const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
- if (yv12 != NULL && (cpi->ref_frame_flags & flag_list[ref_frame])) {
- const struct scale_factors *const scale_fac =
- &cm->frame_refs[ref_frame - 1].sf;
- if (vp9_is_scaled(scale_fac))
- cpi->ref_frame_flags &= (~flag_list[ref_frame]);
+ // For SVC on non-zero spatial layer: check for disabling inter-layer
+ // (spatial) prediction, if svc.disable_inter_layer_pred is set.
+ // if the previous spatial layer was dropped then disable the prediction from
+ // this (scaled) reference.
+ if (cpi->use_svc && cpi->svc.spatial_layer_id > 0) {
+ if ((cpi->svc.disable_inter_layer_pred == INTER_LAYER_PRED_OFF_NONKEY &&
+ !cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame) ||
+ cpi->svc.disable_inter_layer_pred == INTER_LAYER_PRED_OFF ||
+ cpi->svc.drop_spatial_layer[cpi->svc.spatial_layer_id - 1]) {
+ MV_REFERENCE_FRAME ref_frame;
+ static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
+ VP9_ALT_FLAG };
+ for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
+ const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
+ if (yv12 != NULL && (cpi->ref_frame_flags & flag_list[ref_frame])) {
+ const struct scale_factors *const scale_fac =
+ &cm->frame_refs[ref_frame - 1].sf;
+ if (vp9_is_scaled(scale_fac))
+ cpi->ref_frame_flags &= (~flag_list[ref_frame]);
+ }
}
}
}
diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c
index 1957bb9ec..15888603e 100644
--- a/vp9/encoder/vp9_svc_layercontext.c
+++ b/vp9/encoder/vp9_svc_layercontext.c
@@ -38,6 +38,7 @@ void vp9_init_layer_context(VP9_COMP *const cpi) {
svc->current_superframe = 0;
svc->non_reference_frame = 0;
svc->skip_enhancement_layer = 0;
+ svc->disable_inter_layer_pred = INTER_LAYER_PRED_ON;
for (i = 0; i < REF_FRAMES; ++i) svc->ref_frame_index[i] = -1;
for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h
index 9bf62ee61..f18074743 100644
--- a/vp9/encoder/vp9_svc_layercontext.h
+++ b/vp9/encoder/vp9_svc_layercontext.h
@@ -19,6 +19,12 @@
extern "C" {
#endif
+typedef enum {
+ INTER_LAYER_PRED_ON,
+ INTER_LAYER_PRED_OFF,
+ INTER_LAYER_PRED_OFF_NONKEY
+} INTER_LAYER_PRED;
+
typedef struct {
RATE_CONTROL rc;
int target_bandwidth;
@@ -108,6 +114,8 @@ typedef struct SVC {
int last_layer_dropped[VPX_MAX_LAYERS];
int drop_spatial_layer[VPX_MAX_LAYERS];
+
+ INTER_LAYER_PRED disable_inter_layer_pred;
} SVC;
struct VP9_COMP;
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index a2c5dc83e..b33d578c4 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -1516,6 +1516,14 @@ static vpx_codec_err_t ctrl_set_svc_ref_frame_config(vpx_codec_alg_priv_t *ctx,
return VPX_CODEC_OK;
}
+static vpx_codec_err_t ctrl_set_svc_inter_layer_pred(vpx_codec_alg_priv_t *ctx,
+ va_list args) {
+ const int data = va_arg(args, int);
+ VP9_COMP *const cpi = ctx->cpi;
+ cpi->svc.disable_inter_layer_pred = 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 =
@@ -1599,6 +1607,7 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{ VP9E_SET_TARGET_LEVEL, ctrl_set_target_level },
{ VP9E_SET_ROW_MT, ctrl_set_row_mt },
{ VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test },
+ { VP9E_SET_SVC_INTER_LAYER_PRED, ctrl_set_svc_inter_layer_pred },
// Getters
{ VP8E_GET_LAST_QUANTIZER, ctrl_get_quantizer },