Phase 7
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m47s
CI / Windows Release Package (push) Successful in 3m2s

This commit is contained in:
Aiden
2026-05-11 21:05:11 +10:00
parent 50d5880835
commit f288455709
10 changed files with 335 additions and 51 deletions

View File

@@ -92,13 +92,15 @@ public:
return true;
}
void AccountForCompletionResult(VideoIOCompletionResult result) override
void AccountForCompletionResult(VideoIOCompletionResult result, uint64_t readyQueueDepth) override
{
mLastCompletion = result;
mLastReadyQueueDepth = readyQueueDepth;
}
unsigned ScheduledFrames() const { return mScheduledFrames; }
VideoIOCompletionResult LastCompletion() const { return mLastCompletion; }
uint64_t LastReadyQueueDepth() const { return mLastReadyQueueDepth; }
private:
VideoIOState mState;
@@ -108,6 +110,7 @@ private:
std::array<unsigned char, 7680> mOutputBytes = {};
unsigned mScheduledFrames = 0;
VideoIOCompletionResult mLastCompletion = VideoIOCompletionResult::Unknown;
uint64_t mLastReadyQueueDepth = 0;
};
}
@@ -132,13 +135,14 @@ int main()
VideoIOOutputFrame outputFrame;
Expect(device.BeginOutputFrame(outputFrame), "fake output frame can be acquired");
device.EndOutputFrame(outputFrame);
device.AccountForCompletionResult(VideoIOCompletionResult::Completed);
device.AccountForCompletionResult(VideoIOCompletionResult::Completed, 2);
Expect(device.ScheduleOutputFrame(outputFrame), "fake output frame can be scheduled");
Expect(inputSeen, "fake input callback emits generic frame");
Expect(outputSeen, "fake output callback emits generic completion");
Expect(device.ScheduledFrames() == 1, "fake backend schedules one frame");
Expect(device.LastCompletion() == VideoIOCompletionResult::Completed, "fake backend records generic completion");
Expect(device.LastReadyQueueDepth() == 2, "fake backend records ready queue depth");
if (gFailures != 0)
{

View File

@@ -37,30 +37,51 @@ void TestScheduleAdvancesFromZero()
Expect(third.streamTime == 2002, "third frame advances by two durations");
}
void TestLateAndDroppedSkipAhead()
void TestLateAndDroppedRecoveryUsesMeasuredPressure()
{
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");
VideoPlayoutRecoveryDecision lateDecision = scheduler.AccountForCompletionResult(VideoIOCompletionResult::DisplayedLate, 2);
Expect(lateDecision.catchUpFrames == 1, "single late completion catches up by measured one-frame lag");
Expect(lateDecision.lateStreak == 1, "late completion increments late streak");
Expect(scheduler.NextScheduleTime().streamTime == 2000, "single late recovery advances by measured lag");
scheduler.AccountForCompletionResult(VideoIOCompletionResult::Dropped);
Expect(scheduler.NextScheduleTime().streamTime == 6000, "dropped completion preserves the existing two-frame skip policy");
VideoPlayoutRecoveryDecision dropDecision = scheduler.AccountForCompletionResult(VideoIOCompletionResult::Dropped, 2);
Expect(dropDecision.catchUpFrames == 2, "dropped completion catches up by measured drop pressure");
Expect(dropDecision.lateStreak == 0, "dropped completion resets late streak");
Expect(dropDecision.dropStreak == 1, "dropped completion increments drop streak");
Expect(scheduler.NextScheduleTime().streamTime == 5000, "drop recovery advances by measured lag");
}
void TestLateAndDroppedRecoveryUsesPolicy()
void TestMeasuredRecoveryIsCappedByPolicy()
{
VideoPlayoutPolicy policy;
policy.lateOrDropCatchUpFrames = 4;
policy.lateOrDropCatchUpFrames = 1;
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");
VideoPlayoutRecoveryDecision decision = scheduler.AccountForCompletionResult(VideoIOCompletionResult::Dropped, 0);
Expect(decision.measuredLagFrames > decision.catchUpFrames, "policy caps measured recovery");
Expect(decision.catchUpFrames == 1, "drop recovery obeys policy cap");
Expect(scheduler.NextScheduleTime().streamTime == 2000, "capped recovery advances by one frame");
}
void TestCleanCompletionTracksCompletedIndexAndClearsStreaks()
{
VideoPlayoutScheduler scheduler;
scheduler.Configure(1000, 50000);
(void)scheduler.NextScheduleTime();
(void)scheduler.AccountForCompletionResult(VideoIOCompletionResult::DisplayedLate, 2);
VideoPlayoutRecoveryDecision decision = scheduler.AccountForCompletionResult(VideoIOCompletionResult::Completed, 2);
Expect(decision.completedFrameIndex == 2, "completion accounting tracks completed index");
Expect(decision.catchUpFrames == 0, "clean completion does not catch up");
Expect(decision.lateStreak == 0, "clean completion clears late streak");
Expect(decision.dropStreak == 0, "clean completion keeps drop streak clear");
}
void TestPolicyNormalization()
@@ -94,8 +115,9 @@ void TestFrameBudgets()
int main()
{
TestScheduleAdvancesFromZero();
TestLateAndDroppedSkipAhead();
TestLateAndDroppedRecoveryUsesPolicy();
TestLateAndDroppedRecoveryUsesMeasuredPressure();
TestMeasuredRecoveryIsCappedByPolicy();
TestCleanCompletionTracksCompletedIndexAndClearsStreaks();
TestPolicyNormalization();
TestFrameBudgets();