Phase 7
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user