1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
6
7 #include "gtest/gtest.h"
8 #include "DriftCompensation.h"
9
10 using namespace mozilla;
11
12 class DriftCompensatorTest : public ::testing::Test {
13 public:
14 const TrackRate mRate = 44100;
15 const TimeStamp mStart;
16 const RefPtr<DriftCompensator> mComp;
17
DriftCompensatorTest()18 DriftCompensatorTest()
19 : mStart(TimeStamp::Now()),
20 mComp(MakeRefPtr<DriftCompensator>(GetCurrentThreadEventTarget(),
21 mRate)) {
22 mComp->NotifyAudioStart(mStart);
23 // NotifyAudioStart dispatched a runnable to update the audio mStart time on
24 // the video thread. Because this is a test, the video thread is the current
25 // thread. We spin the event loop until we know the mStart time is updated.
26 {
27 bool updated = false;
28 NS_DispatchToCurrentThread(
29 NS_NewRunnableFunction(__func__, [&] { updated = true; }));
30 SpinEventLoopUntil([&] { return updated; });
31 }
32 }
33
34 // Past() is half as far from `mStart` as `aNow`.
Past(TimeStamp aNow)35 TimeStamp Past(TimeStamp aNow) {
36 return mStart + (aNow - mStart) / (int64_t)2;
37 }
38
39 // Future() is twice as far from `mStart` as `aNow`.
Future(TimeStamp aNow)40 TimeStamp Future(TimeStamp aNow) { return mStart + (aNow - mStart) * 2; }
41 };
42
TEST_F(DriftCompensatorTest,Initialized)43 TEST_F(DriftCompensatorTest, Initialized) {
44 EXPECT_EQ(mComp->GetVideoTime(mStart, mStart), mStart);
45 }
46
TEST_F(DriftCompensatorTest,SlowerAudio)47 TEST_F(DriftCompensatorTest, SlowerAudio) {
48 // 10s of audio took 20 seconds of wall clock to play out
49 mComp->NotifyAudio(mRate * 10);
50 TimeStamp now = mStart + TimeDuration::FromSeconds(20);
51 EXPECT_EQ((mComp->GetVideoTime(now, mStart) - mStart).ToSeconds(), 0.0);
52 EXPECT_EQ((mComp->GetVideoTime(now, Past(now)) - mStart).ToSeconds(), 5.0);
53 EXPECT_EQ((mComp->GetVideoTime(now, now) - mStart).ToSeconds(), 10.0);
54 EXPECT_EQ((mComp->GetVideoTime(now, Future(now)) - mStart).ToSeconds(), 20.0);
55 }
56
TEST_F(DriftCompensatorTest,NoDrift)57 TEST_F(DriftCompensatorTest, NoDrift) {
58 // 10s of audio took 10 seconds of wall clock to play out
59 mComp->NotifyAudio(mRate * 10);
60 TimeStamp now = mStart + TimeDuration::FromSeconds(10);
61 EXPECT_EQ((mComp->GetVideoTime(now, mStart) - mStart).ToSeconds(), 0.0);
62 EXPECT_EQ((mComp->GetVideoTime(now, Past(now)) - mStart).ToSeconds(), 5.0);
63 EXPECT_EQ((mComp->GetVideoTime(now, now) - mStart).ToSeconds(), 10.0);
64 EXPECT_EQ((mComp->GetVideoTime(now, Future(now)) - mStart).ToSeconds(), 20.0);
65 }
66
TEST_F(DriftCompensatorTest,NoProgress)67 TEST_F(DriftCompensatorTest, NoProgress) {
68 // 10s of audio took 0 seconds of wall clock to play out
69 mComp->NotifyAudio(mRate * 10);
70 TimeStamp now = mStart;
71 TimeStamp future = mStart + TimeDuration::FromSeconds(5);
72 EXPECT_EQ((mComp->GetVideoTime(now, mStart) - mStart).ToSeconds(), 0.0);
73 EXPECT_EQ((mComp->GetVideoTime(now, future) - mStart).ToSeconds(), 5.0);
74 }
75
TEST_F(DriftCompensatorTest,FasterAudio)76 TEST_F(DriftCompensatorTest, FasterAudio) {
77 // 20s of audio took 10 seconds of wall clock to play out
78 mComp->NotifyAudio(mRate * 20);
79 TimeStamp now = mStart + TimeDuration::FromSeconds(10);
80 EXPECT_EQ((mComp->GetVideoTime(now, mStart) - mStart).ToSeconds(), 0.0);
81 EXPECT_EQ((mComp->GetVideoTime(now, Past(now)) - mStart).ToSeconds(), 10.0);
82 EXPECT_EQ((mComp->GetVideoTime(now, now) - mStart).ToSeconds(), 20.0);
83 EXPECT_EQ((mComp->GetVideoTime(now, Future(now)) - mStart).ToSeconds(), 40.0);
84 }
85