111 lines
3.3 KiB
C++
111 lines
3.3 KiB
C++
#include "VideoPlayoutScheduler.h"
|
|
|
|
#include <cmath>
|
|
#include <iostream>
|
|
|
|
namespace
|
|
{
|
|
int gFailures = 0;
|
|
|
|
void Expect(bool condition, const char* message)
|
|
{
|
|
if (condition)
|
|
return;
|
|
|
|
std::cerr << "FAIL: " << message << "\n";
|
|
++gFailures;
|
|
}
|
|
|
|
void ExpectNear(double actual, double expected, double tolerance, const char* message)
|
|
{
|
|
Expect(std::fabs(actual - expected) <= tolerance, message);
|
|
}
|
|
|
|
void TestScheduleAdvancesFromZero()
|
|
{
|
|
VideoPlayoutScheduler scheduler;
|
|
scheduler.Configure(1001, 60000);
|
|
|
|
const VideoIOScheduleTime first = scheduler.NextScheduleTime();
|
|
const VideoIOScheduleTime second = scheduler.NextScheduleTime();
|
|
const VideoIOScheduleTime third = scheduler.NextScheduleTime();
|
|
|
|
Expect(first.streamTime == 0, "first frame starts at stream time zero");
|
|
Expect(first.duration == 1001, "duration is preserved");
|
|
Expect(first.timeScale == 60000, "time scale is preserved");
|
|
Expect(second.streamTime == 1001, "second frame advances by one duration");
|
|
Expect(third.streamTime == 2002, "third frame advances by two durations");
|
|
}
|
|
|
|
void TestLateAndDroppedSkipAhead()
|
|
{
|
|
VideoPlayoutScheduler scheduler;
|
|
scheduler.Configure(1000, 50000);
|
|
|
|
(void)scheduler.NextScheduleTime();
|
|
scheduler.AccountForCompletionResult(VideoIOCompletionResult::DisplayedLate);
|
|
Expect(scheduler.NextScheduleTime().streamTime == 3000, "late completion preserves the existing two-frame skip policy");
|
|
|
|
scheduler.AccountForCompletionResult(VideoIOCompletionResult::Dropped);
|
|
Expect(scheduler.NextScheduleTime().streamTime == 6000, "dropped completion preserves the existing two-frame skip policy");
|
|
}
|
|
|
|
void TestLateAndDroppedRecoveryUsesPolicy()
|
|
{
|
|
VideoPlayoutPolicy policy;
|
|
policy.lateOrDropCatchUpFrames = 4;
|
|
|
|
VideoPlayoutScheduler scheduler;
|
|
scheduler.Configure(1000, 50000, policy);
|
|
|
|
(void)scheduler.NextScheduleTime();
|
|
scheduler.AccountForCompletionResult(VideoIOCompletionResult::Dropped);
|
|
Expect(scheduler.NextScheduleTime().streamTime == 5000, "drop recovery uses policy catch-up frame count");
|
|
}
|
|
|
|
void TestPolicyNormalization()
|
|
{
|
|
VideoPlayoutPolicy policy;
|
|
policy.outputFramePoolSize = 0;
|
|
policy.targetPrerollFrames = 0;
|
|
policy.targetReadyFrames = 5;
|
|
policy.maxReadyFrames = 2;
|
|
|
|
VideoPlayoutPolicy normalized = NormalizeVideoPlayoutPolicy(policy);
|
|
Expect(normalized.outputFramePoolSize == 1, "policy normalization keeps at least one output frame");
|
|
Expect(normalized.targetPrerollFrames == 1, "policy normalization keeps at least one preroll frame");
|
|
Expect(normalized.maxReadyFrames == normalized.targetReadyFrames, "policy normalization keeps max ready frames above target");
|
|
}
|
|
|
|
void TestFrameBudgets()
|
|
{
|
|
VideoPlayoutScheduler scheduler;
|
|
scheduler.Configure(1000, 50000);
|
|
ExpectNear(scheduler.FrameBudgetMilliseconds(), 20.0, 0.0001, "50 fps budget");
|
|
|
|
scheduler.Configure(1001, 60000);
|
|
ExpectNear(scheduler.FrameBudgetMilliseconds(), 16.6833, 0.0001, "59.94 fps budget");
|
|
|
|
scheduler.Configure(1, 60);
|
|
ExpectNear(scheduler.FrameBudgetMilliseconds(), 16.6667, 0.0001, "60 fps budget");
|
|
}
|
|
}
|
|
|
|
int main()
|
|
{
|
|
TestScheduleAdvancesFromZero();
|
|
TestLateAndDroppedSkipAhead();
|
|
TestLateAndDroppedRecoveryUsesPolicy();
|
|
TestPolicyNormalization();
|
|
TestFrameBudgets();
|
|
|
|
if (gFailures != 0)
|
|
{
|
|
std::cerr << gFailures << " VideoPlayoutScheduler test failure(s).\n";
|
|
return 1;
|
|
}
|
|
|
|
std::cout << "VideoPlayoutScheduler tests passed.\n";
|
|
return 0;
|
|
}
|