xref: /aosp_15_r20/external/libaom/test/level_test.cc (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2019, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker  *
4*77c1e3ccSAndroid Build Coastguard Worker  * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker  * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker  * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker  */
11*77c1e3ccSAndroid Build Coastguard Worker #include <memory>
12*77c1e3ccSAndroid Build Coastguard Worker #include <string>
13*77c1e3ccSAndroid Build Coastguard Worker 
14*77c1e3ccSAndroid Build Coastguard Worker #include "gtest/gtest.h"
15*77c1e3ccSAndroid Build Coastguard Worker 
16*77c1e3ccSAndroid Build Coastguard Worker #include "test/codec_factory.h"
17*77c1e3ccSAndroid Build Coastguard Worker #include "test/encode_test_driver.h"
18*77c1e3ccSAndroid Build Coastguard Worker #include "test/i420_video_source.h"
19*77c1e3ccSAndroid Build Coastguard Worker #include "test/util.h"
20*77c1e3ccSAndroid Build Coastguard Worker #include "test/y4m_video_source.h"
21*77c1e3ccSAndroid Build Coastguard Worker #include "test/yuv_video_source.h"
22*77c1e3ccSAndroid Build Coastguard Worker 
23*77c1e3ccSAndroid Build Coastguard Worker namespace {
24*77c1e3ccSAndroid Build Coastguard Worker const int kLevelMin = 0;
25*77c1e3ccSAndroid Build Coastguard Worker const int kLevelMax = 31;
26*77c1e3ccSAndroid Build Coastguard Worker const int kLevelKeepStats = 32;
27*77c1e3ccSAndroid Build Coastguard Worker // Speed settings tested
28*77c1e3ccSAndroid Build Coastguard Worker static const int kCpuUsedVectors[] = {
29*77c1e3ccSAndroid Build Coastguard Worker   1,
30*77c1e3ccSAndroid Build Coastguard Worker   2,
31*77c1e3ccSAndroid Build Coastguard Worker   3,
32*77c1e3ccSAndroid Build Coastguard Worker   4,
33*77c1e3ccSAndroid Build Coastguard Worker };
34*77c1e3ccSAndroid Build Coastguard Worker 
35*77c1e3ccSAndroid Build Coastguard Worker class LevelTest
36*77c1e3ccSAndroid Build Coastguard Worker     : public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode, int>,
37*77c1e3ccSAndroid Build Coastguard Worker       public ::libaom_test::EncoderTest {
38*77c1e3ccSAndroid Build Coastguard Worker  protected:
LevelTest()39*77c1e3ccSAndroid Build Coastguard Worker   LevelTest()
40*77c1e3ccSAndroid Build Coastguard Worker       : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
41*77c1e3ccSAndroid Build Coastguard Worker         cpu_used_(GET_PARAM(2)), target_level_(31) {}
42*77c1e3ccSAndroid Build Coastguard Worker 
43*77c1e3ccSAndroid Build Coastguard Worker   ~LevelTest() override = default;
44*77c1e3ccSAndroid Build Coastguard Worker 
SetUp()45*77c1e3ccSAndroid Build Coastguard Worker   void SetUp() override {
46*77c1e3ccSAndroid Build Coastguard Worker     InitializeConfig(encoding_mode_);
47*77c1e3ccSAndroid Build Coastguard Worker     if (encoding_mode_ != ::libaom_test::kRealTime) {
48*77c1e3ccSAndroid Build Coastguard Worker       cfg_.g_lag_in_frames = 5;
49*77c1e3ccSAndroid Build Coastguard Worker     } else {
50*77c1e3ccSAndroid Build Coastguard Worker       cfg_.rc_buf_sz = 1000;
51*77c1e3ccSAndroid Build Coastguard Worker       cfg_.rc_buf_initial_sz = 500;
52*77c1e3ccSAndroid Build Coastguard Worker       cfg_.rc_buf_optimal_sz = 600;
53*77c1e3ccSAndroid Build Coastguard Worker     }
54*77c1e3ccSAndroid Build Coastguard Worker   }
55*77c1e3ccSAndroid Build Coastguard Worker 
PreEncodeFrameHook(::libaom_test::VideoSource * video,::libaom_test::Encoder * encoder)56*77c1e3ccSAndroid Build Coastguard Worker   void PreEncodeFrameHook(::libaom_test::VideoSource *video,
57*77c1e3ccSAndroid Build Coastguard Worker                           ::libaom_test::Encoder *encoder) override {
58*77c1e3ccSAndroid Build Coastguard Worker     if (video->frame() == 0) {
59*77c1e3ccSAndroid Build Coastguard Worker       encoder->Control(AOME_SET_CPUUSED, cpu_used_);
60*77c1e3ccSAndroid Build Coastguard Worker       encoder->Control(AV1E_SET_TARGET_SEQ_LEVEL_IDX, target_level_);
61*77c1e3ccSAndroid Build Coastguard Worker       if (encoding_mode_ != ::libaom_test::kRealTime) {
62*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
63*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7);
64*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AOME_SET_ARNR_STRENGTH, 5);
65*77c1e3ccSAndroid Build Coastguard Worker       }
66*77c1e3ccSAndroid Build Coastguard Worker     }
67*77c1e3ccSAndroid Build Coastguard Worker 
68*77c1e3ccSAndroid Build Coastguard Worker     int num_operating_points;
69*77c1e3ccSAndroid Build Coastguard Worker     encoder->Control(AV1E_GET_NUM_OPERATING_POINTS, &num_operating_points);
70*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_EQ(num_operating_points, 1);
71*77c1e3ccSAndroid Build Coastguard Worker     encoder->Control(AV1E_GET_SEQ_LEVEL_IDX, level_);
72*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_LE(level_[0], kLevelMax);
73*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_GE(level_[0], kLevelMin);
74*77c1e3ccSAndroid Build Coastguard Worker   }
75*77c1e3ccSAndroid Build Coastguard Worker 
76*77c1e3ccSAndroid Build Coastguard Worker   libaom_test::TestMode encoding_mode_;
77*77c1e3ccSAndroid Build Coastguard Worker   int cpu_used_;
78*77c1e3ccSAndroid Build Coastguard Worker   int target_level_;
79*77c1e3ccSAndroid Build Coastguard Worker   int level_[32];
80*77c1e3ccSAndroid Build Coastguard Worker };
81*77c1e3ccSAndroid Build Coastguard Worker 
TEST(LevelTest,TestTargetLevelApi)82*77c1e3ccSAndroid Build Coastguard Worker TEST(LevelTest, TestTargetLevelApi) {
83*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *codec = aom_codec_av1_cx();
84*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
85*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
86*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(codec, &cfg, 0));
87*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, codec, &cfg, 0));
88*77c1e3ccSAndroid Build Coastguard Worker   for (int operating_point = 0; operating_point <= 32; ++operating_point) {
89*77c1e3ccSAndroid Build Coastguard Worker     for (int level = 0; level <= 32; ++level) {
90*77c1e3ccSAndroid Build Coastguard Worker       const int target_level = operating_point * 100 + level;
91*77c1e3ccSAndroid Build Coastguard Worker       if (operating_point <= 31 &&
92*77c1e3ccSAndroid Build Coastguard Worker           ((level < (CONFIG_CWG_C013 ? 28 : 20) && level != 2 && level != 3 &&
93*77c1e3ccSAndroid Build Coastguard Worker             level != 6 && level != 7 && level != 10 && level != 11) ||
94*77c1e3ccSAndroid Build Coastguard Worker            level == kLevelMax || level == kLevelKeepStats)) {
95*77c1e3ccSAndroid Build Coastguard Worker         EXPECT_EQ(AOM_CODEC_OK,
96*77c1e3ccSAndroid Build Coastguard Worker                   AOM_CODEC_CONTROL_TYPECHECKED(
97*77c1e3ccSAndroid Build Coastguard Worker                       &enc, AV1E_SET_TARGET_SEQ_LEVEL_IDX, target_level));
98*77c1e3ccSAndroid Build Coastguard Worker       } else {
99*77c1e3ccSAndroid Build Coastguard Worker         EXPECT_EQ(AOM_CODEC_INVALID_PARAM,
100*77c1e3ccSAndroid Build Coastguard Worker                   AOM_CODEC_CONTROL_TYPECHECKED(
101*77c1e3ccSAndroid Build Coastguard Worker                       &enc, AV1E_SET_TARGET_SEQ_LEVEL_IDX, target_level));
102*77c1e3ccSAndroid Build Coastguard Worker       }
103*77c1e3ccSAndroid Build Coastguard Worker     }
104*77c1e3ccSAndroid Build Coastguard Worker   }
105*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
106*77c1e3ccSAndroid Build Coastguard Worker }
107*77c1e3ccSAndroid Build Coastguard Worker 
TEST(LevelTest,InvalidOperatingPointIndexErrorDetail)108*77c1e3ccSAndroid Build Coastguard Worker TEST(LevelTest, InvalidOperatingPointIndexErrorDetail) {
109*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_iface_t *codec = aom_codec_av1_cx();
110*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_ctx_t enc;
111*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_enc_cfg_t cfg;
112*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(aom_codec_enc_config_default(codec, &cfg, 0), AOM_CODEC_OK);
113*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(aom_codec_enc_init(&enc, codec, &cfg, 0), AOM_CODEC_OK);
114*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_TARGET_SEQ_LEVEL_IDX, 3219),
115*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_INVALID_PARAM);
116*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(aom_codec_error_detail(&enc),
117*77c1e3ccSAndroid Build Coastguard Worker             std::string("Invalid operating point index: 32"));
118*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(aom_codec_set_option(&enc, "target-seq-level-idx", "3319"),
119*77c1e3ccSAndroid Build Coastguard Worker             AOM_CODEC_INVALID_PARAM);
120*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(aom_codec_error_detail(&enc),
121*77c1e3ccSAndroid Build Coastguard Worker             std::string("Invalid operating point index: 33"));
122*77c1e3ccSAndroid Build Coastguard Worker   EXPECT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
123*77c1e3ccSAndroid Build Coastguard Worker }
124*77c1e3ccSAndroid Build Coastguard Worker 
TEST_P(LevelTest,TestTargetLevel19)125*77c1e3ccSAndroid Build Coastguard Worker TEST_P(LevelTest, TestTargetLevel19) {
126*77c1e3ccSAndroid Build Coastguard Worker   std::unique_ptr<libaom_test::VideoSource> video;
127*77c1e3ccSAndroid Build Coastguard Worker   video.reset(new libaom_test::Y4mVideoSource("park_joy_90p_8_420.y4m", 0, 10));
128*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NE(video, nullptr);
129*77c1e3ccSAndroid Build Coastguard Worker   // Level index 19 corresponding to level 6.3.
130*77c1e3ccSAndroid Build Coastguard Worker   target_level_ = 19;
131*77c1e3ccSAndroid Build Coastguard Worker   ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
132*77c1e3ccSAndroid Build Coastguard Worker }
133*77c1e3ccSAndroid Build Coastguard Worker 
TEST_P(LevelTest,TestLevelMonitoringLowBitrate)134*77c1e3ccSAndroid Build Coastguard Worker TEST_P(LevelTest, TestLevelMonitoringLowBitrate) {
135*77c1e3ccSAndroid Build Coastguard Worker   // To save run time, we only test speed 4.
136*77c1e3ccSAndroid Build Coastguard Worker   if (cpu_used_ == 4) {
137*77c1e3ccSAndroid Build Coastguard Worker     libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
138*77c1e3ccSAndroid Build Coastguard Worker                                        30, 1, 0, 30);
139*77c1e3ccSAndroid Build Coastguard Worker     target_level_ = kLevelKeepStats;
140*77c1e3ccSAndroid Build Coastguard Worker     cfg_.rc_target_bitrate = 1000;
141*77c1e3ccSAndroid Build Coastguard Worker     cfg_.g_limit = 30;
142*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
143*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_LE(level_[0], 0);
144*77c1e3ccSAndroid Build Coastguard Worker   }
145*77c1e3ccSAndroid Build Coastguard Worker }
146*77c1e3ccSAndroid Build Coastguard Worker 
TEST_P(LevelTest,TestLevelMonitoringHighBitrate)147*77c1e3ccSAndroid Build Coastguard Worker TEST_P(LevelTest, TestLevelMonitoringHighBitrate) {
148*77c1e3ccSAndroid Build Coastguard Worker   // To save run time, we only test speed 4.
149*77c1e3ccSAndroid Build Coastguard Worker   if (cpu_used_ == 4) {
150*77c1e3ccSAndroid Build Coastguard Worker     libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
151*77c1e3ccSAndroid Build Coastguard Worker                                        30, 1, 0, 30);
152*77c1e3ccSAndroid Build Coastguard Worker     target_level_ = kLevelKeepStats;
153*77c1e3ccSAndroid Build Coastguard Worker     cfg_.rc_target_bitrate = 4000;
154*77c1e3ccSAndroid Build Coastguard Worker     cfg_.g_limit = 30;
155*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
156*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_LE(level_[0], 4);
157*77c1e3ccSAndroid Build Coastguard Worker   }
158*77c1e3ccSAndroid Build Coastguard Worker }
159*77c1e3ccSAndroid Build Coastguard Worker 
TEST_P(LevelTest,TestTargetLevel0)160*77c1e3ccSAndroid Build Coastguard Worker TEST_P(LevelTest, TestTargetLevel0) {
161*77c1e3ccSAndroid Build Coastguard Worker   // To save run time, we only test speed 4.
162*77c1e3ccSAndroid Build Coastguard Worker   if (cpu_used_ == 4) {
163*77c1e3ccSAndroid Build Coastguard Worker     libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
164*77c1e3ccSAndroid Build Coastguard Worker                                        30, 1, 0, 50);
165*77c1e3ccSAndroid Build Coastguard Worker     const int target_level = 0;
166*77c1e3ccSAndroid Build Coastguard Worker     target_level_ = target_level;
167*77c1e3ccSAndroid Build Coastguard Worker     cfg_.rc_target_bitrate = 4000;
168*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
169*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_LE(level_[0], target_level);
170*77c1e3ccSAndroid Build Coastguard Worker   }
171*77c1e3ccSAndroid Build Coastguard Worker }
172*77c1e3ccSAndroid Build Coastguard Worker 
TEST_P(LevelTest,TestTargetLevelRecode)173*77c1e3ccSAndroid Build Coastguard Worker TEST_P(LevelTest, TestTargetLevelRecode) {
174*77c1e3ccSAndroid Build Coastguard Worker   if (cpu_used_ == 4 && encoding_mode_ == ::libaom_test::kTwoPassGood) {
175*77c1e3ccSAndroid Build Coastguard Worker     libaom_test::I420VideoSource video("rand_noise_w1280h720.yuv", 1280, 720,
176*77c1e3ccSAndroid Build Coastguard Worker                                        25, 1, 0, 10);
177*77c1e3ccSAndroid Build Coastguard Worker     const int target_level = 0005;
178*77c1e3ccSAndroid Build Coastguard Worker     target_level_ = target_level;
179*77c1e3ccSAndroid Build Coastguard Worker     cfg_.rc_target_bitrate = 5000;
180*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
181*77c1e3ccSAndroid Build Coastguard Worker   }
182*77c1e3ccSAndroid Build Coastguard Worker }
183*77c1e3ccSAndroid Build Coastguard Worker 
184*77c1e3ccSAndroid Build Coastguard Worker AV1_INSTANTIATE_TEST_SUITE(LevelTest,
185*77c1e3ccSAndroid Build Coastguard Worker                            ::testing::Values(::libaom_test::kTwoPassGood,
186*77c1e3ccSAndroid Build Coastguard Worker                                              ::libaom_test::kOnePassGood),
187*77c1e3ccSAndroid Build Coastguard Worker                            ::testing::ValuesIn(kCpuUsedVectors));
188*77c1e3ccSAndroid Build Coastguard Worker }  // namespace
189