|  | /* | 
|  | * Copyright (c) 2021, Alliance for Open Media. All rights reserved. | 
|  | * | 
|  | * This source code is subject to the terms of the BSD 2 Clause License and | 
|  | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License | 
|  | * was not distributed with this source code in the LICENSE file, you can | 
|  | * obtain it at www.aomedia.org/license/software. If the Alliance for Open | 
|  | * Media Patent License 1.0 was not distributed with this source code in the | 
|  | * PATENTS file, you can obtain it at www.aomedia.org/license/patent. | 
|  | */ | 
|  |  | 
|  | #include <cstring> | 
|  | #include <tuple> | 
|  |  | 
|  | #include "aom/aom_codec.h" | 
|  | #include "aom/aom_decoder.h" | 
|  | #include "aom/aom_encoder.h" | 
|  | #include "aom/aomcx.h" | 
|  | #include "aom/aomdx.h" | 
|  | #include "config/aom_config.h" | 
|  | #include "gtest/gtest.h" | 
|  |  | 
|  | namespace { | 
|  | typedef std::tuple<const char *, const char *> KeyValParam; | 
|  |  | 
|  | class BaseKeyValAPI : public testing::Test { | 
|  | public: | 
|  | void SetUp() override { | 
|  | #if CONFIG_AV1_ENCODER | 
|  | aom_codec_iface_t *iface_cx = aom_codec_av1_cx(); | 
|  | aom_codec_enc_cfg_t enc_cfg; | 
|  | #if CONFIG_REALTIME_ONLY | 
|  | const int usage = 1; | 
|  | #else | 
|  | const int usage = 0; | 
|  | #endif | 
|  | EXPECT_EQ(AOM_CODEC_OK, | 
|  | aom_codec_enc_config_default(iface_cx, &enc_cfg, usage)); | 
|  | EXPECT_EQ(AOM_CODEC_OK, | 
|  | aom_codec_enc_init(&enc_, iface_cx, &enc_cfg, usage)); | 
|  | #endif | 
|  | #if CONFIG_AV1_DECODER | 
|  | aom_codec_iface_t *iface_dx = aom_codec_av1_dx(); | 
|  | aom_codec_dec_cfg_t dec_cfg = { 0, 0, 0, !FORCE_HIGHBITDEPTH_DECODING }; | 
|  |  | 
|  | EXPECT_EQ(AOM_CODEC_OK, aom_codec_dec_init(&dec_, iface_dx, &dec_cfg, 0)); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | void TearDown() override { | 
|  | #if CONFIG_AV1_ENCODER | 
|  | EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc_)); | 
|  | #endif | 
|  | #if CONFIG_AV1_DECODER | 
|  | EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&dec_)); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | protected: | 
|  | #if CONFIG_AV1_ENCODER | 
|  | aom_codec_ctx_t enc_; | 
|  | #endif | 
|  | #if CONFIG_AV1_DECODER | 
|  | aom_codec_ctx_t dec_; | 
|  | #endif | 
|  | }; | 
|  |  | 
|  | // Tests on encoder options. | 
|  | // Need to add ones for the decoder in the future if it is also supported in the | 
|  | // key & value API. | 
|  | #if CONFIG_AV1_ENCODER | 
|  | class EncValidTest : public BaseKeyValAPI, | 
|  | public testing::WithParamInterface<KeyValParam> {}; | 
|  | class EncInvalidTest : public BaseKeyValAPI, | 
|  | public testing::WithParamInterface<KeyValParam> {}; | 
|  |  | 
|  | TEST_P(EncValidTest, Valid) { | 
|  | const char *key = std::get<0>(GetParam()); | 
|  | const char *val = std::get<1>(GetParam()); | 
|  | EXPECT_EQ(AOM_CODEC_OK, aom_codec_set_option(&enc_, key, val)); | 
|  | } | 
|  |  | 
|  | TEST_P(EncInvalidTest, NullArg) { | 
|  | const char *key = std::get<0>(GetParam()); | 
|  | const char *val = std::get<1>(GetParam()); | 
|  | EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_set_option(nullptr, key, val)); | 
|  | EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_set_option(&enc_, nullptr, val)); | 
|  | EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_set_option(&enc_, key, nullptr)); | 
|  | } | 
|  |  | 
|  | TEST_P(EncInvalidTest, InvalidParam) { | 
|  | const char *key = std::get<0>(GetParam()); | 
|  | const char *val = std::get<1>(GetParam()); | 
|  | EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_set_option(&enc_, key, val)); | 
|  | ASSERT_NE(aom_codec_error_detail(&enc_), nullptr); | 
|  | EXPECT_GT(strlen(aom_codec_error_detail(&enc_)), 0u); | 
|  | } | 
|  |  | 
|  | // No test for ratio / list for now since the API does not support any of the | 
|  | // parameters of these type. | 
|  | // The string type typically involves reading a path/file, which brings | 
|  | // potential fails. | 
|  | const KeyValParam enc_valid_params[] = { | 
|  | std::make_tuple("auto-intra-tools-off", "1"),  // uint | 
|  | std::make_tuple("min-gf-interval", "10"),      // uint | 
|  | std::make_tuple("min-partition-size", "4"),    // int | 
|  | std::make_tuple("tune", "psnr"),               // enum | 
|  | }; | 
|  |  | 
|  | const KeyValParam enc_invalid_params[] = { | 
|  | // no match | 
|  | std::make_tuple("a-b-c", "10"), | 
|  | // uint | 
|  | std::make_tuple("min-gf-interval", "-1"), | 
|  | std::make_tuple("min-gf-interval", "1.1"), | 
|  | std::make_tuple("min-gf-interval", "abc"), | 
|  | // int | 
|  | std::make_tuple("min-partition-size", "1.1"), | 
|  | std::make_tuple("min-partition-size", "abc"), | 
|  | // enum | 
|  | std::make_tuple("tune", "PsnR1"), | 
|  | // out of range | 
|  | std::make_tuple("cq-level", "1000"), | 
|  | }; | 
|  |  | 
|  | INSTANTIATE_TEST_SUITE_P(KeyValAPI, EncValidTest, | 
|  | testing::ValuesIn(enc_valid_params)); | 
|  |  | 
|  | INSTANTIATE_TEST_SUITE_P(KeyValAPI, EncInvalidTest, | 
|  | testing::ValuesIn(enc_invalid_params)); | 
|  | #endif  // CONFIG_AV1_ENCODER | 
|  |  | 
|  | }  // namespace |