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 "test/codec_factory.h"
13 #include "test/encode_test_driver.h"
14 #include "test/i420_video_source.h"
15 #include "test/util.h"
16
17 namespace {
18
19 const double kPsnrDiffThreshold = 0.1;
20 const int kFirstPassCpuUsed[] = { 2, 4, 6 };
21
22 class CpuUsedFirstpassTest : public ::libaom_test::CodecTestWithParam<int>,
23 public ::libaom_test::EncoderTest {
24 protected:
CpuUsedFirstpassTest()25 CpuUsedFirstpassTest()
26 : EncoderTest(GET_PARAM(0)), second_pass_cpu_used_(GET_PARAM(1)) {}
~CpuUsedFirstpassTest()27 virtual ~CpuUsedFirstpassTest() {}
28
SetUp()29 virtual void SetUp() {
30 InitializeConfig(::libaom_test::kTwoPassGood);
31 const aom_rational timebase = { 1, 30 };
32 cfg_.g_timebase = timebase;
33 cfg_.rc_end_usage = AOM_VBR;
34 cfg_.rc_target_bitrate = 1000;
35 cfg_.g_lag_in_frames = 19;
36 cfg_.g_threads = 0;
37 init_flags_ = AOM_CODEC_USE_PSNR;
38 }
39
BeginPassHook(unsigned int pass)40 virtual void BeginPassHook(unsigned int pass) {
41 psnr_ = 0.0;
42 nframes_ = 0;
43
44 if (pass == 0)
45 cpu_used_ = first_pass_cpu_used_;
46 else
47 cpu_used_ = second_pass_cpu_used_;
48 }
49
PSNRPktHook(const aom_codec_cx_pkt_t * pkt)50 virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) {
51 psnr_ += pkt->data.psnr.psnr[0];
52 nframes_++;
53 }
54
PreEncodeFrameHook(::libaom_test::VideoSource * video,::libaom_test::Encoder * encoder)55 virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
56 ::libaom_test::Encoder *encoder) {
57 if (video->frame() == 0) {
58 encoder->Control(AOME_SET_CPUUSED, cpu_used_);
59 encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1);
60 encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7);
61 encoder->Control(AOME_SET_ARNR_STRENGTH, 5);
62 }
63 }
64
GetAveragePsnr() const65 double GetAveragePsnr() const {
66 if (nframes_) return psnr_ / nframes_;
67 return 0.0;
68 }
69
GetPsnrDiffThreshold()70 double GetPsnrDiffThreshold() { return kPsnrDiffThreshold; }
71
DoTest()72 void DoTest() {
73 libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480,
74 cfg_.g_timebase.den, cfg_.g_timebase.num,
75 0, 30);
76 const int size = sizeof(kFirstPassCpuUsed) / sizeof(kFirstPassCpuUsed[0]);
77 double ref_psnr;
78 double psnr_diff;
79
80 first_pass_cpu_used_ = second_pass_cpu_used_;
81 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); // same preset case ref_psnr
82 ref_psnr = GetAveragePsnr();
83
84 for (int i = 0; i < size; i++) {
85 first_pass_cpu_used_ = kFirstPassCpuUsed[i];
86 if (first_pass_cpu_used_ == second_pass_cpu_used_) continue;
87 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
88 psnr_diff = abs(ref_psnr - GetAveragePsnr());
89 EXPECT_LT(psnr_diff, GetPsnrDiffThreshold())
90 << "first pass cpu used = " << first_pass_cpu_used_
91 << ", second pass cpu used = " << second_pass_cpu_used_;
92 }
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 AV1_INSTANTIATE_TEST_SUITE(CpuUsedFirstpassTestLarge,
109 ::testing::Values(2)); // cpu_used
110
111 AV1_INSTANTIATE_TEST_SUITE(CpuUsedFirstpassTest,
112 ::testing::Values(4, 6)); // cpu_used
113 } // namespace
114