Decklink separation

This commit is contained in:
Aiden
2026-05-09 14:42:11 +10:00
parent 4ffbb97abf
commit 46f2f1ece5
4 changed files with 93 additions and 5 deletions

View File

@@ -83,6 +83,7 @@ bool OpenGLComposite::InitializeVideoIO()
} }
const VideoIOConfiguration videoIOConfig = mRuntimeHost->GetVideoIOConfiguration(); const VideoIOConfiguration videoIOConfig = mRuntimeHost->GetVideoIOConfiguration();
const VideoIOBackendDescriptor* backendDescriptor = GetVideoIOBackendDescriptor(videoIOConfig.backendId);
mVideoIO = CreateVideoIODevice(videoIOConfig.backendId, initFailureReason); mVideoIO = CreateVideoIODevice(videoIOConfig.backendId, initFailureReason);
if (!mVideoIO) if (!mVideoIO)
{ {
@@ -93,8 +94,8 @@ bool OpenGLComposite::InitializeVideoIO()
if (!mVideoIO->DiscoverDevicesAndModes(videoIOConfig, initFailureReason)) if (!mVideoIO->DiscoverDevicesAndModes(videoIOConfig, initFailureReason))
{ {
const char* title = initFailureReason == "Please install the Blackmagic DeckLink drivers to use the features of this application." const char* title = IsVideoIOBackendUnavailableError(videoIOConfig.backendId, initFailureReason) && backendDescriptor != nullptr
? "This application requires the selected video I/O drivers installed." ? backendDescriptor->unavailableTitle
: "Video I/O initialization failed"; : "Video I/O initialization failed";
MessageBoxA(NULL, initFailureReason.c_str(), title, MB_OK | MB_ICONERROR); MessageBoxA(NULL, initFailureReason.c_str(), title, MB_OK | MB_ICONERROR);
return false; return false;

View File

@@ -3,14 +3,73 @@
#include "DeckLinkSession.h" #include "DeckLinkSession.h"
#include "VideoIOTypes.h" #include "VideoIOTypes.h"
#include <array>
namespace
{
struct VideoIOBackendRegistration
{
VideoIOBackendDescriptor descriptor;
VideoIODeviceFactory factory;
};
const std::array<VideoIOBackendRegistration, 1>& RegisteredBackends()
{
static const std::array<VideoIOBackendRegistration, 1> backends = { {
{
{
VideoIOBackendId::DeckLink,
"decklink",
"Blackmagic DeckLink",
"Please install the Blackmagic DeckLink drivers to use the features of this application.",
"This application requires the selected video I/O drivers installed."
},
[]() { return std::make_unique<DeckLinkSession>(); }
}
} };
return backends;
}
}
const VideoIOBackendDescriptor* GetVideoIOBackendDescriptor(VideoIOBackendId backendId)
{
for (const VideoIOBackendRegistration& registration : RegisteredBackends())
{
if (registration.descriptor.backendId == backendId)
return &registration.descriptor;
}
return nullptr;
}
std::vector<VideoIOBackendDescriptor> ListVideoIOBackendDescriptors()
{
std::vector<VideoIOBackendDescriptor> descriptors;
descriptors.reserve(RegisteredBackends().size());
for (const VideoIOBackendRegistration& registration : RegisteredBackends())
descriptors.push_back(registration.descriptor);
return descriptors;
}
std::unique_ptr<VideoIODevice> CreateVideoIODevice(VideoIOBackendId backendId, std::string& error) std::unique_ptr<VideoIODevice> CreateVideoIODevice(VideoIOBackendId backendId, std::string& error)
{ {
switch (backendId) for (const VideoIOBackendRegistration& registration : RegisteredBackends())
{ {
case VideoIOBackendId::DeckLink: if (registration.descriptor.backendId != backendId)
return std::make_unique<DeckLinkSession>(); continue;
error.clear();
return registration.factory ? registration.factory() : nullptr;
} }
error = "Unsupported video I/O backend."; error = "Unsupported video I/O backend.";
return nullptr; return nullptr;
} }
bool IsVideoIOBackendUnavailableError(VideoIOBackendId backendId, const std::string& error)
{
const VideoIOBackendDescriptor* descriptor = GetVideoIOBackendDescriptor(backendId);
return descriptor != nullptr &&
descriptor->unavailableMessage != nullptr &&
*descriptor->unavailableMessage != '\0' &&
error == descriptor->unavailableMessage;
}

View File

@@ -2,9 +2,25 @@
#include "VideoIOConfig.h" #include "VideoIOConfig.h"
#include <functional>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector>
class VideoIODevice; class VideoIODevice;
struct VideoIOBackendDescriptor
{
VideoIOBackendId backendId = VideoIOBackendId::DeckLink;
const char* backendName = "decklink";
const char* displayName = "Blackmagic DeckLink";
const char* unavailableMessage = "";
const char* unavailableTitle = "Video I/O initialization failed";
};
using VideoIODeviceFactory = std::function<std::unique_ptr<VideoIODevice>()>;
const VideoIOBackendDescriptor* GetVideoIOBackendDescriptor(VideoIOBackendId backendId);
std::vector<VideoIOBackendDescriptor> ListVideoIOBackendDescriptors();
std::unique_ptr<VideoIODevice> CreateVideoIODevice(VideoIOBackendId backendId, std::string& error); std::unique_ptr<VideoIODevice> CreateVideoIODevice(VideoIOBackendId backendId, std::string& error);
bool IsVideoIOBackendUnavailableError(VideoIOBackendId backendId, const std::string& error);

View File

@@ -19,6 +19,18 @@ void Expect(bool condition, const char* message)
int main() int main()
{ {
const std::vector<VideoIOBackendDescriptor> backends = ListVideoIOBackendDescriptors();
Expect(!backends.empty(), "backend registry is not empty");
Expect(backends.front().backendId == VideoIOBackendId::DeckLink, "decklink is registered");
Expect(std::string(backends.front().backendName) == "decklink", "decklink registry name is stable");
const VideoIOBackendDescriptor* descriptor = GetVideoIOBackendDescriptor(VideoIOBackendId::DeckLink);
Expect(descriptor != nullptr, "decklink descriptor can be looked up");
Expect(descriptor != nullptr && std::string(descriptor->displayName) == "Blackmagic DeckLink", "decklink descriptor exposes display name");
Expect(descriptor != nullptr && std::string(descriptor->unavailableTitle) == "This application requires the selected video I/O drivers installed.", "decklink descriptor exposes unavailable title");
Expect(IsVideoIOBackendUnavailableError(VideoIOBackendId::DeckLink, "Please install the Blackmagic DeckLink drivers to use the features of this application."), "decklink unavailable message is recognized");
Expect(!IsVideoIOBackendUnavailableError(VideoIOBackendId::DeckLink, "some other error"), "non-driver errors are not treated as backend unavailable");
std::string error; std::string error;
std::unique_ptr<VideoIODevice> device = CreateVideoIODevice(VideoIOBackendId::DeckLink, error); std::unique_ptr<VideoIODevice> device = CreateVideoIODevice(VideoIOBackendId::DeckLink, error);
Expect(device != nullptr, "decklink backend factory returns a device"); Expect(device != nullptr, "decklink backend factory returns a device");