Add check for svc input scaling_factor_den Spatial scaling factors should be such that scaling_factor_den[sl] >= scaling_factor_num[sl]. Return AOM_CODEC_INVALID_PARAM if this is not satisfied. Bug: 503171639 Change-Id: I63c9df9c8f0b6f1516547e6b5eafb64c7b3e5c85
diff --git a/aom/aomcx.h b/aom/aomcx.h index 8d14b41..7c7ad7b 100644 --- a/aom/aomcx.h +++ b/aom/aomcx.h
@@ -1843,10 +1843,14 @@ * \li When \em not using #AV1E_SET_SVC_REF_FRAME_CONFIG: [1, 3] */ int number_temporal_layers; - int max_quantizers[AOM_MAX_LAYERS]; /**< Max Q for each layer */ - int min_quantizers[AOM_MAX_LAYERS]; /**< Min Q for each layer */ - int scaling_factor_num[AOM_MAX_SS_LAYERS]; /**< Scaling factor-numerator */ - int scaling_factor_den[AOM_MAX_SS_LAYERS]; /**< Scaling factor-denominator */ + int max_quantizers[AOM_MAX_LAYERS]; /**< Max Q for each layer */ + int min_quantizers[AOM_MAX_LAYERS]; /**< Min Q for each layer */ + /*! Scaling factor-numerator */ + int scaling_factor_num[AOM_MAX_SS_LAYERS]; + /*! Scaling factor-denominator: must be greater than or equal to the + * scaling_factor_num[]. + */ + int scaling_factor_den[AOM_MAX_SS_LAYERS]; /*! Target bitrate for each layer, in kilobits per second */ int layer_target_bitrate[AOM_MAX_LAYERS]; /*! Frame rate factor for each temporal layer */
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c index 120f6f7..3b63df5 100644 --- a/av1/av1_cx_iface.c +++ b/av1/av1_cx_iface.c
@@ -4142,8 +4142,14 @@ LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer]; lc->max_q = params->max_quantizers[layer]; lc->min_q = params->min_quantizers[layer]; - lc->scaling_factor_num = AOMMAX(1, params->scaling_factor_num[sl]); - lc->scaling_factor_den = AOMMAX(1, params->scaling_factor_den[sl]); + // spatial scaling (scaling_factor_num[]/den[]) is always to a lower + // resolution, so den must be >= num. + if (params->scaling_factor_den[sl] < params->scaling_factor_num[sl]) { + return AOM_CODEC_INVALID_PARAM; + } else { + lc->scaling_factor_num = AOMMAX(1, params->scaling_factor_num[sl]); + lc->scaling_factor_den = AOMMAX(1, params->scaling_factor_den[sl]); + } const int layer_target_bitrate = params->layer_target_bitrate[layer]; if (layer_target_bitrate > INT_MAX / 1000) { lc->layer_target_bitrate = INT_MAX;
diff --git a/test/encode_api_test.cc b/test/encode_api_test.cc index 239d29a..4b75ece 100644 --- a/test/encode_api_test.cc +++ b/test/encode_api_test.cc
@@ -171,6 +171,25 @@ svc_params.framerate_factor[1] = 1; svc_params.layer_target_bitrate[0] = 60 * cfg.rc_target_bitrate / 100; svc_params.layer_target_bitrate[1] = cfg.rc_target_bitrate; + // Check scale factors. + for (int i = 0; i < AOM_MAX_SS_LAYERS; i++) { + svc_params.scaling_factor_num[i] = 1; + svc_params.scaling_factor_den[i] = 1; + } + svc_params.number_spatial_layers = 2; + svc_params.number_temporal_layers = 1; + // Set invalid factors. + svc_params.scaling_factor_num[0] = 2; + svc_params.scaling_factor_den[0] = 1; + EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_SVC_PARAMS, &svc_params), + AOM_CODEC_INVALID_PARAM); + // Set valid factors. + svc_params.scaling_factor_num[0] = 1; + svc_params.scaling_factor_den[0] = 2; + EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_SVC_PARAMS, &svc_params), + AOM_CODEC_OK); + svc_params.scaling_factor_num[0] = 1; + svc_params.scaling_factor_den[0] = 1; for (const bool use_flexible_mode : { false, true }) { if (use_flexible_mode) { aom_svc_ref_frame_config_t ref_frame_config = {};