Browse Source

decklink: Allow selecting input connections.

Colin Edwards 6 years ago
parent
commit
818001fb59

+ 11 - 3
plugins/decklink/DecklinkInput.cpp

@@ -26,16 +26,20 @@ void DeckLinkInput::DevicesChanged(void *param, DeckLinkDevice *device, bool add
 		const char *hash;
 		long long mode;
 		obs_data_t *settings;
+		BMDVideoConnection videoConnection;
+		BMDAudioConnection audioConnection;
 
 		settings = obs_source_get_settings(decklink->source);
 		hash = obs_data_get_string(settings, "device_hash");
+		videoConnection = (BMDVideoConnection) obs_data_get_int(settings, "video_connection");
+		audioConnection = (BMDAudioConnection) obs_data_get_int(settings, "audio_connection");
 		mode = obs_data_get_int(settings, "mode_id");
 		obs_data_release(settings);
 
 		if (device->GetHash().compare(hash) == 0) {
 			if (!decklink->activateRefs)
 				return;
-			if (decklink->Activate(device, mode))
+			if (decklink->Activate(device, mode, videoConnection, audioConnection))
 				os_atomic_dec_long(&decklink->activateRefs);
 		}
 
@@ -47,7 +51,9 @@ void DeckLinkInput::DevicesChanged(void *param, DeckLinkDevice *device, bool add
 	}
 }
 
-bool DeckLinkInput::Activate(DeckLinkDevice *device, long long modeId)
+bool DeckLinkInput::Activate(DeckLinkDevice *device, long long modeId,
+		BMDVideoConnection bmdVideoConnection,
+		BMDAudioConnection bmdAudioConnection)
 {
 	std::lock_guard<std::recursive_mutex> lock(deviceMutex);
 	DeckLinkDevice *curDevice = GetDevice();
@@ -58,6 +64,8 @@ bool DeckLinkInput::Activate(DeckLinkDevice *device, long long modeId)
 		if (!isActive)
 			return false;
 		if (instance->GetActiveModeId() == modeId &&
+		    instance->GetVideoConnection() == bmdVideoConnection &&
+		    instance->GetAudioConnection() == bmdAudioConnection &&
 		    instance->GetActivePixelFormat() == pixelFormat &&
 		    instance->GetActiveColorSpace() == colorSpace &&
 		    instance->GetActiveColorRange() == colorRange &&
@@ -87,7 +95,7 @@ bool DeckLinkInput::Activate(DeckLinkDevice *device, long long modeId)
 		return false;
 	}
 
-	if (!instance->StartCapture(mode)) {
+	if (!instance->StartCapture(mode, bmdVideoConnection, bmdAudioConnection)) {
 		instance = nullptr;
 		return false;
 	}

+ 5 - 1
plugins/decklink/DecklinkInput.hpp

@@ -39,7 +39,9 @@ public:
 		channelFormat = format;
 	}
 
-	bool Activate(DeckLinkDevice *device, long long modeId);
+	bool Activate(DeckLinkDevice *device, long long modeId,
+			BMDVideoConnection bmdVideoConnection,
+			BMDAudioConnection bmdAudioConnection);
 	void Deactivate();
 	bool Capturing();
 
@@ -48,4 +50,6 @@ public:
 	std::string hash;
 	long long id;
 	bool swap = false;
+	BMDVideoConnection videoConnection;
+	BMDAudioConnection audioConnection;
 };

+ 17 - 13
plugins/decklink/const.h

@@ -1,18 +1,22 @@
-#define DEVICE_HASH     "device_hash"
-#define DEVICE_NAME     "device_name"
-#define MODE_ID         "mode_id"
-#define MODE_NAME       "mode_name"
-#define CHANNEL_FORMAT  "channel_format"
-#define PIXEL_FORMAT    "pixel_format"
-#define COLOR_SPACE     "color_space"
-#define COLOR_RANGE     "color_range"
-#define BUFFERING       "buffering"
-#define DEACTIVATE_WNS  "deactivate_when_not_showing"
-#define AUTO_START      "auto_start"
-#define KEYER           "keyer"
-#define SWAP            "swap"
+#define DEVICE_HASH       "device_hash"
+#define DEVICE_NAME       "device_name"
+#define VIDEO_CONNECTION  "video_connection"
+#define AUDIO_CONNECTION  "audio_connection"
+#define MODE_ID           "mode_id"
+#define MODE_NAME         "mode_name"
+#define CHANNEL_FORMAT    "channel_format"
+#define PIXEL_FORMAT      "pixel_format"
+#define COLOR_SPACE       "color_space"
+#define COLOR_RANGE       "color_range"
+#define BUFFERING         "buffering"
+#define DEACTIVATE_WNS    "deactivate_when_not_showing"
+#define AUTO_START        "auto_start"
+#define KEYER             "keyer"
+#define SWAP              "swap"
 
 #define TEXT_DEVICE                 obs_module_text("Device")
