• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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