#include "OutputProductionController.h" #include #include namespace { int gFailures = 0; void Expect(bool condition, const char* message) { if (condition) return; std::cerr << "FAIL: " << message << "\n"; ++gFailures; } void TestLowQueueRequestsProductionToTarget() { VideoPlayoutPolicy policy; policy.targetReadyFrames = 3; policy.maxReadyFrames = 5; OutputProductionController controller(policy); OutputProductionPressure pressure; pressure.readyQueueDepth = 1; pressure.readyQueueCapacity = 5; const OutputProductionDecision decision = controller.Decide(pressure); Expect(decision.action == OutputProductionAction::Produce, "low ready queue requests production"); Expect(decision.requestedFrames == 2, "low ready queue requests enough frames to reach target"); Expect(decision.targetReadyFrames == 3, "decision reports effective target"); Expect(decision.maxReadyFrames == 5, "decision reports effective max"); Expect(decision.reason == "ready-queue-below-target", "low queue decision names reason"); } void TestFullQueueThrottles() { VideoPlayoutPolicy policy; policy.targetReadyFrames = 2; policy.maxReadyFrames = 4; OutputProductionController controller(policy); OutputProductionPressure pressure; pressure.readyQueueDepth = 4; pressure.readyQueueCapacity = 4; const OutputProductionDecision decision = controller.Decide(pressure); Expect(decision.action == OutputProductionAction::Throttle, "full ready queue throttles production"); Expect(decision.requestedFrames == 0, "full ready queue requests no frames"); Expect(decision.reason == "ready-queue-full", "full queue decision names reason"); } void TestAtTargetWaitsWithoutPressure() { VideoPlayoutPolicy policy; policy.targetReadyFrames = 2; policy.maxReadyFrames = 4; OutputProductionController controller(policy); OutputProductionPressure pressure; pressure.readyQueueDepth = 2; pressure.readyQueueCapacity = 4; const OutputProductionDecision decision = controller.Decide(pressure); Expect(decision.action == OutputProductionAction::Wait, "ready queue at target waits without pressure"); Expect(decision.requestedFrames == 0, "wait decision requests no frames"); Expect(decision.reason == "ready-queue-at-target", "wait decision names reason"); } void TestLateDropPressureRequestsHeadroom() { VideoPlayoutPolicy policy; policy.targetReadyFrames = 2; policy.maxReadyFrames = 4; OutputProductionController controller(policy); OutputProductionPressure pressure; pressure.readyQueueDepth = 2; pressure.readyQueueCapacity = 4; pressure.lateStreak = 1; OutputProductionDecision decision = controller.Decide(pressure); Expect(decision.action == OutputProductionAction::Produce, "late pressure requests extra headroom"); Expect(decision.requestedFrames == 1, "late pressure requests one frame"); Expect(decision.reason == "playout-pressure", "late pressure decision names reason"); pressure.lateStreak = 0; pressure.dropStreak = 2; decision = controller.Decide(pressure); Expect(decision.action == OutputProductionAction::Produce, "drop pressure requests extra headroom"); pressure.dropStreak = 0; pressure.readyQueueUnderrunCount = 1; decision = controller.Decide(pressure); Expect(decision.action == OutputProductionAction::Produce, "underrun pressure requests extra headroom"); } void TestPolicyNormalizesAndClampsToCapacity() { VideoPlayoutPolicy policy; policy.targetReadyFrames = 0; policy.maxReadyFrames = 8; OutputProductionController controller(policy); OutputProductionPressure pressure; pressure.readyQueueDepth = 1; pressure.readyQueueCapacity = 3; const OutputProductionDecision decision = controller.Decide(pressure); Expect(decision.action == OutputProductionAction::Wait, "normalized target at current depth waits"); Expect(decision.targetReadyFrames == 1, "target normalizes to at least one frame"); Expect(decision.maxReadyFrames == 3, "max ready frames clamps to queue capacity"); } void TestActionNames() { Expect(OutputProductionActionName(OutputProductionAction::Produce) == std::string("Produce"), "produce action has name"); Expect(OutputProductionActionName(OutputProductionAction::Wait) == std::string("Wait"), "wait action has name"); Expect(OutputProductionActionName(OutputProductionAction::Throttle) == std::string("Throttle"), "throttle action has name"); } } int main() { TestLowQueueRequestsProductionToTarget(); TestFullQueueThrottles(); TestAtTargetWaitsWithoutPressure(); TestLateDropPressureRequestsHeadroom(); TestPolicyNormalizesAndClampsToCapacity(); TestActionNames(); if (gFailures != 0) { std::cerr << gFailures << " OutputProductionController test failure(s).\n"; return 1; } std::cout << "OutputProductionController tests passed.\n"; return 0; }