+#define TEXT_VIDEO_CONNECTION       obs_module_text("VideoConnection")
+#define TEXT_AUDIO_CONNECTION       obs_module_text("AudioConnection")
 #define TEXT_MODE                   obs_module_text("Mode")
 #define TEXT_PIXEL_FORMAT           obs_module_text("PixelFormat")
 #define TEXT_COLOR_SPACE            obs_module_text("ColorSpace")

+ 3 - 1
plugins/decklink/data/locale/en-US.ini

@@ -20,4 +20,6 @@ ChannelFormat.7_1ch="7.1ch"
 DeactivateWhenNotShowing="Deactivate when not showing"
 AutoStart="Auto start on launch"
 SwapFC-LFE="Swap FC <-> LFE"
-SwapFC-LFE.Tooltip="Swap Front Channel and LFE Channel"
+SwapFC-LFE.Tooltip="Swap Front Channel and LFE Channel"
+VideoConnection="Video Connection"
+AudioConnection="Audio Connection"

+ 37 - 1
plugins/decklink/decklink-device-instance.cpp

@@ -191,7 +191,9 @@ void DeckLinkDeviceInstance::SetupVideoFormat(DeckLinkDeviceMode *mode_)
 #endif
 }
 
-bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_)
+bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_,
+		BMDVideoConnection bmdVideoConnection,
+		BMDAudioConnection bmdAudioConnection)
 {
 	if (mode != nullptr)
 		return false;
@@ -203,6 +205,40 @@ bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_)
 	if (!device->GetInput(&input))
 		return false;
 
+
+	IDeckLinkConfiguration *deckLinkConfiguration = NULL;
+	HRESULT result = input->QueryInterface(IID_IDeckLinkConfiguration,
+			(void**)&deckLinkConfiguration);
+	if (result != S_OK)
+	{
+		LOG(LOG_ERROR,
+				"Could not obtain the IDeckLinkConfiguration interface: %08x\n",
+				result);
+	} else {
+		if (bmdVideoConnection > 0) {
+			result = deckLinkConfiguration->SetInt(
+					bmdDeckLinkConfigVideoInputConnection, bmdVideoConnection);
+			if (result != S_OK) {
+				LOG(LOG_ERROR,
+						"Couldn't set input video port to %d\n\n",
+						bmdVideoConnection);
+			}
+		}
+
+		if (bmdAudioConnection > 0) {
+			result = deckLinkConfiguration->SetInt(
+					bmdDeckLinkConfigAudioInputConnection, bmdAudioConnection);
+			if (result != S_OK) {
+				LOG(LOG_ERROR,
+						"Couldn't set input audio port to %d\n\n",
+						bmdVideoConnection);
+			}
+		}
+	}
+
+	videoConnection = bmdVideoConnection;
+	audioConnection = bmdAudioConnection;
+
 	BMDVideoInputFlags flags;
 
 	bool isauto = mode_->GetName() == "Auto";

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

@@ -16,6 +16,8 @@ protected:
 	DecklinkBase            *decklink = nullptr;
 	DeckLinkDevice          *device = nullptr;
 	DeckLinkDeviceMode      *mode = nullptr;
+	BMDVideoConnection      videoConnection;
+	BMDAudioConnection      audioConnection;
 	BMDDisplayMode          displayMode = bmdModeNTSC;
 	BMDPixelFormat          pixelFormat = bmdFormat8BitYUV;
 	video_colorspace        colorSpace = VIDEO_CS_DEFAULT;
@@ -56,10 +58,14 @@ public:
 	inline video_range_type GetActiveColorRange() const {return colorRange;}
 	inline speaker_layout GetActiveChannelFormat() const {return channelFormat;}
 	inline bool GetActiveSwapState() const {return swap;}
+	inline BMDVideoConnection GetVideoConnection() const {return videoConnection;}
+	inline BMDAudioConnection GetAudioConnection() const {return audioConnection;}
 
 	inline DeckLinkDeviceMode *GetMode() const {return mode;}
 
