Phase 7.5 step 2
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
#include "OutputProductionController.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace
|
||||
{
|
||||
std::size_t ClampReadyLimit(unsigned value, std::size_t capacity)
|
||||
{
|
||||
const std::size_t requested = static_cast<std::size_t>(value);
|
||||
if (capacity == 0)
|
||||
return requested;
|
||||
return (std::min)(requested, capacity);
|
||||
}
|
||||
}
|
||||
|
||||
OutputProductionController::OutputProductionController(const VideoPlayoutPolicy& policy) :
|
||||
mPolicy(NormalizeVideoPlayoutPolicy(policy))
|
||||
{
|
||||
}
|
||||
|
||||
void OutputProductionController::Configure(const VideoPlayoutPolicy& policy)
|
||||
{
|
||||
mPolicy = NormalizeVideoPlayoutPolicy(policy);
|
||||
}
|
||||
|
||||
OutputProductionDecision OutputProductionController::Decide(const OutputProductionPressure& pressure) const
|
||||
{
|
||||
OutputProductionDecision decision;
|
||||
|
||||
const std::size_t configuredMaxReadyFrames = static_cast<std::size_t>(mPolicy.maxReadyFrames);
|
||||
const std::size_t effectiveMaxReadyFrames = pressure.readyQueueCapacity > 0
|
||||
? (std::min)(configuredMaxReadyFrames, pressure.readyQueueCapacity)
|
||||
: configuredMaxReadyFrames;
|
||||
const std::size_t effectiveTargetReadyFrames = (std::min)(
|
||||
ClampReadyLimit(mPolicy.targetReadyFrames, pressure.readyQueueCapacity),
|
||||
effectiveMaxReadyFrames);
|
||||
|
||||
decision.targetReadyFrames = effectiveTargetReadyFrames;
|
||||
decision.maxReadyFrames = effectiveMaxReadyFrames;
|
||||
|
||||
if (effectiveMaxReadyFrames == 0)
|
||||
{
|
||||
decision.action = OutputProductionAction::Throttle;
|
||||
decision.reason = "no-ready-frame-capacity";
|
||||
return decision;
|
||||
}
|
||||
|
||||
if (pressure.readyQueueDepth >= effectiveMaxReadyFrames)
|
||||
{
|
||||
decision.action = OutputProductionAction::Throttle;
|
||||
decision.reason = "ready-queue-full";
|
||||
return decision;
|
||||
}
|
||||
|
||||
if (pressure.readyQueueDepth < effectiveTargetReadyFrames)
|
||||
{
|
||||
decision.action = OutputProductionAction::Produce;
|
||||
decision.requestedFrames = effectiveTargetReadyFrames - pressure.readyQueueDepth;
|
||||
decision.reason = "ready-queue-below-target";
|
||||
return decision;
|
||||
}
|
||||
|
||||
if ((pressure.lateStreak > 0 || pressure.dropStreak > 0 || pressure.readyQueueUnderrunCount > 0) &&
|
||||
pressure.readyQueueDepth < effectiveMaxReadyFrames)
|
||||
{
|
||||
decision.action = OutputProductionAction::Produce;
|
||||
decision.requestedFrames = 1;
|
||||
decision.reason = "playout-pressure";
|
||||
return decision;
|
||||
}
|
||||
|
||||
decision.action = OutputProductionAction::Wait;
|
||||
decision.reason = "ready-queue-at-target";
|
||||
return decision;
|
||||
}
|
||||
|
||||
const char* OutputProductionActionName(OutputProductionAction action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case OutputProductionAction::Produce:
|
||||
return "Produce";
|
||||
case OutputProductionAction::Throttle:
|
||||
return "Throttle";
|
||||
case OutputProductionAction::Wait:
|
||||
default:
|
||||
return "Wait";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user