Video backend
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m43s
CI / Windows Release Package (push) Successful in 2m54s

This commit is contained in:
Aiden
2026-05-09 14:15:49 +10:00
parent 98f5cbe309
commit 4ffbb97abf
21 changed files with 512 additions and 275 deletions

View File

@@ -1,5 +1,3 @@
#include "DeckLinkDisplayMode.h"
#include "DeckLinkSession.h"
#include "OpenGLComposite.h"
#include "GLExtensions.h"
#include "GlRenderConstants.h"
@@ -10,6 +8,7 @@
#include "PngScreenshotWriter.h"
#include "RuntimeServices.h"
#include "ShaderBuildQueue.h"
#include "VideoIOBackendFactory.h"
#include <algorithm>
#include <chrono>
@@ -23,7 +22,6 @@
OpenGLComposite::OpenGLComposite(HWND hWnd, HDC hDC, HGLRC hRC) :
hGLWnd(hWnd), hGLDC(hDC), hGLRC(hRC),
mVideoIO(std::make_unique<DeckLinkSession>()),
mRenderer(std::make_unique<OpenGLRenderer>()),
mUseCommittedLayerStates(false),
mScreenshotRequested(false)
@@ -37,7 +35,7 @@ OpenGLComposite::OpenGLComposite(HWND hWnd, HDC hDC, HGLRC hRC) :
[this]() { ProcessScreenshotRequest(); },
[this]() { paintGL(); });
mVideoIOBridge = std::make_unique<OpenGLVideoIOBridge>(
*mVideoIO,
nullptr,
*mRenderer,
*mRenderPipeline,
*mRuntimeHost,
@@ -56,20 +54,15 @@ OpenGLComposite::~OpenGLComposite()
mRuntimeServices->Stop();
if (mShaderBuildQueue)
mShaderBuildQueue->Stop();
mVideoIO->ReleaseResources();
if (mVideoIO)
mVideoIO->ReleaseResources();
mRenderer->DestroyResources();
DeleteCriticalSection(&pMutex);
}
bool OpenGLComposite::InitDeckLink()
bool OpenGLComposite::InitializeVideoIO()
{
return InitVideoIO();
}
bool OpenGLComposite::InitVideoIO()
{
VideoFormatSelection videoModes;
std::string initFailureReason;
if (mRuntimeHost && mRuntimeHost->GetRepoRoot().empty())
@@ -82,31 +75,31 @@ bool OpenGLComposite::InitVideoIO()
}
}
if (mRuntimeHost)
if (!mRuntimeHost)
{
if (!ResolveConfiguredVideoFormats(
mRuntimeHost->GetInputVideoFormat(),
mRuntimeHost->GetInputFrameRate(),
mRuntimeHost->GetOutputVideoFormat(),
mRuntimeHost->GetOutputFrameRate(),
videoModes,
initFailureReason))
{
MessageBoxA(NULL, initFailureReason.c_str(), "DeckLink mode configuration error", MB_OK);
return false;
}
initFailureReason = "Runtime host is not available.";
MessageBoxA(NULL, initFailureReason.c_str(), "Video I/O initialization failed", MB_OK | MB_ICONERROR);
return false;
}
if (!mVideoIO->DiscoverDevicesAndModes(videoModes, initFailureReason))
const VideoIOConfiguration videoIOConfig = mRuntimeHost->GetVideoIOConfiguration();
mVideoIO = CreateVideoIODevice(videoIOConfig.backendId, initFailureReason);
if (!mVideoIO)
{
MessageBoxA(NULL, initFailureReason.c_str(), "Video I/O initialization failed", MB_OK | MB_ICONERROR);
return false;
}
mVideoIOBridge->SetVideoIODevice(mVideoIO.get());
if (!mVideoIO->DiscoverDevicesAndModes(videoIOConfig, initFailureReason))
{
const char* title = initFailureReason == "Please install the Blackmagic DeckLink drivers to use the features of this application."
? "This application requires the DeckLink drivers installed."
: "DeckLink initialization failed";
? "This application requires the selected video I/O drivers installed."
: "Video I/O initialization failed";
MessageBoxA(NULL, initFailureReason.c_str(), title, MB_OK | MB_ICONERROR);
return false;
}
const bool outputAlphaRequired = mRuntimeHost && mRuntimeHost->ExternalKeyingEnabled();
if (!mVideoIO->SelectPreferredFormats(videoModes, outputAlphaRequired, initFailureReason))
if (!mVideoIO->SelectPreferredFormats(videoIOConfig, initFailureReason))
goto error;
if (! CheckOpenGLExtensions())
@@ -121,9 +114,9 @@ bool OpenGLComposite::InitVideoIO()
goto error;
}
PublishVideoIOStatus(mVideoIO->OutputModelName().empty()
? "DeckLink output device selected."
: ("Selected output device: " + mVideoIO->OutputModelName()));
PublishVideoIOStatus(mVideoIO->DeviceName().empty()
? "Video I/O output device selected."
: ("Selected output device: " + mVideoIO->DeviceName()));
// Resize window to match output video frame, but scale large formats down by half for viewing.
if (mVideoIO->OutputFrameWidth() < 1920)
@@ -131,7 +124,7 @@ bool OpenGLComposite::InitVideoIO()
else
resizeWindow(mVideoIO->OutputFrameWidth() / 2, mVideoIO->OutputFrameHeight() / 2);
if (!mVideoIO->ConfigureInput([this](const VideoIOFrame& frame) { mVideoIOBridge->VideoFrameArrived(frame); }, videoModes.input, initFailureReason))
if (!mVideoIO->ConfigureInput([this](const VideoIOFrame& frame) { mVideoIOBridge->VideoFrameArrived(frame); }, initFailureReason))
{
goto error;
}
@@ -140,7 +133,7 @@ bool OpenGLComposite::InitVideoIO()
mRuntimeHost->SetSignalStatus(false, mVideoIO->InputFrameWidth(), mVideoIO->InputFrameHeight(), mVideoIO->InputDisplayModeName());
}
if (!mVideoIO->ConfigureOutput([this](const VideoIOCompletion& completion) { mVideoIOBridge->PlayoutFrameCompleted(completion); }, videoModes.output, mRuntimeHost && mRuntimeHost->ExternalKeyingEnabled(), initFailureReason))
if (!mVideoIO->ConfigureOutput([this](const VideoIOCompletion& completion) { mVideoIOBridge->PlayoutFrameCompleted(completion); }, initFailureReason))
{
goto error;
}
@@ -151,13 +144,16 @@ bool OpenGLComposite::InitVideoIO()
error:
if (!initFailureReason.empty())
MessageBoxA(NULL, initFailureReason.c_str(), "DeckLink initialization failed", MB_OK | MB_ICONERROR);
MessageBoxA(NULL, initFailureReason.c_str(), "Video I/O initialization failed", MB_OK | MB_ICONERROR);
mVideoIO->ReleaseResources();
return false;
}
void OpenGLComposite::paintGL()
{
if (!mVideoIO)
return;
if (!TryEnterCriticalSection(&pMutex))
{
ValidateRect(hGLWnd, NULL);
@@ -187,21 +183,13 @@ void OpenGLComposite::resizeWindow(int width, int height)
void OpenGLComposite::PublishVideoIOStatus(const std::string& statusMessage)
{
if (!mRuntimeHost)
if (!mRuntimeHost || !mVideoIO)
return;
if (!statusMessage.empty())
mVideoIO->SetStatusMessage(statusMessage);
mRuntimeHost->SetVideoIOStatus(
"decklink",
mVideoIO->OutputModelName(),
mVideoIO->SupportsInternalKeying(),
mVideoIO->SupportsExternalKeying(),
mVideoIO->KeyerInterfaceAvailable(),
mRuntimeHost->ExternalKeyingEnabled(),
mVideoIO->ExternalKeyingActive(),
mVideoIO->StatusMessage());
mRuntimeHost->SetVideoIOStatus(mVideoIO->State());
}
bool OpenGLComposite::InitOpenGLState()