-	bool StartCapture(DeckLinkDeviceMode *mode);
+	bool StartCapture(DeckLinkDeviceMode *mode,
+			BMDVideoConnection bmdVideoConnection,
+			BMDAudioConnection bmdAudioConnection);
 	bool StopCapture(void);
 
 	bool StartOutput(DeckLinkDeviceMode *mode_);

+ 41 - 2
plugins/decklink/decklink-device.cpp

@@ -72,6 +72,18 @@ bool DeckLinkDevice::Init()
 		}
 	}
 
+	// Get supported video connections
+	attributes->GetInt(BMDDeckLinkVideoInputConnections,
+			&supportedVideoInputConnections);
+	attributes->GetInt(BMDDeckLinkVideoOutputConnections,
+			&supportedVideoOutputConnections);
+
+	// Get supported audio connections
+	attributes->GetInt(BMDDeckLinkAudioInputConnections,
+			&supportedAudioInputConnections);
+	attributes->GetInt(BMDDeckLinkAudioOutputConnections,
+			&supportedAudioOutputConnections);
+
 	// find output modes
 	ComPtr<IDeckLinkOutput> output;
 	if (device->QueryInterface(IID_IDeckLinkOutput, (void **) &output) == S_OK) {
@@ -98,8 +110,14 @@ bool DeckLinkDevice::Init()
 	}
 
 	// get keyer support
-	attributes->GetFlag(BMDDeckLinkSupportsExternalKeying, &supportsExternalKeyer);
-	attributes->GetFlag(BMDDeckLinkSupportsInternalKeying, &supportsInternalKeyer);
+	attributes->GetFlag(BMDDeckLinkSupportsExternalKeying,
+			&supportsExternalKeyer);
+	attributes->GetFlag(BMDDeckLinkSupportsInternalKeying,
+			&supportsInternalKeyer);
+
+	// Sub Device Counts
+	attributes->GetInt(BMDDeckLinkSubDeviceIndex, &subDeviceIndex);
+	attributes->GetInt(BMDDeckLinkNumberOfSubDevices, &numSubDevices);
 
 	decklink_string_t decklinkModelName;
 	decklink_string_t decklinkDisplayName;
@@ -207,6 +225,17 @@ const std::vector<DeckLinkDeviceMode *>& DeckLinkDevice::GetOutputModes(void) co
 	return outputModes;
 }
 
+int64_t DeckLinkDevice::GetVideoInputConnections()
+{
+	return supportedVideoInputConnections;
+}
+
+int64_t DeckLinkDevice::GetAudioInputConnections()
+{
+	return supportedAudioInputConnections;
+}
+
+
 bool DeckLinkDevice::GetSupportsExternalKeyer(void) const
 {
 	return supportsExternalKeyer;
@@ -217,6 +246,16 @@ bool DeckLinkDevice::GetSupportsInternalKeyer(void) const
 	return supportsInternalKeyer;
 }
 
