more seperation

This commit is contained in:
Aiden
2026-05-10 23:53:27 +10:00
parent 7f0f60c0e3
commit 41075bbc61
25 changed files with 733 additions and 1031 deletions

View File

@@ -417,11 +417,21 @@ double DeckLinkSession::FrameBudgetMilliseconds() const
return mScheduler.FrameBudgetMilliseconds();
}
bool DeckLinkSession::BeginOutputFrame(VideoIOOutputFrame& frame)
bool DeckLinkSession::AcquireNextOutputVideoFrame(CComPtr<IDeckLinkMutableVideoFrame>& outputVideoFrame)
{
CComPtr<IDeckLinkMutableVideoFrame> outputVideoFrame = outputVideoFrameQueue.front();
if (outputVideoFrameQueue.empty())
return false;
outputVideoFrame = outputVideoFrameQueue.front();
outputVideoFrameQueue.push_back(outputVideoFrame);
outputVideoFrameQueue.pop_front();
return outputVideoFrame != nullptr;
}
bool DeckLinkSession::PopulateOutputFrame(IDeckLinkMutableVideoFrame* outputVideoFrame, VideoIOOutputFrame& frame)
{
if (outputVideoFrame == nullptr)
return false;
CComPtr<IDeckLinkVideoBuffer> outputVideoFrameBuffer;
if (outputVideoFrame->QueryInterface(IID_IDeckLinkVideoBuffer, (void**)&outputVideoFrameBuffer) != S_OK)
@@ -438,11 +448,44 @@ bool DeckLinkSession::BeginOutputFrame(VideoIOOutputFrame& frame)
frame.width = mState.outputFrameSize.width;
frame.height = mState.outputFrameSize.height;
frame.pixelFormat = mState.outputPixelFormat;
frame.nativeFrame = outputVideoFrame.p;
frame.nativeFrame = outputVideoFrame;
frame.nativeBuffer = outputVideoFrameBuffer.Detach();
return true;
}
bool DeckLinkSession::ScheduleFrame(IDeckLinkMutableVideoFrame* outputVideoFrame)
{
const VideoIOScheduleTime scheduleTime = mScheduler.NextScheduleTime();
return outputVideoFrame != nullptr &&
output->ScheduleVideoFrame(outputVideoFrame, scheduleTime.streamTime, scheduleTime.duration, scheduleTime.timeScale) == S_OK;
}
bool DeckLinkSession::ScheduleBlackFrame(IDeckLinkMutableVideoFrame* outputVideoFrame)
{
if (outputVideoFrame == nullptr)
return false;
CComPtr<IDeckLinkVideoBuffer> outputVideoFrameBuffer;
if (outputVideoFrame->QueryInterface(IID_IDeckLinkVideoBuffer, (void**)&outputVideoFrameBuffer) != S_OK)
return false;
if (outputVideoFrameBuffer->StartAccess(bmdBufferAccessWrite) != S_OK)
return false;
void* pFrame = nullptr;
outputVideoFrameBuffer->GetBytes((void**)&pFrame);
memset(pFrame, 0, outputVideoFrame->GetRowBytes() * mState.outputFrameSize.height);
outputVideoFrameBuffer->EndAccess(bmdBufferAccessWrite);
return ScheduleFrame(outputVideoFrame);
}
bool DeckLinkSession::BeginOutputFrame(VideoIOOutputFrame& frame)
{
CComPtr<IDeckLinkMutableVideoFrame> outputVideoFrame;
return AcquireNextOutputVideoFrame(outputVideoFrame) && PopulateOutputFrame(outputVideoFrame, frame);
}
void DeckLinkSession::EndOutputFrame(VideoIOOutputFrame& frame)
{
IDeckLinkVideoBuffer* outputVideoFrameBuffer = static_cast<IDeckLinkVideoBuffer*>(frame.nativeBuffer);
@@ -463,11 +506,7 @@ void DeckLinkSession::AccountForCompletionResult(VideoIOCompletionResult complet
bool DeckLinkSession::ScheduleOutputFrame(const VideoIOOutputFrame& frame)
{
IDeckLinkMutableVideoFrame* outputVideoFrame = static_cast<IDeckLinkMutableVideoFrame*>(frame.nativeFrame);
const VideoIOScheduleTime scheduleTime = mScheduler.NextScheduleTime();
if (outputVideoFrame == nullptr || output->ScheduleVideoFrame(outputVideoFrame, scheduleTime.streamTime, scheduleTime.duration, scheduleTime.timeScale) != S_OK)
return false;
return true;
return ScheduleFrame(outputVideoFrame);
}
bool DeckLinkSession::Start()
@@ -486,31 +525,13 @@ bool DeckLinkSession::Start()
for (unsigned i = 0; i < kPrerollFrameCount; i++)
{
CComPtr<IDeckLinkMutableVideoFrame> outputVideoFrame = outputVideoFrameQueue.front();
outputVideoFrameQueue.push_back(outputVideoFrame);
outputVideoFrameQueue.pop_front();
CComPtr<IDeckLinkVideoBuffer> outputVideoFrameBuffer;
if (outputVideoFrame->QueryInterface(IID_IDeckLinkVideoBuffer, (void**)&outputVideoFrameBuffer) != S_OK)
CComPtr<IDeckLinkMutableVideoFrame> outputVideoFrame;
if (!AcquireNextOutputVideoFrame(outputVideoFrame))
{
MessageBoxA(NULL, "Could not query the preroll output frame buffer.", "DeckLink start failed", MB_OK | MB_ICONERROR);
MessageBoxA(NULL, "Could not acquire a preroll output frame.", "DeckLink start failed", MB_OK | MB_ICONERROR);
return false;
}
if (outputVideoFrameBuffer->StartAccess(bmdBufferAccessWrite) != S_OK)
{
MessageBoxA(NULL, "Could not write to the preroll output frame buffer.", "DeckLink start failed", MB_OK | MB_ICONERROR);
return false;
}
void* pFrame = nullptr;
outputVideoFrameBuffer->GetBytes((void**)&pFrame);
memset(pFrame, 0, outputVideoFrame->GetRowBytes() * mState.outputFrameSize.height);
outputVideoFrameBuffer->EndAccess(bmdBufferAccessWrite);
const VideoIOScheduleTime scheduleTime = mScheduler.NextScheduleTime();
if (output->ScheduleVideoFrame(outputVideoFrame, scheduleTime.streamTime, scheduleTime.duration, scheduleTime.timeScale) != S_OK)
if (!ScheduleBlackFrame(outputVideoFrame))
{
MessageBoxA(NULL, "Could not schedule a preroll output frame.", "DeckLink start failed", MB_OK | MB_ICONERROR);
return false;
@@ -599,23 +620,23 @@ void DeckLinkSession::HandlePlayoutFrameCompleted(IDeckLinkVideoFrame*, BMDOutpu
return;
VideoIOCompletion completion;
completion.result = TranslateCompletionResult(completionResult);
mOutputFrameCallback(completion);
}
VideoIOCompletionResult DeckLinkSession::TranslateCompletionResult(BMDOutputFrameCompletionResult completionResult)
{
switch (completionResult)
{
case bmdOutputFrameDisplayedLate:
completion.result = VideoIOCompletionResult::DisplayedLate;
break;
return VideoIOCompletionResult::DisplayedLate;
case bmdOutputFrameDropped:
completion.result = VideoIOCompletionResult::Dropped;
break;
return VideoIOCompletionResult::Dropped;
case bmdOutputFrameFlushed:
completion.result = VideoIOCompletionResult::Flushed;
break;
return VideoIOCompletionResult::Flushed;
case bmdOutputFrameCompleted:
completion.result = VideoIOCompletionResult::Completed;
break;
return VideoIOCompletionResult::Completed;
default:
completion.result = VideoIOCompletionResult::Unknown;
break;
return VideoIOCompletionResult::Unknown;
}
mOutputFrameCallback(completion);
}

View File

@@ -66,6 +66,12 @@ public:
void HandlePlayoutFrameCompleted(IDeckLinkVideoFrame* completedFrame, BMDOutputFrameCompletionResult completionResult);
private:
bool AcquireNextOutputVideoFrame(CComPtr<IDeckLinkMutableVideoFrame>& outputVideoFrame);
bool PopulateOutputFrame(IDeckLinkMutableVideoFrame* outputVideoFrame, VideoIOOutputFrame& frame);
bool ScheduleFrame(IDeckLinkMutableVideoFrame* outputVideoFrame);
bool ScheduleBlackFrame(IDeckLinkMutableVideoFrame* outputVideoFrame);
static VideoIOCompletionResult TranslateCompletionResult(BMDOutputFrameCompletionResult completionResult);
CComPtr<CaptureDelegate> captureDelegate;
CComPtr<PlayoutDelegate> playoutDelegate;
CComPtr<IDeckLinkInput> input;