decklink separation
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
#include "DeckLinkSession.h"
|
||||
|
||||
#include "GlRenderConstants.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
DeckLinkSession::~DeckLinkSession()
|
||||
{
|
||||
ReleaseResources();
|
||||
}
|
||||
|
||||
void DeckLinkSession::ReleaseResources()
|
||||
{
|
||||
if (input != nullptr)
|
||||
{
|
||||
input->SetCallback(nullptr);
|
||||
if (captureDelegate != nullptr)
|
||||
{
|
||||
captureDelegate->Release();
|
||||
captureDelegate = nullptr;
|
||||
}
|
||||
input->Release();
|
||||
input = nullptr;
|
||||
}
|
||||
|
||||
while (!outputVideoFrameQueue.empty())
|
||||
{
|
||||
IDeckLinkMutableVideoFrame* frameToRelease = outputVideoFrameQueue.front();
|
||||
if (frameToRelease != nullptr)
|
||||
frameToRelease->Release();
|
||||
outputVideoFrameQueue.pop_front();
|
||||
}
|
||||
|
||||
if (output != nullptr)
|
||||
{
|
||||
if (keyer != nullptr)
|
||||
{
|
||||
keyer->Disable();
|
||||
keyer->Release();
|
||||
keyer = nullptr;
|
||||
externalKeyingActive = false;
|
||||
}
|
||||
output->SetScheduledFrameCompletionCallback(nullptr);
|
||||
if (playoutDelegate != nullptr)
|
||||
{
|
||||
playoutDelegate->Release();
|
||||
playoutDelegate = nullptr;
|
||||
}
|
||||
output->Release();
|
||||
output = nullptr;
|
||||
}
|
||||
|
||||
if (playoutAllocator != nullptr)
|
||||
{
|
||||
playoutAllocator->Release();
|
||||
playoutAllocator = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool DeckLinkSession::Start(unsigned outputHeight)
|
||||
{
|
||||
totalPlayoutFrames = 0;
|
||||
if (!output)
|
||||
{
|
||||
MessageBoxA(NULL, "Cannot start playout because no DeckLink output device is available.", "DeckLink start failed", MB_OK | MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
if (outputVideoFrameQueue.empty())
|
||||
{
|
||||
MessageBoxA(NULL, "Cannot start playout because the output frame queue is empty.", "DeckLink start failed", MB_OK | MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < kPrerollFrameCount; i++)
|
||||
{
|
||||
IDeckLinkMutableVideoFrame* outputVideoFrame = outputVideoFrameQueue.front();
|
||||
outputVideoFrameQueue.push_back(outputVideoFrame);
|
||||
outputVideoFrameQueue.pop_front();
|
||||
|
||||
IDeckLinkVideoBuffer* outputVideoFrameBuffer;
|
||||
if (outputVideoFrame->QueryInterface(IID_IDeckLinkVideoBuffer, (void**)&outputVideoFrameBuffer) != S_OK)
|
||||
{
|
||||
MessageBoxA(NULL, "Could not query the preroll output frame buffer.", "DeckLink start failed", MB_OK | MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (outputVideoFrameBuffer->StartAccess(bmdBufferAccessWrite) != S_OK)
|
||||
{
|
||||
outputVideoFrameBuffer->Release();
|
||||
MessageBoxA(NULL, "Could not write to the preroll output frame buffer.", "DeckLink start failed", MB_OK | MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
void* pFrame;
|
||||
outputVideoFrameBuffer->GetBytes((void**)&pFrame);
|
||||
memset(pFrame, 0, outputVideoFrame->GetRowBytes() * outputHeight);
|
||||
|
||||
outputVideoFrameBuffer->EndAccess(bmdBufferAccessWrite);
|
||||
outputVideoFrameBuffer->Release();
|
||||
|
||||
if (output->ScheduleVideoFrame(outputVideoFrame, (totalPlayoutFrames * frameDuration), frameDuration, frameTimescale) != S_OK)
|
||||
{
|
||||
MessageBoxA(NULL, "Could not schedule a preroll output frame.", "DeckLink start failed", MB_OK | MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
totalPlayoutFrames++;
|
||||
}
|
||||
|
||||
if (input)
|
||||
{
|
||||
if (input->StartStreams() != S_OK)
|
||||
{
|
||||
MessageBoxA(NULL, "Could not start the DeckLink input stream.", "DeckLink start failed", MB_OK | MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (output->StartScheduledPlayback(0, frameTimescale, 1.0) != S_OK)
|
||||
{
|
||||
MessageBoxA(NULL, "Could not start DeckLink scheduled playback.", "DeckLink start failed", MB_OK | MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeckLinkSession::Stop()
|
||||
{
|
||||
if (keyer != nullptr)
|
||||
{
|
||||
keyer->Disable();
|
||||
externalKeyingActive = false;
|
||||
}
|
||||
|
||||
if (input)
|
||||
{
|
||||
input->StopStreams();
|
||||
input->DisableVideoInput();
|
||||
}
|
||||
|
||||
if (output)
|
||||
{
|
||||
output->StopScheduledPlayback(0, NULL, 0);
|
||||
output->DisableVideoOutput();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user