Files
video-shader-toys/apps/RenderCadenceCompositor/video/DeckLinkOutput.cpp
Aiden 5c1fc2a6cf
All checks were successful
CI / React UI Build (push) Successful in 10s
CI / Native Windows Build And Tests (push) Successful in 2m58s
CI / Windows Release Package (push) Has been skipped
telemetry and timing updates
2026-05-13 00:21:28 +10:00

113 lines
2.9 KiB
C++

#include "DeckLinkOutput.h"
#include "VideoIOFormat.h"
namespace RenderCadenceCompositor
{
DeckLinkOutput::~DeckLinkOutput()
{
ReleaseResources();
}
bool DeckLinkOutput::Initialize(const DeckLinkOutputConfig& config, CompletionCallback completionCallback, std::string& error)
{
mConfig = config;
mCompletionCallback = completionCallback;
VideoFormatSelection formats;
formats.output = config.outputVideoMode;
if (!mSession.DiscoverDevicesAndModes(formats, error))
return false;
if (!mSession.SelectPreferredFormats(formats, config.outputAlphaRequired, error))
return false;
if (!mSession.ConfigureOutput(
[this](const VideoIOCompletion& completion) { HandleCompletion(completion); },
formats.output,
config.externalKeyingEnabled,
error))
{
return false;
}
if (!mSession.PrepareOutputSchedule())
{
error = "DeckLink output schedule preparation failed.";
return false;
}
return true;
}
bool DeckLinkOutput::StartScheduledPlayback(std::string& error)
{
if (mSession.StartScheduledPlayback())
return true;
error = "DeckLink scheduled playback failed to start.";
return false;
}
bool DeckLinkOutput::ScheduleFrame(const VideoIOOutputFrame& frame)
{
return mSession.ScheduleOutputFrame(frame);
}
void DeckLinkOutput::Stop()
{
mSession.Stop();
}
void DeckLinkOutput::ReleaseResources()
{
mSession.ReleaseResources();
}
const VideoIOState& DeckLinkOutput::State() const
{
return mSession.State();
}
DeckLinkOutputMetrics DeckLinkOutput::Metrics() const
{
DeckLinkOutputMetrics metrics;
metrics.completions = mCompletions.load();
metrics.displayedLate = mDisplayedLate.load();
metrics.dropped = mDropped.load();
metrics.flushed = mFlushed.load();
const VideoIOState& state = mSession.State();
metrics.scheduleFailures = state.deckLinkScheduleFailureCount;
metrics.actualBufferedFramesAvailable = state.actualDeckLinkBufferedFramesAvailable;
metrics.actualBufferedFrames = state.actualDeckLinkBufferedFrames;
metrics.scheduleCallMilliseconds = state.deckLinkScheduleCallMilliseconds;
metrics.scheduleLeadAvailable = state.deckLinkScheduleLeadAvailable;
metrics.playbackStreamTime = state.deckLinkPlaybackStreamTime;
metrics.playbackFrameIndex = state.deckLinkPlaybackFrameIndex;
metrics.nextScheduleFrameIndex = state.deckLinkNextScheduleFrameIndex;
metrics.scheduleLeadFrames = state.deckLinkScheduleLeadFrames;
metrics.scheduleRealignmentCount = state.deckLinkScheduleRealignmentCount;
return metrics;
}
void DeckLinkOutput::HandleCompletion(const VideoIOCompletion& completion)
{
++mCompletions;
switch (completion.result)
{
case VideoIOCompletionResult::DisplayedLate:
++mDisplayedLate;
break;
case VideoIOCompletionResult::Dropped:
++mDropped;
break;
case VideoIOCompletionResult::Flushed:
++mFlushed;
break;
case VideoIOCompletionResult::Completed:
case VideoIOCompletionResult::Unknown:
default:
break;
}
if (mCompletionCallback)
mCompletionCallback(completion);
}
}