diff --git a/plugins/decklink/data/locale/en-US.ini b/plugins/decklink/data/locale/en-US.ini index 50ace69d8..e19dea4ff 100644 --- a/plugins/decklink/data/locale/en-US.ini +++ b/plugins/decklink/data/locale/en-US.ini @@ -2,3 +2,4 @@ BlackmagicDevice="Blackmagic Device" Device="Device" Mode="Mode" Buffering="Use Buffering" +PixelFormat="Pixel Format" diff --git a/plugins/decklink/decklink-device-instance.cpp b/plugins/decklink/decklink-device-instance.cpp index 2555d367a..6185b12f8 100644 --- a/plugins/decklink/decklink-device-instance.cpp +++ b/plugins/decklink/decklink-device-instance.cpp @@ -8,21 +8,22 @@ #define LOG(level, message, ...) blog(level, "%s: " message, \ obs_source_get_name(this->decklink->GetSource()), ##__VA_ARGS__) +static inline enum video_format ConvertPixelFormat(BMDPixelFormat format) +{ + switch (format) { + case bmdFormat8BitBGRA: return VIDEO_FORMAT_BGRX; + + default: + case bmdFormat8BitYUV:; + } + + return VIDEO_FORMAT_UYVY; +} + DeckLinkDeviceInstance::DeckLinkDeviceInstance(DeckLink *decklink_, DeckLinkDevice *device_) : currentFrame(), currentPacket(), decklink(decklink_), device(device_) { - // use BGRA mode if the device is a BMI intensity pro 4K... wish there - // was a better way to check the device model, but older cards don't - // implement BMDDeckLinkPersistentID - if (std::string("Intensity Pro 4K").compare(device_->GetName()) == 0) { - currentFrame.format = VIDEO_FORMAT_BGRX; - pixelFormat = bmdFormat8BitBGRA; - } else { - currentFrame.format = VIDEO_FORMAT_UYVY; - pixelFormat = bmdFormat8BitYUV; - } - currentPacket.samples_per_sec = 48000; currentPacket.speakers = SPEAKERS_STEREO; currentPacket.format = AUDIO_FORMAT_16BIT; @@ -89,6 +90,9 @@ bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_) if (!device->GetInput(&input)) return false; + pixelFormat = decklink->GetPixelFormat(); + currentFrame.format = ConvertPixelFormat(pixelFormat); + input->SetCallback(this); const BMDDisplayMode displayMode = mode_->GetDisplayMode(); diff --git a/plugins/decklink/decklink-device-instance.hpp b/plugins/decklink/decklink-device-instance.hpp index 8ceae8c0e..b2c60529e 100644 --- a/plugins/decklink/decklink-device-instance.hpp +++ b/plugins/decklink/decklink-device-instance.hpp @@ -28,6 +28,8 @@ public: return mode ? mode->GetId() : 0; } + inline BMDPixelFormat GetActivePixelFormat() const {return pixelFormat;} + inline DeckLinkDeviceMode *GetMode() const {return mode;} bool StartCapture(DeckLinkDeviceMode *mode); diff --git a/plugins/decklink/decklink.cpp b/plugins/decklink/decklink.cpp index d9fc8a11f..e435e03a0 100644 --- a/plugins/decklink/decklink.cpp +++ b/plugins/decklink/decklink.cpp @@ -61,8 +61,13 @@ bool DeckLink::Activate(DeckLinkDevice *device, long long modeId) const bool same = device == curDevice; const bool isActive = instance != nullptr; - if (same && (!isActive || instance->GetActiveModeId() == modeId)) - return false; + if (same) { + if (!isActive) + return false; + if (instance->GetActiveModeId() == modeId && + instance->GetActivePixelFormat() == pixelFormat) + return false; + } if (isActive) instance->StopCapture(); diff --git a/plugins/decklink/decklink.hpp b/plugins/decklink/decklink.hpp index 9b68f67bc..daa0df72c 100644 --- a/plugins/decklink/decklink.hpp +++ b/plugins/decklink/decklink.hpp @@ -21,6 +21,7 @@ protected: obs_source_t *source; volatile long activateRefs = 0; std::recursive_mutex deviceMutex; + BMDPixelFormat pixelFormat = bmdFormat8BitYUV; void SaveSettings(); static void DevicesChanged(void *param, DeckLinkDevice *device, @@ -35,6 +36,12 @@ public: long long GetActiveModeId(void) const; obs_source_t *GetSource(void) const; + inline BMDPixelFormat GetPixelFormat() const {return pixelFormat;} + inline void SetPixelFormat(BMDPixelFormat format) + { + pixelFormat = format; + } + bool Activate(DeckLinkDevice *device, long long modeId); void Deactivate(); }; diff --git a/plugins/decklink/plugin-main.cpp b/plugins/decklink/plugin-main.cpp index 0b3697fac..b999f7ca1 100644 --- a/plugins/decklink/plugin-main.cpp +++ b/plugins/decklink/plugin-main.cpp @@ -42,6 +42,8 @@ static void decklink_update(void *data, obs_data_t *settings) DeckLink *decklink = (DeckLink *)data; const char *hash = obs_data_get_string(settings, "device_hash"); long long id = obs_data_get_int(settings, "mode_id"); + BMDPixelFormat format = (BMDPixelFormat)obs_data_get_int(settings, + "pixel_format"); decklink_enable_buffering(decklink, obs_data_get_bool(settings, "buffering")); @@ -49,12 +51,14 @@ static void decklink_update(void *data, obs_data_t *settings) ComPtr device; device.Set(deviceEnum->FindByHash(hash)); + decklink->SetPixelFormat(format); decklink->Activate(device, id); } static void decklink_get_defaults(obs_data_t *settings) { obs_data_set_default_bool(settings, "buffering", true); + obs_data_set_default_int(settings, "pixel_format", bmdFormat8BitYUV); } static const char *decklink_get_name(void*) @@ -139,6 +143,13 @@ static obs_properties_t *decklink_get_properties(void *data) obs_module_text("Mode"), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + list = obs_properties_add_list(props, "pixel_format", + obs_module_text("PixelFormat"), OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); + + obs_property_list_add_int(list, "8-bit YUV", bmdFormat8BitYUV); + obs_property_list_add_int(list, "8-bit BGRA", bmdFormat8BitBGRA); + obs_properties_add_bool(props, "buffering", obs_module_text("Buffering"));