#include "DeckLinkDisplayMode.h" #include std::string NormalizeModeToken(const std::string& value) { std::string normalized; for (unsigned char ch : value) { if (std::isalnum(ch)) normalized.push_back(static_cast(std::tolower(ch))); } return normalized; } bool ResolveConfiguredDeckLinkDisplayMode(const VideoIOModeConfiguration& mode, BMDDisplayMode& displayMode, std::string& displayModeName) { DeckLinkVideoMode videoMode; if (!ResolveConfiguredDeckLinkVideoMode(mode, videoMode)) return false; displayMode = videoMode.displayMode; displayModeName = videoMode.displayName; return true; } bool ResolveConfiguredDeckLinkVideoMode(const VideoIOModeConfiguration& mode, DeckLinkVideoMode& videoMode) { const std::string formatToken = NormalizeModeToken(mode.videoFormat); const std::string frameToken = NormalizeModeToken(mode.frameRate); const std::string combinedToken = formatToken + frameToken; struct ModeOption { const char* token; BMDDisplayMode mode; const char* displayName; }; static const ModeOption options[] = { { "720p50", bmdModeHD720p50, "720p50" }, { "hd720p50", bmdModeHD720p50, "720p50" }, { "720p5994", bmdModeHD720p5994, "720p59.94" }, { "hd720p5994", bmdModeHD720p5994, "720p59.94" }, { "720p60", bmdModeHD720p60, "720p60" }, { "hd720p60", bmdModeHD720p60, "720p60" }, { "1080i50", bmdModeHD1080i50, "1080i50" }, { "hd1080i50", bmdModeHD1080i50, "1080i50" }, { "1080i5994", bmdModeHD1080i5994, "1080i59.94" }, { "hd1080i5994", bmdModeHD1080i5994, "1080i59.94" }, { "1080i60", bmdModeHD1080i6000, "1080i60" }, { "hd1080i60", bmdModeHD1080i6000, "1080i60" }, { "1080p2398", bmdModeHD1080p2398, "1080p23.98" }, { "hd1080p2398", bmdModeHD1080p2398, "1080p23.98" }, { "1080p24", bmdModeHD1080p24, "1080p24" }, { "hd1080p24", bmdModeHD1080p24, "1080p24" }, { "1080p25", bmdModeHD1080p25, "1080p25" }, { "hd1080p25", bmdModeHD1080p25, "1080p25" }, { "1080p2997", bmdModeHD1080p2997, "1080p29.97" }, { "hd1080p2997", bmdModeHD1080p2997, "1080p29.97" }, { "1080p30", bmdModeHD1080p30, "1080p30" }, { "hd1080p30", bmdModeHD1080p30, "1080p30" }, { "1080p50", bmdModeHD1080p50, "1080p50" }, { "hd1080p50", bmdModeHD1080p50, "1080p50" }, { "1080p5994", bmdModeHD1080p5994, "1080p59.94" }, { "hd1080p5994", bmdModeHD1080p5994, "1080p59.94" }, { "1080p60", bmdModeHD1080p6000, "1080p60" }, { "hd1080p60", bmdModeHD1080p6000, "1080p60" }, { "2160p2398", bmdMode4K2160p2398, "2160p23.98" }, { "4k2160p2398", bmdMode4K2160p2398, "2160p23.98" }, { "2160p24", bmdMode4K2160p24, "2160p24" }, { "4k2160p24", bmdMode4K2160p24, "2160p24" }, { "2160p25", bmdMode4K2160p25, "2160p25" }, { "4k2160p25", bmdMode4K2160p25, "2160p25" }, { "2160p2997", bmdMode4K2160p2997, "2160p29.97" }, { "4k2160p2997", bmdMode4K2160p2997, "2160p29.97" }, { "2160p30", bmdMode4K2160p30, "2160p30" }, { "4k2160p30", bmdMode4K2160p30, "2160p30" }, { "2160p50", bmdMode4K2160p50, "2160p50" }, { "4k2160p50", bmdMode4K2160p50, "2160p50" }, { "2160p5994", bmdMode4K2160p5994, "2160p59.94" }, { "4k2160p5994", bmdMode4K2160p5994, "2160p59.94" }, { "2160p60", bmdMode4K2160p60, "2160p60" }, { "4k2160p60", bmdMode4K2160p60, "2160p60" } }; for (const ModeOption& option : options) { if (combinedToken == option.token || (frameToken.empty() && formatToken == option.token)) { videoMode.displayMode = option.mode; videoMode.displayName = option.displayName; return true; } } return false; } bool ResolveConfiguredDeckLinkVideoModes( const VideoIOConfiguration& config, DeckLinkVideoModeSelection& videoModes, std::string& error) { if (!ResolveConfiguredDeckLinkVideoMode(config.inputMode, videoModes.input)) { error = "Unsupported DeckLink input mode in config/runtime-host.json: " + config.inputMode.videoFormat + " / " + config.inputMode.frameRate; return false; } if (!ResolveConfiguredDeckLinkVideoMode(config.outputMode, videoModes.output)) { error = "Unsupported DeckLink output mode in config/runtime-host.json: " + config.outputMode.videoFormat + " / " + config.outputMode.frameRate; return false; } return true; } bool FindDeckLinkDisplayMode(IDeckLinkDisplayModeIterator* iterator, BMDDisplayMode targetMode, IDeckLinkDisplayMode** foundMode) { if (!iterator || !foundMode) return false; *foundMode = NULL; IDeckLinkDisplayMode* candidate = NULL; while (iterator->Next(&candidate) == S_OK) { if (candidate->GetDisplayMode() == targetMode) { *foundMode = candidate; return true; } candidate->Release(); candidate = NULL; } return false; }