From e4a80d0396feef0907d0787f40edb3eaeb4f2ac3 Mon Sep 17 00:00:00 2001 From: jpark37 Date: Tue, 28 Mar 2023 13:47:36 -0700 Subject: [PATCH] decklink: Query for preroll frame count Three is recommended though, so use at least that many. --- plugins/decklink/CMakeLists.txt | 1 + plugins/decklink/cmake/legacy.cmake | 1 + plugins/decklink/decklink-device-instance.cpp | 20 +++++++++++++------ plugins/decklink/decklink-device-instance.hpp | 2 +- plugins/decklink/decklink-device.cpp | 10 ++++++++++ plugins/decklink/decklink-device.hpp | 2 ++ 6 files changed, 29 insertions(+), 7 deletions(-) diff --git a/plugins/decklink/CMakeLists.txt b/plugins/decklink/CMakeLists.txt index a90734893..f3df2653c 100644 --- a/plugins/decklink/CMakeLists.txt +++ b/plugins/decklink/CMakeLists.txt @@ -49,6 +49,7 @@ target_link_libraries(decklink PRIVATE OBS::libobs OBS::caption Decklink::SDK) if(OS_WINDOWS) configure_file(cmake/windows/obs-module.rc.in win-decklink.rc) + target_compile_definitions(decklink PRIVATE NOMINMAX) target_sources(decklink PRIVATE win/platform.cpp win-decklink.rc) include(idlfilehelper) diff --git a/plugins/decklink/cmake/legacy.cmake b/plugins/decklink/cmake/legacy.cmake index c618e8b0b..b30c3ae43 100644 --- a/plugins/decklink/cmake/legacy.cmake +++ b/plugins/decklink/cmake/legacy.cmake @@ -58,6 +58,7 @@ if(OS_WINDOWS) set(MODULE_DESCRIPTION "OBS DeckLink Windows module") configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in win-decklink.rc) + target_compile_definitions(decklink PRIVATE NOMINMAX) target_sources(decklink PRIVATE win/platform.cpp win-decklink.rc) target_sources(decklink-sdk INTERFACE win/decklink-sdk/DeckLinkAPIVersion.h ${win-decklink-sdk_GENERATED_FILES}) diff --git a/plugins/decklink/decklink-device-instance.cpp b/plugins/decklink/decklink-device-instance.cpp index 71a8ec10c..9eb8ec941 100644 --- a/plugins/decklink/decklink-device-instance.cpp +++ b/plugins/decklink/decklink-device-instance.cpp @@ -614,8 +614,9 @@ bool DeckLinkDeviceInstance::StartOutput(DeckLinkDeviceMode *mode_) } frameData.clear(); - size_t i = 0; - for (; i < 3; ++i) { + const int64_t minimumPrerollFrames = + std::max(device->GetMinimumPrerollFrames(), INT64_C(3)); + for (int64_t i = 0; i < minimumPrerollFrames; ++i) { ComPtr decklinkOutputFrame; HRESULT result = output_->CreateVideoFrame( decklinkOutput->GetWidth(), decklinkOutput->GetHeight(), @@ -630,11 +631,18 @@ bool DeckLinkDeviceInstance::StartOutput(DeckLinkDeviceMode *mode_) const long size = decklinkOutputFrame->GetRowBytes() * decklinkOutputFrame->GetHeight(); frameData.resize(size); - output_->ScheduleVideoFrame(decklinkOutputFrame, - (i * frameDuration), frameDuration, - frameTimescale); + result = output_->ScheduleVideoFrame(decklinkOutputFrame, + i * frameDuration, + frameDuration, + frameTimescale); + if (result != S_OK) { + blog(LOG_ERROR, + "failed to schedule video frame for preroll 0x%X", + result); + return false; + } } - totalFramesScheduled = i; + totalFramesScheduled = minimumPrerollFrames; *renderDelegate.Assign() = new RenderDelegate(this); diff --git a/plugins/decklink/decklink-device-instance.hpp b/plugins/decklink/decklink-device-instance.hpp index aaad97972..47596fc8d 100644 --- a/plugins/decklink/decklink-device-instance.hpp +++ b/plugins/decklink/decklink-device-instance.hpp @@ -70,7 +70,7 @@ protected: std::vector frameData; BMDTimeValue frameDuration; BMDTimeScale frameTimescale; - size_t totalFramesScheduled; + BMDTimeScale totalFramesScheduled; ComPtr> renderDelegate; void FinalizeStream(); diff --git a/plugins/decklink/decklink-device.cpp b/plugins/decklink/decklink-device.cpp index 5e6d16d28..1d67aae3c 100644 --- a/plugins/decklink/decklink-device.cpp +++ b/plugins/decklink/decklink-device.cpp @@ -114,6 +114,11 @@ bool DeckLinkDevice::Init() attributes->GetInt(BMDDeckLinkSubDeviceIndex, &subDeviceIndex); attributes->GetInt(BMDDeckLinkNumberOfSubDevices, &numSubDevices); + if (FAILED(attributes->GetInt(BMDDeckLinkMinimumPrerollFrames, + &minimumPrerollFrames))) { + minimumPrerollFrames = 3; + } + decklink_string_t decklinkModelName; decklink_string_t decklinkDisplayName; @@ -255,6 +260,11 @@ int64_t DeckLinkDevice::GetSubDeviceIndex() return subDeviceIndex; } +int64_t DeckLinkDevice::GetMinimumPrerollFrames() +{ + return minimumPrerollFrames; +} + const std::string &DeckLinkDevice::GetName(void) const { return name; diff --git a/plugins/decklink/decklink-device.hpp b/plugins/decklink/decklink-device.hpp index b9dac04b0..290118d80 100644 --- a/plugins/decklink/decklink-device.hpp +++ b/plugins/decklink/decklink-device.hpp @@ -21,6 +21,7 @@ class DeckLinkDevice { decklink_bool_t supportsInternalKeyer = false; int64_t subDeviceIndex = 0; int64_t numSubDevices = 0; + int64_t minimumPrerollFrames = 3; int64_t supportedVideoInputConnections = -1; int64_t supportedVideoOutputConnections = -1; int64_t supportedAudioInputConnections = -1; @@ -49,6 +50,7 @@ public: bool GetSupportsInternalKeyer(void) const; int64_t GetSubDeviceCount(); int64_t GetSubDeviceIndex(); + int64_t GetMinimumPrerollFrames(); int GetKeyerMode(void); void SetKeyerMode(int newKeyerMode); const std::string &GetName(void) const;