/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "DriftCompensation.h"
#include "mozilla/SpinEventLoopUntil.h"
using namespace mozilla;
class DriftCompensatorTest :
public ::testing::Test {
public:
const TrackRate mRate =
44100;
const TimeStamp mStart;
const RefPtr<DriftCompensator> mComp;
DriftCompensatorTest()
: mStart(TimeStamp::Now()),
mComp(MakeRefPtr<DriftCompensator>(GetCurrentSerialEventTarget(),
mRate)) {
mComp->NotifyAudioStart(mStart);
// NotifyAudioStart dispatched a runnable to update the audio mStart time on
// the video thread. Because this is a test, the video thread is the current
// thread. We spin the event loop until we know the mStart time is updated.
{
bool updated =
false;
NS_DispatchToCurrentThread(
NS_NewRunnableFunction(__func__, [&] { updated =
true; }));
SpinEventLoopUntil(
"DriftCompensatorTest::DriftCompensatorTest"_ns,
[&] {
return updated; });
}
}
// Past() is half as far from `mStart` as `aNow`.
TimeStamp Past(TimeStamp aNow) {
return mStart + (aNow - mStart) / (int64_t)
2;
}
// Future() is twice as far from `mStart` as `aNow`.
TimeStamp Future(TimeStamp aNow) {
return mStart + (aNow - mStart) *
2; }
};
TEST_F(DriftCompensatorTest, Initialized) {
EXPECT_EQ(mComp->GetVideoTime(mStart, mStart), mStart);
}
TEST_F(DriftCompensatorTest, SlowerAudio) {
// 10s of audio took 20 seconds of wall clock to play out
mComp->NotifyAudio(mRate *
10);
TimeStamp now = mStart + TimeDuration::FromSeconds(
20);
EXPECT_EQ((mComp->GetVideoTime(now, mStart) - mStart).ToSeconds(),
0.
0);
EXPECT_EQ((mComp->GetVideoTime(now, Past(now)) - mStart).ToSeconds(),
5.
0);
EXPECT_EQ((mComp->GetVideoTime(now, now) - mStart).ToSeconds(),
10.
0);
EXPECT_EQ((mComp->GetVideoTime(now, Future(now)) - mStart).ToSeconds(),
20.
0);
}
TEST_F(DriftCompensatorTest, NoDrift) {
// 10s of audio took 10 seconds of wall clock to play out
mComp->NotifyAudio(mRate *
10);
TimeStamp now = mStart + TimeDuration::FromSeconds(
10);
EXPECT_EQ((mComp->GetVideoTime(now, mStart) - mStart).ToSeconds(),
0.
0);
EXPECT_EQ((mComp->GetVideoTime(now, Past(now)) - mStart).ToSeconds(),
5.
0);
EXPECT_EQ((mComp->GetVideoTime(now, now) - mStart).ToSeconds(),
10.
0);
EXPECT_EQ((mComp->GetVideoTime(now, Future(now)) - mStart).ToSeconds(),
20.
0);
}
TEST_F(DriftCompensatorTest, NoProgress) {
// 10s of audio took 0 seconds of wall clock to play out
mComp->NotifyAudio(mRate *
10);
TimeStamp now = mStart;
TimeStamp future = mStart + TimeDuration::FromSeconds(
5);
EXPECT_EQ((mComp->GetVideoTime(now, mStart) - mStart).ToSeconds(),
0.
0);
EXPECT_EQ((mComp->GetVideoTime(now, future) - mStart).ToSeconds(),
5.
0);
}
TEST_F(DriftCompensatorTest, FasterAudio) {
// 20s of audio took 10 seconds of wall clock to play out
mComp->NotifyAudio(mRate *
20);
TimeStamp now = mStart + TimeDuration::FromSeconds(
10);
EXPECT_EQ((mComp->GetVideoTime(now, mStart) - mStart).ToSeconds(),
0.
0);
EXPECT_EQ((mComp->GetVideoTime(now, Past(now)) - mStart).ToSeconds(),
10.
0);
EXPECT_EQ((mComp->GetVideoTime(now, now) - mStart).ToSeconds(),
20.
0);
EXPECT_EQ((mComp->GetVideoTime(now, Future(now)) - mStart).ToSeconds(),
40.
0);
}