+int64_t DeckLinkDevice::GetSubDeviceCount()
+{
+	return numSubDevices;
+}
+
+int64_t DeckLinkDevice::GetSubDeviceIndex()
+{
+	return subDeviceIndex;
+}
+
 const std::string& DeckLinkDevice::GetName(void) const
 {
 	return name;

+ 10 - 0
plugins/decklink/decklink-device.hpp

@@ -21,6 +21,12 @@ class DeckLinkDevice {
 	int32_t                                   maxChannel = 0;
 	decklink_bool_t                           supportsExternalKeyer = false;
 	decklink_bool_t                           supportsInternalKeyer = false;
+	int64_t                                   subDeviceIndex = 0;
+	int64_t                                   numSubDevices = 0;
+	int64_t                                   supportedVideoInputConnections = -1;
+	int64_t                                   supportedVideoOutputConnections = -1;
+	int64_t                                   supportedAudioInputConnections = -1;
+	int64_t                                   supportedAudioOutputConnections = -1;
 	int                                       keyerMode = 0;
 	volatile long                             refCount = 1;
 
@@ -39,8 +45,12 @@ public:
 	const std::string& GetHash(void) const;
 	const std::vector<DeckLinkDeviceMode *>& GetInputModes(void) const;
 	const std::vector<DeckLinkDeviceMode *>& GetOutputModes(void) const;
+	int64_t GetVideoInputConnections();
+	int64_t GetAudioInputConnections();
 	bool GetSupportsExternalKeyer(void) const;
 	bool GetSupportsInternalKeyer(void) const;
+	int64_t GetSubDeviceCount();
+	int64_t GetSubDeviceIndex();
 	int GetKeyerMode(void);
 	void SetKeyerMode(int newKeyerMode);
 	const std::string& GetName(void) const;

+ 49 - 2
plugins/decklink/decklink-source.cpp

@@ -1,6 +1,7 @@
 #include <obs-module.h>
 
 #include "const.h"
+#include "util.hpp"
 
 #include "DecklinkInput.hpp"
 #include "decklink-device.hpp"
@@ -42,6 +43,10 @@ static void decklink_update(void *data, obs_data_t *settings)
 	DeckLinkInput *decklink = (DeckLinkInput *)data;
 	const char *hash = obs_data_get_string(settings, DEVICE_HASH);
 	long long id = obs_data_get_int(settings, MODE_ID);
+	BMDVideoConnection videoConnection = (BMDVideoConnection) obs_data_get_int(settings,
+			VIDEO_CONNECTION);
+	BMDAudioConnection audioConnection = (BMDAudioConnection) obs_data_get_int(settings,
+			AUDIO_CONNECTION);
 	BMDPixelFormat pixelFormat = (BMDPixelFormat)obs_data_get_int(settings,
 			PIXEL_FORMAT);
 	video_colorspace colorSpace = (video_colorspace)obs_data_get_int(settings,
@@ -72,7 +77,7 @@ static void decklink_update(void *data, obs_data_t *settings)
 	decklink->SetChannelFormat(channelFormat);
 	decklink->hash = std::string(hash);
 	decklink->swap = obs_data_get_bool(settings, SWAP);
-	decklink->Activate(device, id);
+	decklink->Activate(device, id, videoConnection, audioConnection);
 }
 
 static void decklink_show(void *data)
@@ -83,7 +88,8 @@ static void decklink_show(void *data)
 	if (decklink->dwns && showing && !decklink->Capturing()) {
 		ComPtr<DeckLinkDevice> device;
 		device.Set(deviceEnum->FindByHash(decklink->hash.c_str()));
-		decklink->Activate(device, decklink->id);
+		decklink->Activate(device, decklink->id, decklink->videoConnection,
+				decklink->audioConnection);
 	}
 }
 static void decklink_hide(void *data)
@@ -134,9 +140,16 @@ static bool decklink_device_changed(obs_properties_t *props,
 		obs_property_list_item_disable(list, 0, true);
 	}
 
+	obs_property_t *videoConnectionList = obs_properties_get(props,
+			VIDEO_CONNECTION);
+	obs_property_t *audioConnectionList = obs_properties_get(props,
+			AUDIO_CONNECTION);
 	obs_property_t *modeList = obs_properties_get(props, MODE_ID);
 	obs_property_t *channelList = obs_properties_get(props, CHANNEL_FORMAT);
 
+	obs_property_list_clear(videoConnectionList);
+	obs_property_list_clear(audioConnectionList);
+
 	obs_property_list_clear(modeList);
 
 	obs_property_list_clear(channelList);
@@ -149,9 +162,38 @@ static bool decklink_device_changed(obs_properties_t *props,
 	device.Set(deviceEnum->FindByHash(hash));
 
 	if (!device) {
+		obs_property_list_item_disable(videoConnectionList, 0, true);
+		obs_property_list_item_disable(audioConnectionList, 0, true);
 		obs_property_list_add_int(modeList, mode, modeId);
 		obs_property_list_item_disable(modeList, 0, true);
 	} else {
+		const BMDVideoConnection BMDVideoConnections[] = {
+				bmdVideoConnectionSDI, bmdVideoConnectionHDMI,
+				bmdVideoConnectionOpticalSDI, bmdVideoConnectionComponent,
+				bmdVideoConnectionComposite, bmdVideoConnectionSVideo
+		};
+
+		for (BMDVideoConnection conn : BMDVideoConnections) {
+			if ((device->GetVideoInputConnections() & conn) == conn) {
+				obs_property_list_add_int(videoConnectionList,
+						bmd_video_connection_to_name(conn), conn);
+			}
+		}
+
+		const BMDAudioConnection BMDAudioConnections[] = {
+				bmdAudioConnectionEmbedded, bmdAudioConnectionAESEBU,
+				bmdAudioConnectionAnalog, bmdAudioConnectionAnalogXLR,
+				bmdAudioConnectionAnalogRCA, bmdAudioConnectionMicrophone,
+				bmdAudioConnectionHeadphones
+		};
+
+		for (BMDAudioConnection conn : BMDAudioConnections) {
+			if ((device->GetAudioInputConnections() & conn) == conn) {
+				obs_property_list_add_int(audioConnectionList,
+						bmd_audio_connection_to_name(conn), conn);
+			}
+		}
+
 		const std::vector<DeckLinkDeviceMode*> &modes =
 				device->GetInputModes();
 
@@ -220,6 +262,11 @@ static obs_properties_t *decklink_get_properties(void *data)
 
 	fill_out_devices(list);
 
+	obs_properties_add_list(props, VIDEO_CONNECTION, TEXT_VIDEO_CONNECTION,
+			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
+	obs_properties_add_list(props, AUDIO_CONNECTION, TEXT_AUDIO_CONNECTION,
+								   OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
+
 	list = obs_properties_add_list(props, MODE_ID, TEXT_MODE,
 			OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
 	obs_property_set_modified_callback(list, mode_id_changed);

+ 2 - 0
plugins/decklink/linux/CMakeLists.txt

@@ -33,6 +33,7 @@ set(linux-decklink_HEADERS
 	../decklink-device-mode.hpp
 	../audio-repack.h
 	../audio-repack.hpp
+	../util.hpp
 	)
 
 set(linux-decklink_SOURCES
@@ -49,6 +50,7 @@ set(linux-decklink_SOURCES
 	../decklink-device-mode.cpp
 	../audio-repack.c
 	platform.cpp
+	../util.cpp
 	)
 
 add_library(linux-decklink MODULE

+ 2 - 0
plugins/decklink/mac/CMakeLists.txt

@@ -36,6 +36,7 @@ set(mac-decklink_HEADERS
 	../decklink-device-mode.hpp
 	../audio-repack.h
 	../audio-repack.hpp
+	../util.hpp
 	)
 
 set(mac-decklink_SOURCES
@@ -52,6 +53,7 @@ set(mac-decklink_SOURCES
 	../decklink-device-mode.cpp
 	../audio-repack.c
 	platform.cpp
+	../util.cpp
 	)
 
 list(APPEND decklink_HEADERS ${decklink_UI_HEADERS})

+ 43 - 0
plugins/decklink/util.cpp

@@ -0,0 +1,43 @@
+#include "util.hpp"
+
+const char *bmd_video_connection_to_name(BMDVideoConnection connection)
+{
+	switch (connection) {
+		case bmdVideoConnectionSDI:
+			return "SDI";
+		case bmdVideoConnectionHDMI:
+			return "HDMI";
+		case bmdVideoConnectionOpticalSDI:
+			return "Optical SDI";
+		case bmdVideoConnectionComponent:
+			return "Component";
+		case bmdVideoConnectionComposite:
+			return "Composite";
+		case bmdVideoConnectionSVideo:
+			return "S-Video";
+		default:
+			return "Unknown";
+	}
+}
+
+const char *bmd_audio_connection_to_name(BMDAudioConnection connection)
+{
+	switch (connection) {
+		case bmdAudioConnectionEmbedded:
+			return "Embedded";
+		case bmdAudioConnectionAESEBU:
+			return "AES/EBU";
+		case bmdAudioConnectionAnalog:
+			return "Analog";
+		case bmdAudioConnectionAnalogXLR:
+			return "Analog XLR";
+		case bmdAudioConnectionAnalogRCA:
+			return "Analog RCA";
+		case bmdAudioConnectionMicrophone:
+			return "Microphone";
+		case bmdAudioConnectionHeadphones:
+			return "Headphones";
+		default:
+			return "Unknown";
+	}
+}

+ 7 - 0
plugins/decklink/util.hpp

@@ -0,0 +1,7 @@
+#pragma once
+
+#include "decklink-device.hpp"
+
+const char *bmd_video_connection_to_name(BMDVideoConnection connection);
+
+const char *bmd_audio_connection_to_name(BMDAudioConnection connection);

+ 2 - 0
plugins/decklink/win/CMakeLists.txt

@@ -28,6 +28,7 @@ set(win-decklink_HEADERS
 	../decklink-device-mode.hpp
 	../audio-repack.h
 	../audio-repack.hpp
+	../util.hpp
 	)
 
 set(win-decklink_SOURCES
@@ -44,6 +45,7 @@ set(win-decklink_SOURCES
 	../decklink-device-mode.cpp
 	../audio-repack.c
 	platform.cpp
+	../util.cpp
 	)
 
 add_idl_files(win-decklink-sdk_GENERATED_FILES