1 /*
2 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12 #include <cstdlib>
13
14 #include "test/codec_factory.h"
15 #include "test/encode_test_driver.h"
16 #include "test/i420_video_source.h"
17 #include "test/util.h"
18
19 namespace {
20
21 const double kPsnrDiffThreshold = 0.1;
22
23 // Params: first pass cpu used, second pass cpu used
24 class CpuUsedFirstpassTest
25 : public ::libaom_test::CodecTestWith2Params<int, int>,
26 public ::libaom_test::EncoderTest {
27 protected:
CpuUsedFirstpassTest()28 CpuUsedFirstpassTest()
29 : EncoderTest(GET_PARAM(0)), second_pass_cpu_used_(GET_PARAM(2)) {}
30 ~CpuUsedFirstpassTest() override = default;
31
SetUp()32 void SetUp() override {
33 InitializeConfig(::libaom_test::kTwoPassGood);
34 const aom_rational timebase = { 1, 30 };
35 cfg_.g_timebase = timebase;
36 cfg_.rc_end_usage = AOM_VBR;
37 cfg_.rc_target_bitrate = 1000;
38 cfg_.g_lag_in_frames = 19;
39 cfg_.g_threads = 0;
40 init_flags_ = AOM_CODEC_USE_PSNR;
41 }
42
BeginPassHook(unsigned int pass)43 void BeginPassHook(unsigned int pass) override {
44 psnr_ = 0.0;
45 nframes_ = 0;
46
47 if (pass == 0)
48 cpu_used_ = first_pass_cpu_used_;
49 else
50 cpu_used_ = second_pass_cpu_used_;
51 }
52
PSNRPktHook(const aom_codec_cx_pkt_t * pkt)53 void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) override {
54 psnr_ += pkt->data.psnr.psnr[0];
55 nframes_++;
56 }
57
PreEncodeFrameHook(::libaom_test::VideoSource * video,::libaom_test::Encoder * encoder)58 void PreEncodeFrameHook(::libaom_test::VideoSource *video,
59 ::libaom_test::Encoder *encoder) override {
60 if (video->frame() == 0) {
61 encoder->Control(AOME_SET_CPUUSED, cpu_used_);
62 encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
63 encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7);
64 encoder->Control(AOME_SET_ARNR_STRENGTH, 5);
65 }
66 }
67
GetAveragePsnr() const68 double GetAveragePsnr() const {
69 if (nframes_) return psnr_ / nframes_;
70 return 0.0;
71 }
72
GetPsnrDiffThreshold()73 double GetPsnrDiffThreshold() { return kPsnrDiffThreshold; }
74
DoTest()75 void DoTest() {
76 libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480,
77 cfg_.g_timebase.den, cfg_.g_timebase.num,
78 0, 30);
79 double ref_psnr;
80 double psnr_diff;
81
82 first_pass_cpu_used_ = second_pass_cpu_used_;
83 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); // same preset case ref_psnr
84 ref_psnr = GetAveragePsnr();
85
86 first_pass_cpu_used_ = GET_PARAM(1);
87 if (first_pass_cpu_used_ == second_pass_cpu_used_) return;
88 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
89 psnr_diff = std::abs(ref_psnr - GetAveragePsnr());
90 EXPECT_LT(psnr_diff, GetPsnrDiffThreshold())
91 << "first pass cpu used = " << first_pass_cpu_used_
92 << ", second pass cpu used = " << second_pass_cpu_used_;
93 }
94
95 int cpu_used_;
96 int first_pass_cpu_used_;
97 int second_pass_cpu_used_;
98 unsigned int nframes_;
99 double psnr_;
100 };
101
TEST_P(CpuUsedFirstpassTest,FirstPassTest)102 TEST_P(CpuUsedFirstpassTest, FirstPassTest) { DoTest(); }
103
104 class CpuUsedFirstpassTestLarge : public CpuUsedFirstpassTest {};
105
TEST_P(CpuUsedFirstpassTestLarge,FirstPassTest)106 TEST_P(CpuUsedFirstpassTestLarge, FirstPassTest) { DoTest(); }
107
108 #if defined(__has_feature)
109 #if __has_feature(memory_sanitizer)
110 static const int kSecondPassCpuUsedLarge[] = { 2, 4 };
111 static const int kSecondPassCpuUsed[] = { 6 };
112 #else
113 static const int kSecondPassCpuUsedLarge[] = { 2 };
114 static const int kSecondPassCpuUsed[] = { 4, 6 };
115 #endif
116 #else
117 static const int kSecondPassCpuUsedLarge[] = { 2 };
118 static const int kSecondPassCpuUsed[] = { 4, 6 };
119 #endif
120
121 AV1_INSTANTIATE_TEST_SUITE(
122 CpuUsedFirstpassTestLarge, ::testing::Values(2, 4, 6),
123 ::testing::ValuesIn(kSecondPassCpuUsedLarge)); // cpu_used
124
125 AV1_INSTANTIATE_TEST_SUITE(
126 CpuUsedFirstpassTest, ::testing::Values(2, 4, 6),
127 ::testing::ValuesIn(kSecondPassCpuUsed)); // cpu_used
128
129 } // namespace
130