faliure
This commit is contained in:
@@ -421,9 +421,7 @@ void VideoBackend::OutputProducerWorkerMain()
|
||||
for (;;)
|
||||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mOutputProducerMutex);
|
||||
mOutputProducerCondition.wait_for(lock, OutputProducerWakeInterval());
|
||||
|
||||
std::lock_guard<std::mutex> lock(mOutputProducerMutex);
|
||||
if (mOutputProducerWorkerStopping)
|
||||
{
|
||||
mOutputProducerWorkerRunning = false;
|
||||
@@ -431,11 +429,22 @@ void VideoBackend::OutputProducerWorkerMain()
|
||||
}
|
||||
}
|
||||
|
||||
ScheduleReadyOutputFramesToTarget();
|
||||
|
||||
const RenderOutputQueueMetrics metrics = mReadyOutputQueue.GetMetrics();
|
||||
RecordReadyQueueDepthSample(metrics);
|
||||
const OutputProductionDecision decision = mOutputProductionController.Decide(BuildOutputProductionPressure(metrics));
|
||||
if (decision.action != OutputProductionAction::Produce || decision.requestedFrames == 0)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mOutputProducerMutex);
|
||||
mOutputProducerCondition.wait_for(lock, OutputProducerWakeInterval());
|
||||
if (mOutputProducerWorkerStopping)
|
||||
{
|
||||
mOutputProducerWorkerRunning = false;
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
VideoIOCompletion completion;
|
||||
{
|
||||
@@ -445,15 +454,32 @@ void VideoBackend::OutputProducerWorkerMain()
|
||||
completion = mLastOutputProductionCompletion;
|
||||
}
|
||||
|
||||
const bool belowTargetDepth = metrics.depth < decision.targetReadyFrames;
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
if (mLastOutputProductionTime != std::chrono::steady_clock::time_point() &&
|
||||
if (!belowTargetDepth &&
|
||||
mLastOutputProductionTime != std::chrono::steady_clock::time_point() &&
|
||||
now - mLastOutputProductionTime < OutputProducerWakeInterval())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ProduceReadyOutputFrames(completion, 1) > 0)
|
||||
const std::size_t producedFrames = ProduceReadyOutputFrames(completion, decision.requestedFrames);
|
||||
if (producedFrames > 0)
|
||||
{
|
||||
mLastOutputProductionTime = std::chrono::steady_clock::now();
|
||||
ScheduleReadyOutputFramesToTarget();
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mOutputProducerMutex);
|
||||
mOutputProducerCondition.wait_for(lock, OutputProducerWakeInterval());
|
||||
if (mOutputProducerWorkerStopping)
|
||||
{
|
||||
mOutputProducerWorkerRunning = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,16 +513,27 @@ void VideoBackend::ProcessOutputFrameCompletion(const VideoIOCompletion& complet
|
||||
}
|
||||
NotifyOutputProducer();
|
||||
|
||||
if (!ScheduleReadyOutputFrame() &&
|
||||
(ProduceReadyOutputFrames(completion, 1) == 0 || !ScheduleReadyOutputFrame()))
|
||||
{
|
||||
ScheduleBlackUnderrunFrame();
|
||||
}
|
||||
NotifyOutputProducer();
|
||||
RecordBackendPlayoutHealth(completion.result, recoveryDecision);
|
||||
RecordSystemMemoryPlayoutStats();
|
||||
}
|
||||
|
||||
std::size_t VideoBackend::ScheduleReadyOutputFramesToTarget()
|
||||
{
|
||||
const std::size_t targetScheduledFrames = static_cast<std::size_t>(mPlayoutPolicy.targetPrerollFrames);
|
||||
std::size_t scheduledFrames = 0;
|
||||
for (;;)
|
||||
{
|
||||
const SystemOutputFramePoolMetrics poolMetrics = mSystemOutputFramePool.GetMetrics();
|
||||
if (poolMetrics.scheduledCount >= targetScheduledFrames)
|
||||
break;
|
||||
if (!ScheduleReadyOutputFrame())
|
||||
break;
|
||||
++scheduledFrames;
|
||||
}
|
||||
return scheduledFrames;
|
||||
}
|
||||
|
||||
void VideoBackend::RecordBackendPlayoutHealth(VideoIOCompletionResult result, const VideoPlayoutRecoveryDecision& recoveryDecision)
|
||||
{
|
||||
const RenderOutputQueueMetrics queueMetrics = mReadyOutputQueue.GetMetrics();
|
||||
@@ -650,6 +687,7 @@ bool VideoBackend::RenderReadyOutputFrame(const VideoIOState& state, const Video
|
||||
|
||||
bool VideoBackend::ScheduleReadyOutputFrame()
|
||||
{
|
||||
std::lock_guard<std::mutex> schedulingLock(mOutputSchedulingMutex);
|
||||
RenderOutputFrame readyFrame;
|
||||
if (!mReadyOutputQueue.TryPop(readyFrame))
|
||||
return false;
|
||||
|
||||
@@ -81,6 +81,7 @@ private:
|
||||
std::size_t ProduceReadyOutputFrames(const VideoIOCompletion& completion, std::size_t maxFrames);
|
||||
OutputProductionPressure BuildOutputProductionPressure(const RenderOutputQueueMetrics& metrics) const;
|
||||
bool RenderReadyOutputFrame(const VideoIOState& state, const VideoIOCompletion& completion);
|
||||
std::size_t ScheduleReadyOutputFramesToTarget();
|
||||
bool ScheduleReadyOutputFrame();
|
||||
bool ScheduleBlackUnderrunFrame();
|
||||
void RecordFramePacing(VideoIOCompletionResult completionResult);
|
||||
@@ -117,6 +118,7 @@ private:
|
||||
VideoIOCompletion mLastOutputProductionCompletion;
|
||||
std::chrono::steady_clock::time_point mLastOutputProductionTime;
|
||||
std::mutex mOutputProductionMutex;
|
||||
std::mutex mOutputSchedulingMutex;
|
||||
mutable std::mutex mOutputMetricsMutex;
|
||||
bool mOutputCompletionWorkerRunning = false;
|
||||
bool mOutputCompletionWorkerStopping = false;
|
||||
|
||||
@@ -11,11 +11,11 @@ enum class VideoUnderrunBehavior
|
||||
struct VideoPlayoutPolicy
|
||||
{
|
||||
unsigned outputFramePoolSize = 10;
|
||||
unsigned targetPrerollFrames = 12;
|
||||
unsigned targetPrerollFrames = 4;
|
||||
unsigned targetReadyFrames = 2;
|
||||
unsigned maxReadyFrames = 4;
|
||||
unsigned minimumSpareDeviceFrames = 1;
|
||||
uint64_t lateOrDropCatchUpFrames = 2;
|
||||
uint64_t lateOrDropCatchUpFrames = 0;
|
||||
VideoUnderrunBehavior underrunBehavior = VideoUnderrunBehavior::ReuseLastCompletedFrame;
|
||||
bool adaptiveHeadroomEnabled = false;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user