From c459ade36066b7adb5e0f4e74d92d005d84810db Mon Sep 17 00:00:00 2001 From: mntone Date: Fri, 31 Mar 2017 13:03:38 +0900 Subject: [PATCH] decklink: Add option to select channel format Closes jp9000/obs-studio#867 --- plugins/decklink/audio-repack.c | 114 ++++++++++++++++++ plugins/decklink/audio-repack.h | 41 +++++++ plugins/decklink/audio-repack.hpp | 25 ++++ plugins/decklink/data/locale/en-US.ini | 6 + plugins/decklink/decklink-device-instance.cpp | 103 +++++++++++++--- plugins/decklink/decklink-device-instance.hpp | 8 ++ plugins/decklink/decklink-device.cpp | 14 +++ plugins/decklink/decklink-device.hpp | 2 + plugins/decklink/decklink.cpp | 3 +- plugins/decklink/decklink.hpp | 6 + plugins/decklink/linux/CMakeLists.txt | 3 + plugins/decklink/mac/CMakeLists.txt | 3 + plugins/decklink/plugin-main.cpp | 101 +++++++++++----- plugins/decklink/win/CMakeLists.txt | 3 + 14 files changed, 383 insertions(+), 49 deletions(-) create mode 100644 plugins/decklink/audio-repack.c create mode 100644 plugins/decklink/audio-repack.h create mode 100644 plugins/decklink/audio-repack.hpp diff --git a/plugins/decklink/audio-repack.c b/plugins/decklink/audio-repack.c new file mode 100644 index 000000000..739f29f78 --- /dev/null +++ b/plugins/decklink/audio-repack.c @@ -0,0 +1,114 @@ +#include "audio-repack.h" + +#include + +int check_buffer(struct audio_repack *repack, + uint32_t frame_count) +{ + const uint32_t new_size = frame_count * repack->base_dst_size + + repack->extra_dst_size; + + if (repack->packet_size < new_size) { + repack->packet_buffer = brealloc( + repack->packet_buffer, new_size); + if (!repack->packet_buffer) + return -1; + + repack->packet_size = new_size; + } + + return 0; +} + +/* + Swap channel between LFE and FC, and + squash data array + + | FL | FR |LFE | FC | BL | BR |emp |emp | + | | x | | + | FL | FR | FC |LFE | BL | BR | + */ +int repack_8to6ch_swap23(struct audio_repack *repack, + const uint8_t *bsrc, uint32_t frame_count) +{ + if (check_buffer(repack, frame_count) < 0) + return -1; + + const uint32_t size = frame_count * repack->base_src_size; + + const __m128i *src = (__m128i *)bsrc; + const __m128i *esrc = src + frame_count; + uint32_t *dst = (uint32_t *)repack->packet_buffer; + while (src != esrc) { + __m128i target = _mm_load_si128(src++); + __m128i buf = _mm_shufflelo_epi16(target, _MM_SHUFFLE(2, 3, 1, 0)); + _mm_storeu_si128((__m128i *)dst, buf); + dst += 3; + } + + return 0; +} + +/* + Swap channel between LFE and FC + + | FL | FR |LFE | FC | BL | BR |SBL |SBR | + | | x | | | | + | FL | FR | FC |LFE | BL | BR |SBL |SBR | + */ +int repack_8ch_swap23(struct audio_repack *repack, + const uint8_t *bsrc, uint32_t frame_count) +{ + if (check_buffer(repack, frame_count) < 0) + return -1; + + const uint32_t size = frame_count * repack->base_src_size; + + const __m128i *src = (__m128i *)bsrc; + const __m128i *esrc = src + frame_count; + __m128i *dst = (__m128i *)repack->packet_buffer; + while (src != esrc) { + __m128i target = _mm_load_si128(src++); + __m128i buf = _mm_shufflelo_epi16(target, _MM_SHUFFLE(2, 3, 1, 0)); + _mm_store_si128(dst++, buf); + } + + return 0; +} + +int audio_repack_init(struct audio_repack *repack, + audio_repack_mode_t repack_mode, uint8_t sample_bit) +{ + memset(repack, 0, sizeof(*repack)); + + if (sample_bit != 16) + return -1; + + switch (repack_mode) { + case repack_mode_8to6ch_swap23: + repack->base_src_size = 8 * (16 / 8); + repack->base_dst_size = 6 * (16 / 8); + repack->extra_dst_size = 2; + repack->repack_func = &repack_8to6ch_swap23; + break; + + case repack_mode_8ch_swap23: + repack->base_src_size = 8 * (16 / 8); + repack->base_dst_size = 8 * (16 / 8); + repack->extra_dst_size = 0; + repack->repack_func = &repack_8ch_swap23; + break; + + default: return -1; + } + + return 0; +} + +void audio_repack_free(struct audio_repack *repack) +{ + if (repack->packet_buffer) + bfree(repack->packet_buffer); + + memset(repack, 0, sizeof(*repack)); +} diff --git a/plugins/decklink/audio-repack.h b/plugins/decklink/audio-repack.h new file mode 100644 index 000000000..b5116e7a5 --- /dev/null +++ b/plugins/decklink/audio-repack.h @@ -0,0 +1,41 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include + +struct audio_repack; + +typedef int (*audio_repack_func_t)(struct audio_repack *, + const uint8_t *, uint32_t); + +struct audio_repack { + uint8_t *packet_buffer; + uint32_t packet_size; + + uint32_t base_src_size; + uint32_t base_dst_size; + uint32_t extra_dst_size; + + audio_repack_func_t repack_func; +}; + +enum _audio_repack_mode { + repack_mode_8to6ch_swap23, + repack_mode_8ch_swap23, +}; + +typedef enum _audio_repack_mode audio_repack_mode_t; + +extern int audio_repack_init(struct audio_repack *repack, + audio_repack_mode_t repack_mode, uint8_t sample_bit); +extern void audio_repack_free(struct audio_repack *repack); + +#ifdef __cplusplus +} +#endif diff --git a/plugins/decklink/audio-repack.hpp b/plugins/decklink/audio-repack.hpp new file mode 100644 index 000000000..d495172e0 --- /dev/null +++ b/plugins/decklink/audio-repack.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include "audio-repack.h" + +class AudioRepacker { + struct audio_repack arepack; + +public: + inline AudioRepacker(audio_repack_mode_t repack_mode) + { + audio_repack_init(&arepack, repack_mode, 16); + } + inline ~AudioRepacker() + { + audio_repack_free(&arepack); + } + + inline int repack(const uint8_t *src, uint32_t frame_size) + { + return (*arepack.repack_func)(&arepack, src, frame_size); + } + + inline operator struct audio_repack*() {return &arepack;} + inline struct audio_repack *operator->() {return &arepack;} +}; diff --git a/plugins/decklink/data/locale/en-US.ini b/plugins/decklink/data/locale/en-US.ini index e19dea4ff..202070d5f 100644 --- a/plugins/decklink/data/locale/en-US.ini +++ b/plugins/decklink/data/locale/en-US.ini @@ -3,3 +3,9 @@ Device="Device" Mode="Mode" Buffering="Use Buffering" PixelFormat="Pixel Format" +ChannelFormat="Channel" +ChannelFormat.None="None" +ChannelFormat.2_0ch="2ch" +ChannelFormat.5_1ch="5.1ch" +ChannelFormat.5_1chBack="5.1ch (Back)" +ChannelFormat.7_1ch="7.1ch" diff --git a/plugins/decklink/decklink-device-instance.cpp b/plugins/decklink/decklink-device-instance.cpp index 6185b12f8..f4f7acfe1 100644 --- a/plugins/decklink/decklink-device-instance.cpp +++ b/plugins/decklink/decklink-device-instance.cpp @@ -1,4 +1,5 @@ #include "decklink-device-instance.hpp" +#include "audio-repack.hpp" #include #include @@ -8,6 +9,8 @@ #define LOG(level, message, ...) blog(level, "%s: " message, \ obs_source_get_name(this->decklink->GetSource()), ##__VA_ARGS__) +#define ISSTEREO(flag) ((flag) == SPEAKERS_STEREO) + static inline enum video_format ConvertPixelFormat(BMDPixelFormat format) { switch (format) { @@ -20,6 +23,36 @@ static inline enum video_format ConvertPixelFormat(BMDPixelFormat format) return VIDEO_FORMAT_UYVY; } +static inline int ConvertChannelFormat(speaker_layout format) +{ + switch (format) { + case SPEAKERS_5POINT1: + case SPEAKERS_5POINT1_SURROUND: + case SPEAKERS_7POINT1: + return 8; + + default: + case SPEAKERS_STEREO: + return 2; + } +} + +static inline audio_repack_mode_t ConvertRepackFormat(speaker_layout format) +{ + switch (format) { + case SPEAKERS_5POINT1: + case SPEAKERS_5POINT1_SURROUND: + return repack_mode_8to6ch_swap23; + + case SPEAKERS_7POINT1: + return repack_mode_8ch_swap23; + + default: + assert(false && "No repack requested"); + return (audio_repack_mode_t)-1; + } +} + DeckLinkDeviceInstance::DeckLinkDeviceInstance(DeckLink *decklink_, DeckLinkDevice *device_) : currentFrame(), currentPacket(), decklink(decklink_), device(device_) @@ -46,9 +79,20 @@ void DeckLinkDeviceInstance::HandleAudioPacket( return; } - currentPacket.data[0] = (uint8_t *)bytes; - currentPacket.frames = (uint32_t)audioPacket->GetSampleFrameCount(); - currentPacket.timestamp = timestamp; + const uint32_t frameCount = (uint32_t)audioPacket->GetSampleFrameCount(); + currentPacket.frames = frameCount; + currentPacket.timestamp = timestamp; + + if (!ISSTEREO(channelFormat)) { + if (audioRepacker->repack((uint8_t *)bytes, frameCount) < 0) { + LOG(LOG_ERROR, "Failed to convert audio packet data"); + return; + } + + currentPacket.data[0] = (*audioRepacker)->packet_buffer; + } else { + currentPacket.data[0] = (uint8_t *)bytes; + } obs_source_output_audio(decklink->GetSource(), ¤tPacket); } @@ -78,6 +122,19 @@ void DeckLinkDeviceInstance::HandleVideoFrame( obs_source_output_video(decklink->GetSource(), ¤tFrame); } +void DeckLinkDeviceInstance::FinalizeStream() +{ + input->SetCallback(nullptr); + + if (audioRepacker != nullptr) + { + delete audioRepacker; + audioRepacker = nullptr; + } + + mode = nullptr; +} + bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_) { if (mode != nullptr) @@ -93,8 +150,6 @@ bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_) pixelFormat = decklink->GetPixelFormat(); currentFrame.format = ConvertPixelFormat(pixelFormat); - input->SetCallback(this); - const BMDDisplayMode displayMode = mode_->GetDisplayMode(); const HRESULT videoResult = input->EnableVideoInput(displayMode, @@ -102,22 +157,36 @@ bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_) if (videoResult != S_OK) { LOG(LOG_ERROR, "Failed to enable video input"); - input->SetCallback(nullptr); return false; } - const HRESULT audioResult = input->EnableAudioInput( - bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, - 2); + channelFormat = decklink->GetChannelFormat(); + currentPacket.speakers = channelFormat; - if (audioResult != S_OK) - LOG(LOG_WARNING, "Failed to enable audio input; continuing..."); + if (channelFormat != SPEAKERS_UNKNOWN) { + const int channel = ConvertChannelFormat(channelFormat); + const HRESULT audioResult = input->EnableAudioInput( + bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, + channel); + + if (audioResult != S_OK) + LOG(LOG_WARNING, "Failed to enable audio input; continuing..."); + + if (!ISSTEREO(channelFormat)) { + const audio_repack_mode_t repack_mode = ConvertRepackFormat(channelFormat); + audioRepacker = new AudioRepacker(repack_mode); + } + } + + if (input->SetCallback(this) != S_OK) { + LOG(LOG_ERROR, "Failed to set callback"); + FinalizeStream(); + return false; + } if (input->StartStreams() != S_OK) { LOG(LOG_ERROR, "Failed to start streams"); - input->SetCallback(nullptr); - input->DisableVideoInput(); - input->DisableAudioInput(); + FinalizeStream(); return false; } @@ -135,11 +204,7 @@ bool DeckLinkDeviceInstance::StopCapture(void) GetDevice()->GetDisplayName().c_str()); input->StopStreams(); - input->SetCallback(nullptr); - input->DisableVideoInput(); - input->DisableAudioInput(); - - mode = nullptr; + FinalizeStream(); return true; } diff --git a/plugins/decklink/decklink-device-instance.hpp b/plugins/decklink/decklink-device-instance.hpp index b2c60529e..854e983e0 100644 --- a/plugins/decklink/decklink-device-instance.hpp +++ b/plugins/decklink/decklink-device-instance.hpp @@ -2,6 +2,8 @@ #include "decklink-device.hpp" +class AudioRepacker; + class DeckLinkDeviceInstance : public IDeckLinkInputCallback { protected: struct obs_source_frame currentFrame; @@ -13,6 +15,11 @@ protected: ComPtr input; volatile long refCount = 1; + AudioRepacker *audioRepacker = nullptr; + speaker_layout channelFormat = SPEAKERS_STEREO; + + void FinalizeStream(); + void HandleAudioPacket(IDeckLinkAudioInputPacket *audioPacket, const uint64_t timestamp); void HandleVideoFrame(IDeckLinkVideoInputFrame *videoFrame, @@ -29,6 +36,7 @@ public: } inline BMDPixelFormat GetActivePixelFormat() const {return pixelFormat;} + inline speaker_layout GetActiveChannelFormat() const {return channelFormat;} inline DeckLinkDeviceMode *GetMode() const {return mode;} diff --git a/plugins/decklink/decklink-device.cpp b/plugins/decklink/decklink-device.cpp index 8dc109bf0..c6bdf1e06 100644 --- a/plugins/decklink/decklink-device.cpp +++ b/plugins/decklink/decklink-device.cpp @@ -72,6 +72,15 @@ bool DeckLinkDevice::Init() if (result != S_OK) return true; + int64_t channels; + /* Intensity Shuttle for Thunderbolt return 2; however, it supports 8 channels */ + if (name == "Intensity Shuttle Thunderbolt") + maxChannel = 8; + else if (attributes->GetInt(BMDDeckLinkMaximumAudioChannels, &channels) == S_OK) + maxChannel = (int32_t)channels; + else + maxChannel = 2; + /* http://forum.blackmagicdesign.com/viewtopic.php?f=12&t=33967 * BMDDeckLinkTopologicalID for older devices * BMDDeckLinkPersistentID for newer ones */ @@ -118,3 +127,8 @@ const std::string& DeckLinkDevice::GetName(void) const { return name; } + +const int32_t DeckLinkDevice::GetMaxChannel(void) const +{ + return maxChannel; +} diff --git a/plugins/decklink/decklink-device.hpp b/plugins/decklink/decklink-device.hpp index bf1a79be4..c18ff8580 100644 --- a/plugins/decklink/decklink-device.hpp +++ b/plugins/decklink/decklink-device.hpp @@ -14,6 +14,7 @@ class DeckLinkDevice { std::string name; std::string displayName; std::string hash; + int32_t maxChannel; volatile long refCount = 1; public: @@ -30,6 +31,7 @@ public: const std::string& GetHash(void) const; const std::vector& GetModes(void) const; const std::string& GetName(void) const; + const int32_t GetMaxChannel(void) const; bool GetInput(IDeckLinkInput **input); diff --git a/plugins/decklink/decklink.cpp b/plugins/decklink/decklink.cpp index e435e03a0..c20ff32d5 100644 --- a/plugins/decklink/decklink.cpp +++ b/plugins/decklink/decklink.cpp @@ -65,7 +65,8 @@ bool DeckLink::Activate(DeckLinkDevice *device, long long modeId) if (!isActive) return false; if (instance->GetActiveModeId() == modeId && - instance->GetActivePixelFormat() == pixelFormat) + instance->GetActivePixelFormat() == pixelFormat && + instance->GetActiveChannelFormat() == channelFormat) return false; } diff --git a/plugins/decklink/decklink.hpp b/plugins/decklink/decklink.hpp index daa0df72c..217637a4a 100644 --- a/plugins/decklink/decklink.hpp +++ b/plugins/decklink/decklink.hpp @@ -22,6 +22,7 @@ protected: volatile long activateRefs = 0; std::recursive_mutex deviceMutex; BMDPixelFormat pixelFormat = bmdFormat8BitYUV; + speaker_layout channelFormat = SPEAKERS_STEREO; void SaveSettings(); static void DevicesChanged(void *param, DeckLinkDevice *device, @@ -41,6 +42,11 @@ public: { pixelFormat = format; } + inline speaker_layout GetChannelFormat() const {return channelFormat;} + inline void SetChannelFormat(speaker_layout format) + { + channelFormat = format; + } bool Activate(DeckLinkDevice *device, long long modeId); void Deactivate(); diff --git a/plugins/decklink/linux/CMakeLists.txt b/plugins/decklink/linux/CMakeLists.txt index e51cb95dd..d1a945222 100644 --- a/plugins/decklink/linux/CMakeLists.txt +++ b/plugins/decklink/linux/CMakeLists.txt @@ -22,6 +22,8 @@ set(linux-decklink_HEADERS ../decklink-device-discovery.hpp ../decklink-device.hpp ../decklink-device-mode.hpp + ../audio-repack.h + ../audio-repack.hpp ) set(linux-decklink_SOURCES @@ -31,6 +33,7 @@ set(linux-decklink_SOURCES ../decklink-device-discovery.cpp ../decklink-device.cpp ../decklink-device-mode.cpp + ../audio-repack.c platform.cpp) add_library(linux-decklink MODULE diff --git a/plugins/decklink/mac/CMakeLists.txt b/plugins/decklink/mac/CMakeLists.txt index ce0b9bdf2..a47923a2a 100644 --- a/plugins/decklink/mac/CMakeLists.txt +++ b/plugins/decklink/mac/CMakeLists.txt @@ -26,6 +26,8 @@ set(mac-decklink_HEADERS ../decklink-device-discovery.hpp ../decklink-device.hpp ../decklink-device-mode.hpp + ../audio-repack.h + ../audio-repack.hpp ) set(mac-decklink_SOURCES @@ -35,6 +37,7 @@ set(mac-decklink_SOURCES ../decklink-device-discovery.cpp ../decklink-device.cpp ../decklink-device-mode.cpp + ../audio-repack.c platform.cpp) add_library(mac-decklink MODULE diff --git a/plugins/decklink/plugin-main.cpp b/plugins/decklink/plugin-main.cpp index 13523f8f6..e0be2ef7a 100644 --- a/plugins/decklink/plugin-main.cpp +++ b/plugins/decklink/plugin-main.cpp @@ -7,6 +7,25 @@ OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("decklink", "en-US") +#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 BUFFERING "buffering" + +#define TEXT_DEVICE obs_module_text("Device") +#define TEXT_MODE obs_module_text("Mode") +#define TEXT_PIXEL_FORMAT obs_module_text("PixelFormat") +#define TEXT_CHANNEL_FORMAT obs_module_text("ChannelFormat") +#define TEXT_CHANNEL_FORMAT_NONE obs_module_text("ChannelFormat.None") +#define TEXT_CHANNEL_FORMAT_2_0CH obs_module_text("ChannelFormat.2_0ch") +#define TEXT_CHANNEL_FORMAT_5_1CH obs_module_text("ChannelFormat.5_1ch") +#define TEXT_CHANNEL_FORMAT_5_1CH_BACK obs_module_text("ChannelFormat.5_1chBack") +#define TEXT_CHANNEL_FORMAT_7_1CH obs_module_text("ChannelFormat.7_1ch") +#define TEXT_BUFFERING obs_module_text("Buffering") + static DeckLinkDeviceDiscovery *deviceEnum = nullptr; static void decklink_enable_buffering(DeckLink *decklink, bool enabled) @@ -25,7 +44,7 @@ static void *decklink_create(obs_data_t *settings, obs_source_t *source) DeckLink *decklink = new DeckLink(source, deviceEnum); decklink_enable_buffering(decklink, - obs_data_get_bool(settings, "buffering")); + obs_data_get_bool(settings, BUFFERING)); obs_source_update(source, settings); return decklink; @@ -40,25 +59,29 @@ static void decklink_destroy(void *data) 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"); + const char *hash = obs_data_get_string(settings, DEVICE_HASH); + long long id = obs_data_get_int(settings, MODE_ID); + BMDPixelFormat pixelFormat = (BMDPixelFormat)obs_data_get_int(settings, + PIXEL_FORMAT); + speaker_layout channelFormat = (speaker_layout)obs_data_get_int(settings, + CHANNEL_FORMAT); decklink_enable_buffering(decklink, - obs_data_get_bool(settings, "buffering")); + obs_data_get_bool(settings, BUFFERING)); ComPtr device; device.Set(deviceEnum->FindByHash(hash)); - decklink->SetPixelFormat(format); + decklink->SetPixelFormat(pixelFormat); + decklink->SetChannelFormat(channelFormat); 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); + obs_data_set_default_bool(settings, BUFFERING, true); + obs_data_set_default_int(settings, PIXEL_FORMAT, bmdFormat8BitYUV); + obs_data_set_default_int(settings, CHANNEL_FORMAT, SPEAKERS_STEREO); } static const char *decklink_get_name(void*) @@ -69,10 +92,10 @@ static const char *decklink_get_name(void*) static bool decklink_device_changed(obs_properties_t *props, obs_property_t *list, obs_data_t *settings) { - const char *name = obs_data_get_string(settings, "device_name"); - const char *hash = obs_data_get_string(settings, "device_hash"); - const char *mode = obs_data_get_string(settings, "mode_name"); - long long modeId = obs_data_get_int(settings, "mode_id"); + const char *name = obs_data_get_string(settings, DEVICE_NAME); + const char *hash = obs_data_get_string(settings, DEVICE_HASH); + const char *mode = obs_data_get_string(settings, MODE_NAME); + long long modeId = obs_data_get_int(settings, MODE_ID); size_t itemCount = obs_property_list_item_count(list); bool itemFound = false; @@ -90,25 +113,41 @@ static bool decklink_device_changed(obs_properties_t *props, obs_property_list_item_disable(list, 0, true); } - list = obs_properties_get(props, "mode_id"); + obs_property_t *modeList = obs_properties_get(props, MODE_ID); + obs_property_t *channelList = obs_properties_get(props, CHANNEL_FORMAT); - obs_property_list_clear(list); + obs_property_list_clear(modeList); + + obs_property_list_clear(channelList); + obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_NONE, + SPEAKERS_UNKNOWN); + obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_2_0CH, + SPEAKERS_STEREO); ComPtr device; device.Set(deviceEnum->FindByHash(hash)); if (!device) { - obs_property_list_add_int(list, mode, modeId); - obs_property_list_item_disable(list, 0, true); + obs_property_list_add_int(modeList, mode, modeId); + obs_property_list_item_disable(modeList, 0, true); } else { const std::vector &modes = device->GetModes(); for (DeckLinkDeviceMode *mode : modes) { - obs_property_list_add_int(list, + obs_property_list_add_int(modeList, mode->GetName().c_str(), mode->GetId()); } + + if (device->GetMaxChannel() >= 8) { + obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_5_1CH, + SPEAKERS_5POINT1); + obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_5_1CH_BACK, + SPEAKERS_5POINT1_SURROUND); + obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_7_1CH, + SPEAKERS_7POINT1); + } } return true; @@ -132,26 +171,30 @@ static obs_properties_t *decklink_get_properties(void *data) { obs_properties_t *props = obs_properties_create(); - obs_property_t *list = obs_properties_add_list(props, "device_hash", - obs_module_text("Device"), OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_STRING); + obs_property_t *list = obs_properties_add_list(props, DEVICE_HASH, + TEXT_DEVICE, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); obs_property_set_modified_callback(list, decklink_device_changed); fill_out_devices(list); - list = obs_properties_add_list(props, "mode_id", - obs_module_text("Mode"), 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); - list = obs_properties_add_list(props, "pixel_format", - obs_module_text("PixelFormat"), OBS_COMBO_TYPE_LIST, + list = obs_properties_add_list(props, PIXEL_FORMAT, + TEXT_PIXEL_FORMAT, 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")); + list = obs_properties_add_list(props, CHANNEL_FORMAT, + TEXT_CHANNEL_FORMAT, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_NONE, + SPEAKERS_UNKNOWN); + obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_2_0CH, + SPEAKERS_STEREO); + + obs_properties_add_bool(props, BUFFERING, TEXT_BUFFERING); UNUSED_PARAMETER(data); return props; diff --git a/plugins/decklink/win/CMakeLists.txt b/plugins/decklink/win/CMakeLists.txt index 2b4ecb823..515d13bf3 100644 --- a/plugins/decklink/win/CMakeLists.txt +++ b/plugins/decklink/win/CMakeLists.txt @@ -17,6 +17,8 @@ set(win-decklink_HEADERS ../decklink-device-discovery.hpp ../decklink-device.hpp ../decklink-device-mode.hpp + ../audio-repack.h + ../audio-repack.hpp ) set(win-decklink_SOURCES @@ -26,6 +28,7 @@ set(win-decklink_SOURCES ../decklink-device-discovery.cpp ../decklink-device.cpp ../decklink-device-mode.cpp + ../audio-repack.c platform.cpp) add_idl_files(win-decklink-sdk_GENERATED_FILES