diff options
Diffstat (limited to 'vp9')
-rw-r--r-- | vp9/encoder/vp9_encoder.c | 34 | ||||
-rw-r--r-- | vp9/encoder/vp9_svc_layercontext.c | 1 | ||||
-rw-r--r-- | vp9/encoder/vp9_svc_layercontext.h | 8 | ||||
-rw-r--r-- | vp9/vp9_cx_iface.c | 9 |
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 }, |