Validate operating point for target-seq-level-idx
Return AOM_CODEC_INVALID_PARAM if operating_point_idx is invalid.
Also use TEST instead of TEST_P with LevelTest.TestTargetLevelApi
because that test doesn't depend on any parameters of LevelTest.
Change-Id: Ib35d1a2e73ed5785edc715868b60d1dfe1770f56
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index c20bfdf..d655b65 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -2464,10 +2464,15 @@
const int val = CAST(AV1E_SET_TARGET_SEQ_LEVEL_IDX, args);
const int level = val % 100;
const int operating_point_idx = val / 100;
- if (operating_point_idx >= 0 &&
- operating_point_idx < MAX_NUM_OPERATING_POINTS) {
- extra_cfg.target_seq_level_idx[operating_point_idx] = (AV1_LEVEL)level;
+ if (operating_point_idx < 0 ||
+ operating_point_idx >= MAX_NUM_OPERATING_POINTS) {
+ char *const err_string = ctx->ppi->error.detail;
+ snprintf(err_string, ARG_ERR_MSG_MAX_LEN,
+ "Invalid operating point index: %d", operating_point_idx);
+ ctx->base.err_detail = err_string;
+ return AOM_CODEC_INVALID_PARAM;
}
+ extra_cfg.target_seq_level_idx[operating_point_idx] = (AV1_LEVEL)level;
return update_extra_cfg(ctx, &extra_cfg);
}
@@ -4053,8 +4058,12 @@
const int val = arg_parse_int_helper(&arg, err_string);
const int level = val % 100;
const int operating_point_idx = val / 100;
- if (operating_point_idx >= 0 &&
- operating_point_idx < MAX_NUM_OPERATING_POINTS) {
+ if (operating_point_idx < 0 ||
+ operating_point_idx >= MAX_NUM_OPERATING_POINTS) {
+ snprintf(err_string, ARG_ERR_MSG_MAX_LEN,
+ "Invalid operating point index: %d", operating_point_idx);
+ err = AOM_CODEC_INVALID_PARAM;
+ } else {
extra_cfg.target_seq_level_idx[operating_point_idx] = (AV1_LEVEL)level;
}
} else if (arg_match_helper(&arg,
diff --git a/test/level_test.cc b/test/level_test.cc
index 7ae1a75..cc79926 100644
--- a/test/level_test.cc
+++ b/test/level_test.cc
@@ -9,6 +9,7 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include <memory>
+#include <string>
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
@@ -78,8 +79,8 @@
int level_[32];
};
-TEST_P(LevelTest, TestTargetLevelApi) {
- static aom_codec_iface_t *codec = aom_codec_av1_cx();
+TEST(LevelTest, TestTargetLevelApi) {
+ aom_codec_iface_t *codec = aom_codec_av1_cx();
aom_codec_ctx_t enc;
aom_codec_enc_cfg_t cfg;
EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(codec, &cfg, 0));
@@ -87,10 +88,10 @@
for (int operating_point = 0; operating_point <= 32; ++operating_point) {
for (int level = 0; level <= 32; ++level) {
const int target_level = operating_point * 100 + level;
- if ((level < (CONFIG_CWG_C013 ? 28 : 20) && level != 2 && level != 3 &&
- level != 6 && level != 7 && level != 10 && level != 11) ||
- level == kLevelMax || level == kLevelKeepStats ||
- operating_point > 31) {
+ if (operating_point <= 31 &&
+ ((level < (CONFIG_CWG_C013 ? 28 : 20) && level != 2 && level != 3 &&
+ level != 6 && level != 7 && level != 10 && level != 11) ||
+ level == kLevelMax || level == kLevelKeepStats)) {
EXPECT_EQ(AOM_CODEC_OK,
AOM_CODEC_CONTROL_TYPECHECKED(
&enc, AV1E_SET_TARGET_SEQ_LEVEL_IDX, target_level));
@@ -104,6 +105,23 @@
EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
}
+TEST(LevelTest, InvalidOperatingPointIndexErrorDetail) {
+ aom_codec_iface_t *codec = aom_codec_av1_cx();
+ aom_codec_ctx_t enc;
+ aom_codec_enc_cfg_t cfg;
+ EXPECT_EQ(aom_codec_enc_config_default(codec, &cfg, 0), AOM_CODEC_OK);
+ EXPECT_EQ(aom_codec_enc_init(&enc, codec, &cfg, 0), AOM_CODEC_OK);
+ EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_TARGET_SEQ_LEVEL_IDX, 3219),
+ AOM_CODEC_INVALID_PARAM);
+ EXPECT_EQ(aom_codec_error_detail(&enc),
+ std::string("Invalid operating point index: 32"));
+ EXPECT_EQ(aom_codec_set_option(&enc, "target-seq-level-idx", "3319"),
+ AOM_CODEC_INVALID_PARAM);
+ EXPECT_EQ(aom_codec_error_detail(&enc),
+ std::string("Invalid operating point index: 33"));
+ EXPECT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
+}
+
TEST_P(LevelTest, TestTargetLevel19) {
std::unique_ptr<libaom_test::VideoSource> video;
video.reset(new libaom_test::Y4mVideoSource("park_joy_90p_8_420.y4m", 0, 10));