1 /*
2  *  Copyright (c) 2019 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #include "test/codec_factory.h"
11 #include "test/encode_test_driver.h"
12 #include "test/util.h"
13 #include "test/video_source.h"
14 #include "third_party/googletest/src/include/gtest/gtest.h"
15 
16 namespace {
17 
18 const int kVideoSourceWidth = 320;
19 const int kVideoSourceHeight = 240;
20 const int kFramesToEncode = 3;
21 
22 // A video source that exposes functions to set the timebase, framerate and
23 // starting pts.
24 class DummyTimebaseVideoSource : public ::libvpx_test::DummyVideoSource {
25  public:
26   // Parameters num and den set the timebase for the video source.
DummyTimebaseVideoSource(int num,int den)27   DummyTimebaseVideoSource(int num, int den)
28       : timebase_({ num, den }), framerate_numerator_(30),
29         framerate_denominator_(1), starting_pts_(0) {
30     SetSize(kVideoSourceWidth, kVideoSourceHeight);
31     set_limit(kFramesToEncode);
32   }
33 
SetFramerate(int numerator,int denominator)34   void SetFramerate(int numerator, int denominator) {
35     framerate_numerator_ = numerator;
36     framerate_denominator_ = denominator;
37   }
38 
39   // Returns one frames duration in timebase units as a double.
FrameDuration() const40   double FrameDuration() const {
41     return (static_cast<double>(timebase_.den) / timebase_.num) /
42            (static_cast<double>(framerate_numerator_) / framerate_denominator_);
43   }
44 
pts() const45   virtual vpx_codec_pts_t pts() const {
46     return static_cast<vpx_codec_pts_t>(frame_ * FrameDuration() +
47                                         starting_pts_ + 0.5);
48   }
49 
duration() const50   virtual unsigned long duration() const {
51     return static_cast<unsigned long>(FrameDuration() + 0.5);
52   }
53 
timebase() const54   virtual vpx_rational_t timebase() const { return timebase_; }
55 
set_starting_pts(int64_t starting_pts)56   void set_starting_pts(int64_t starting_pts) { starting_pts_ = starting_pts; }
57 
58  private:
59   vpx_rational_t timebase_;
60   int framerate_numerator_;
61   int framerate_denominator_;
62   int64_t starting_pts_;
63 };
64 
65 class TimestampTest
66     : public ::libvpx_test::EncoderTest,
67       public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
68  protected:
TimestampTest()69   TimestampTest() : EncoderTest(GET_PARAM(0)) {}
~TimestampTest()70   virtual ~TimestampTest() {}
71 
SetUp()72   virtual void SetUp() {
73     InitializeConfig();
74     SetMode(GET_PARAM(1));
75   }
76 };
77 
78 class TimestampTestVp9Only : public TimestampTest {};
79 
80 // Tests encoding in millisecond timebase.
TEST_P(TimestampTest,EncodeFrames)81 TEST_P(TimestampTest, EncodeFrames) {
82   DummyTimebaseVideoSource video(1, 1000);
83   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
84 }
85 
86 // TODO(fgalligan): Enable test when
87 // https://bugs.chromium.org/p/webm/issues/detail?id=1614 is fixed.
TEST_P(TimestampTest,DISABLED_TestMicrosecondTimebase)88 TEST_P(TimestampTest, DISABLED_TestMicrosecondTimebase) {
89   // Set the timebase to microseconds.
90   DummyTimebaseVideoSource video(1, 1000000);
91   video.set_limit(1);
92   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
93 }
94 
95 // TODO(webm:701): Enable VP8 test when the overflow issue in
96 // TestVpxRollover is fixed.
TEST_P(TimestampTestVp9Only,TestVpxRollover)97 TEST_P(TimestampTestVp9Only, TestVpxRollover) {
98   DummyTimebaseVideoSource video(1, 1000);
99   video.set_starting_pts(922337170351ll);
100   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
101 }
102 
103 VP8_INSTANTIATE_TEST_CASE(TimestampTest,
104                           ::testing::Values(::libvpx_test::kTwoPassGood));
105 VP9_INSTANTIATE_TEST_CASE(TimestampTest,
106                           ::testing::Values(::libvpx_test::kTwoPassGood));
107 VP9_INSTANTIATE_TEST_CASE(TimestampTestVp9Only,
108                           ::testing::Values(::libvpx_test::kTwoPassGood));
109 }  // namespace
110