Преглед изворни кода

decklink: Query for preroll frame count

Three is recommended though, so use at least that many.
jpark37 пре 2 година
родитељ
комит
e4a80d0396

+ 1 - 0
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)

+ 1 - 0
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})

+ 14 - 6
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<IDeckLinkMutableVideoFrame> 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<DeckLinkDeviceInstance>(this);

+ 1 - 1
plugins/decklink/decklink-device-instance.hpp

@@ -70,7 +70,7 @@ protected:
 	std::vector<uint8_t> frameData;
 	BMDTimeValue frameDuration;
 	BMDTimeScale frameTimescale;
-	size_t totalFramesScheduled;
+	BMDTimeScale totalFramesScheduled;
 	ComPtr<RenderDelegate<DeckLinkDeviceInstance>> renderDelegate;
 
 	void FinalizeStream();

+ 10 - 0
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;

+ 2 - 0
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;