From 7266bedc041b4bbc3e823226f14d70e97892d959 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 1 Oct 2015 15:46:06 -0700 Subject: [PATCH] Add first_spatial_layer_to_encode to SVC. Use the existing VP9_SET_SVC control to set the first spatial layer to encode. Since we loop over all spatial layers inside the encoder, the setting of spatial_layer_id via VP9_SET_SVC has no relevance. Use it instead to set the first_spatial_layer_to_encode, which allows an application to skip encoding lower layer(s). Change only affects the 1 pass CBR SVC. Change-Id: I5d63ab713c3e250fdf42c637f38d5ec8f60cd1fb --- vp9/encoder/vp9_encoder.c | 3 ++- vp9/encoder/vp9_ratectrl.c | 2 +- vp9/encoder/vp9_svc_layercontext.c | 1 + vp9/encoder/vp9_svc_layercontext.h | 1 + vp9/vp9_cx_iface.c | 9 ++++++--- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index f9486e843..5b75d672f 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -4279,7 +4279,8 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, // non-zero spatial layer, it should not be an intra picture. // TODO(Won Kap): this needs to change if per-layer intra frame is // allowed. - if ((source->flags & VPX_EFLAG_FORCE_KF) && cpi->svc.spatial_layer_id) { + if ((source->flags & VPX_EFLAG_FORCE_KF) && + cpi->svc.spatial_layer_id > cpi->svc.first_spatial_layer_to_encode) { source->flags &= ~(unsigned int)(VPX_EFLAG_FORCE_KF); } diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 20e72758e..5f308e117 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -1595,7 +1595,7 @@ void vp9_rc_get_svc_params(VP9_COMP *cpi) { cpi->ref_frame_flags &= (~VP9_ALT_FLAG); } else if (is_one_pass_cbr_svc(cpi)) { LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer]; - if (cpi->svc.spatial_layer_id == 0) { + if (cpi->svc.spatial_layer_id == cpi->svc.first_spatial_layer_to_encode) { lc->is_key_frame = 0; } else { lc->is_key_frame = diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c index 25209f4b1..8a6818c86 100644 --- a/vp9/encoder/vp9_svc_layercontext.c +++ b/vp9/encoder/vp9_svc_layercontext.c @@ -30,6 +30,7 @@ void vp9_init_layer_context(VP9_COMP *const cpi) { svc->spatial_layer_id = 0; svc->temporal_layer_id = 0; + svc->first_spatial_layer_to_encode = 0; if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) { if (vpx_realloc_frame_buffer(&cpi->svc.empty_frame.img, diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h index 8feab2968..694b5abdc 100644 --- a/vp9/encoder/vp9_svc_layercontext.h +++ b/vp9/encoder/vp9_svc_layercontext.h @@ -55,6 +55,7 @@ typedef struct { int number_temporal_layers; int spatial_layer_to_encode; + int first_spatial_layer_to_encode; // Workaround for multiple frame contexts enum { diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index a253c0692..5ad713c58 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -1372,17 +1372,20 @@ static vpx_codec_err_t ctrl_set_svc_layer_id(vpx_codec_alg_priv_t *ctx, VP9_COMP *const cpi = (VP9_COMP *)ctx->cpi; SVC *const svc = &cpi->svc; - svc->spatial_layer_id = data->spatial_layer_id; + svc->first_spatial_layer_to_encode = data->spatial_layer_id; svc->temporal_layer_id = data->temporal_layer_id; // Checks on valid layer_id input. if (svc->temporal_layer_id < 0 || svc->temporal_layer_id >= (int)ctx->cfg.ts_number_layers) { return VPX_CODEC_INVALID_PARAM; } - if (svc->spatial_layer_id < 0 || - svc->spatial_layer_id >= (int)ctx->cfg.ss_number_layers) { + if (svc->first_spatial_layer_to_encode < 0 || + svc->first_spatial_layer_to_encode >= (int)ctx->cfg.ss_number_layers) { return VPX_CODEC_INVALID_PARAM; } + // First spatial layer to encode not implemented for two-pass. + if (is_two_pass_svc(cpi) && svc->first_spatial_layer_to_encode > 0) + return VPX_CODEC_INVALID_PARAM; return VPX_CODEC_OK; } -- 2.40.0