From e1cdb5029830350ec7c61dee290c08e79d7b4949 Mon Sep 17 00:00:00 2001 From: Marco Date: Sun, 30 Oct 2016 22:20:04 -0700 Subject: [PATCH] vp9-svc: Add checks to layer bitrates in vp9_spatial_svc_encoder. Add some checks to the layer bitrates passed in through the command line. Change-Id: I16f270035a6034d63313fe3019aa90dca9a3eefb --- vpx/src/svc_encodeframe.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/vpx/src/svc_encodeframe.c b/vpx/src/svc_encodeframe.c index fc0e0f65e..88b1531d8 100644 --- a/vpx/src/svc_encodeframe.c +++ b/vpx/src/svc_encodeframe.c @@ -183,7 +183,7 @@ static vpx_codec_err_t parse_layer_options_from_string(SvcContext *svc_ctx, svc_log(svc_ctx, SVC_LOG_ERROR, "svc: layer params type: %d %d values required, " "but only %d specified\n", - type, svc_ctx->spatial_layers, i); + type, num_layers, i); res = VPX_CODEC_INVALID_PARAM; } free(input_string); @@ -294,26 +294,30 @@ vpx_codec_err_t vpx_svc_set_options(SvcContext *svc_ctx, const char *options) { return VPX_CODEC_OK; } -void assign_layer_bitrates(const SvcContext *svc_ctx, - vpx_codec_enc_cfg_t *const enc_cfg) { +vpx_codec_err_t assign_layer_bitrates(const SvcContext *svc_ctx, + vpx_codec_enc_cfg_t *const enc_cfg) { int i; const SvcInternal_t *const si = get_const_svc_internal(svc_ctx); int sl, tl, spatial_layer_target; if (svc_ctx->temporal_layering_mode != 0) { if (si->bitrates[0] != 0) { - enc_cfg->rc_target_bitrate = 0; + unsigned int total_bitrate = 0; for (sl = 0; sl < svc_ctx->spatial_layers; ++sl) { - enc_cfg->rc_target_bitrate += - si->bitrates[sl * svc_ctx->temporal_layers + - svc_ctx->temporal_layers - 1]; + total_bitrate += si->bitrates[sl * svc_ctx->temporal_layers + + svc_ctx->temporal_layers - 1]; for (tl = 0; tl < svc_ctx->temporal_layers; ++tl) { enc_cfg->ss_target_bitrate[sl * svc_ctx->temporal_layers] += (unsigned int)si->bitrates[sl * svc_ctx->temporal_layers + tl]; enc_cfg->layer_target_bitrate[sl * svc_ctx->temporal_layers + tl] = si->bitrates[sl * svc_ctx->temporal_layers + tl]; + if (tl > 0 && (si->bitrates[sl * svc_ctx->temporal_layers + tl] <= + si->bitrates[sl * svc_ctx->temporal_layers + tl - 1])) + return VPX_CODEC_INVALID_PARAM; } } + if (total_bitrate != enc_cfg->rc_target_bitrate) + return VPX_CODEC_INVALID_PARAM; } else { float total = 0; float alloc_ratio[VPX_MAX_LAYERS] = { 0 }; @@ -350,12 +354,14 @@ void assign_layer_bitrates(const SvcContext *svc_ctx, } } else { if (si->bitrates[0] != 0) { - enc_cfg->rc_target_bitrate = 0; + unsigned int total_bitrate = 0; for (i = 0; i < svc_ctx->spatial_layers; ++i) { enc_cfg->ss_target_bitrate[i] = (unsigned int)si->bitrates[i]; enc_cfg->layer_target_bitrate[i] = (unsigned int)si->bitrates[i]; - enc_cfg->rc_target_bitrate += si->bitrates[i]; + total_bitrate += si->bitrates[i]; } + if (total_bitrate != enc_cfg->rc_target_bitrate) + return VPX_CODEC_INVALID_PARAM; } else { float total = 0; float alloc_ratio[VPX_MAX_LAYERS] = { 0 }; @@ -378,6 +384,7 @@ void assign_layer_bitrates(const SvcContext *svc_ctx, } } } + return VPX_CODEC_OK; } vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx, @@ -464,7 +471,15 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx, (int)VPX_MAX_LAYERS); return VPX_CODEC_INVALID_PARAM; } - assign_layer_bitrates(svc_ctx, enc_cfg); + res = assign_layer_bitrates(svc_ctx, enc_cfg); + if (res != VPX_CODEC_OK) { + svc_log(svc_ctx, SVC_LOG_ERROR, + "layer bitrates incorrect: \n" + "1) spatial layer bitrates should sum up to target \n" + "2) temporal layer bitrates should be increasing within \n" + "a spatial layer \n"); + return VPX_CODEC_INVALID_PARAM; + } #if CONFIG_SPATIAL_SVC for (i = 0; i < svc_ctx->spatial_layers; ++i)