New upstream version 24.0.1+dfsg1

This commit is contained in:
Sebastian Ramacher 2019-09-22 23:19:10 +02:00
parent b14f9eae6d
commit 5a730d6ec3
842 changed files with 42245 additions and 33385 deletions

View file

@ -1,7 +1,7 @@
#include "DecklinkBase.h"
DecklinkBase::DecklinkBase(DeckLinkDeviceDiscovery *discovery_)
: discovery(discovery_)
: discovery(discovery_)
{
}
@ -10,11 +10,9 @@ DeckLinkDevice *DecklinkBase::GetDevice() const
return instance ? instance->GetDevice() : nullptr;
}
bool DecklinkBase::Activate(DeckLinkDevice*, long long)
bool DecklinkBase::Activate(DeckLinkDevice *, long long)
{
return false;
}
void DecklinkBase::Deactivate()
{
}
void DecklinkBase::Deactivate() {}

View file

@ -16,14 +16,14 @@ class DecklinkBase {
protected:
DecklinkBase(DeckLinkDeviceDiscovery *discovery_);
ComPtr<DeckLinkDeviceInstance> instance;
DeckLinkDeviceDiscovery *discovery;
std::recursive_mutex deviceMutex;
volatile long activateRefs = 0;
BMDPixelFormat pixelFormat = bmdFormat8BitYUV;
video_colorspace colorSpace = VIDEO_CS_DEFAULT;
video_range_type colorRange = VIDEO_RANGE_DEFAULT;
speaker_layout channelFormat = SPEAKERS_STEREO;
ComPtr<DeckLinkDeviceInstance> instance;
DeckLinkDeviceDiscovery *discovery;
std::recursive_mutex deviceMutex;
volatile long activateRefs = 0;
BMDPixelFormat pixelFormat = bmdFormat8BitYUV;
video_colorspace colorSpace = VIDEO_CS_DEFAULT;
video_range_type colorRange = VIDEO_RANGE_DEFAULT;
speaker_layout channelFormat = SPEAKERS_STEREO;
public:
virtual bool Activate(DeckLinkDevice *device, long long modeId);

View file

@ -2,9 +2,9 @@
#include <util/threading.h>
DeckLinkInput::DeckLinkInput(obs_source_t *source, DeckLinkDeviceDiscovery *discovery_)
: DecklinkBase(discovery_),
source(source)
DeckLinkInput::DeckLinkInput(obs_source_t *source,
DeckLinkDeviceDiscovery *discovery_)
: DecklinkBase(discovery_), source(source)
{
discovery->AddCallback(DeckLinkInput::DevicesChanged, this);
}
@ -15,9 +15,10 @@ DeckLinkInput::~DeckLinkInput(void)
Deactivate();
}
void DeckLinkInput::DevicesChanged(void *param, DeckLinkDevice *device, bool added)
void DeckLinkInput::DevicesChanged(void *param, DeckLinkDevice *device,
bool added)
{
DeckLinkInput *decklink = reinterpret_cast<DeckLinkInput*>(param);
DeckLinkInput *decklink = reinterpret_cast<DeckLinkInput *>(param);
std::lock_guard<std::recursive_mutex> lock(decklink->deviceMutex);
obs_source_update_properties(decklink->source);
@ -31,15 +32,18 @@ void DeckLinkInput::DevicesChanged(void *param, DeckLinkDevice *device, bool add
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");
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, videoConnection, audioConnection))
if (decklink->Activate(device, mode, videoConnection,
audioConnection))
os_atomic_dec_long(&decklink->activateRefs);
}
@ -52,8 +56,8 @@ void DeckLinkInput::DevicesChanged(void *param, DeckLinkDevice *device, bool add
}
bool DeckLinkInput::Activate(DeckLinkDevice *device, long long modeId,
BMDVideoConnection bmdVideoConnection,
BMDAudioConnection bmdAudioConnection)
BMDVideoConnection bmdVideoConnection,
BMDAudioConnection bmdAudioConnection)
{
std::lock_guard<std::recursive_mutex> lock(deviceMutex);
DeckLinkDevice *curDevice = GetDevice();
@ -85,7 +89,8 @@ bool DeckLinkInput::Activate(DeckLinkDevice *device, long long modeId,
return false;
if (GetDevice() == nullptr) {
LOG(LOG_ERROR, "Tried to activate an input with nullptr device.");
LOG(LOG_ERROR,
"Tried to activate an input with nullptr device.");
return false;
}
@ -95,7 +100,8 @@ bool DeckLinkInput::Activate(DeckLinkDevice *device, long long modeId,
return false;
}
if (!instance->StartCapture(mode, bmdVideoConnection, bmdAudioConnection)) {
if (!instance->StartCapture(mode, bmdVideoConnection,
bmdAudioConnection)) {
instance = nullptr;
return false;
}
@ -133,10 +139,9 @@ void DeckLinkInput::SaveSettings()
obs_data_t *settings = obs_source_get_settings(source);
obs_data_set_string(settings, "device_hash",
device->GetHash().c_str());
obs_data_set_string(settings, "device_hash", device->GetHash().c_str());
obs_data_set_string(settings, "device_name",
device->GetDisplayName().c_str());
device->GetDisplayName().c_str());
obs_data_set_int(settings, "mode_id", instance->GetActiveModeId());
obs_data_set_string(settings, "mode_name", mode->GetName().c_str());

View file

@ -4,12 +4,12 @@
class DeckLinkInput : public DecklinkBase {
protected:
bool isCapturing = false;
obs_source_t *source;
bool isCapturing = false;
obs_source_t *source;
void SaveSettings();
static void DevicesChanged(void *param, DeckLinkDevice *device,
bool added);
bool added);
public:
DeckLinkInput(obs_source_t *source, DeckLinkDeviceDiscovery *discovery);
@ -18,30 +18,30 @@ public:
long long GetActiveModeId(void) const;
obs_source_t *GetSource(void) const;
inline BMDPixelFormat GetPixelFormat() const {return pixelFormat;}
inline BMDPixelFormat GetPixelFormat() const { return pixelFormat; }
inline void SetPixelFormat(BMDPixelFormat format)
{
pixelFormat = format;
}
inline video_colorspace GetColorSpace() const {return colorSpace;}
inline video_colorspace GetColorSpace() const { return colorSpace; }
inline void SetColorSpace(video_colorspace format)
{
colorSpace = format;
}
inline video_range_type GetColorRange() const {return colorRange;}
inline video_range_type GetColorRange() const { return colorRange; }
inline void SetColorRange(video_range_type format)
{
colorRange = format;
}
inline speaker_layout GetChannelFormat() const {return channelFormat;}
inline speaker_layout GetChannelFormat() const { return channelFormat; }
inline void SetChannelFormat(speaker_layout format)
{
channelFormat = format;
}
bool Activate(DeckLinkDevice *device, long long modeId,
BMDVideoConnection bmdVideoConnection,
BMDAudioConnection bmdAudioConnection);
BMDVideoConnection bmdVideoConnection,
BMDAudioConnection bmdAudioConnection);
void Deactivate();
bool Capturing();

View file

@ -2,9 +2,9 @@
#include <util/threading.h>
DeckLinkOutput::DeckLinkOutput(obs_output_t *output, DeckLinkDeviceDiscovery *discovery_)
: DecklinkBase(discovery_),
output(output)
DeckLinkOutput::DeckLinkOutput(obs_output_t *output,
DeckLinkDeviceDiscovery *discovery_)
: DecklinkBase(discovery_), output(output)
{
discovery->AddCallback(DeckLinkOutput::DevicesChanged, this);
}
@ -17,7 +17,7 @@ DeckLinkOutput::~DeckLinkOutput(void)
void DeckLinkOutput::DevicesChanged(void *param, DeckLinkDevice *device, bool)
{
auto *decklink = reinterpret_cast<DeckLinkOutput*>(param);
auto *decklink = reinterpret_cast<DeckLinkOutput *>(param);
std::lock_guard<std::recursive_mutex> lock(decklink->deviceMutex);
blog(LOG_DEBUG, "%s", device->GetHash().c_str());
@ -35,10 +35,10 @@ bool DeckLinkOutput::Activate(DeckLinkDevice *device, long long modeId)
return false;
if (instance->GetActiveModeId() == modeId &&
instance->GetActivePixelFormat() == pixelFormat &&
instance->GetActiveColorSpace() == colorSpace &&
instance->GetActiveColorRange() == colorRange &&
instance->GetActiveChannelFormat() == channelFormat)
instance->GetActivePixelFormat() == pixelFormat &&
instance->GetActiveColorSpace() == colorSpace &&
instance->GetActiveColorRange() == colorRange &&
instance->GetActiveChannelFormat() == channelFormat)
return false;
}
@ -57,7 +57,6 @@ bool DeckLinkOutput::Activate(DeckLinkDevice *device, long long modeId)
return false;
}
if (!instance->StartOutput(mode)) {
instance = nullptr;
return false;

View file

@ -10,7 +10,8 @@ protected:
int width;
int height;
static void DevicesChanged(void *param, DeckLinkDevice *device, bool added);
static void DevicesChanged(void *param, DeckLinkDevice *device,
bool added);
public:
const char *deviceHash;
@ -21,7 +22,8 @@ public:
size_t audio_size;
int keyerMode;
DeckLinkOutput(obs_output_t *output, DeckLinkDeviceDiscovery *discovery);
DeckLinkOutput(obs_output_t *output,
DeckLinkDeviceDiscovery *discovery);
virtual ~DeckLinkOutput(void);
obs_output_t *GetOutput(void) const;
bool Activate(DeckLinkDevice *device, long long modeId) override;

View file

@ -2,15 +2,14 @@
#include <emmintrin.h>
int check_buffer(struct audio_repack *repack,
uint32_t frame_count)
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;
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);
repack->packet_buffer =
brealloc(repack->packet_buffer, new_size);
if (!repack->packet_buffer)
return -1;
@ -30,8 +29,8 @@ int check_buffer(struct audio_repack *repack,
* | FL | FR | LFE |
*/
int repack_squash(struct audio_repack *repack,
const uint8_t *bsrc, uint32_t frame_count)
int repack_squash(struct audio_repack *repack, const uint8_t *bsrc,
uint32_t frame_count)
{
if (check_buffer(repack, frame_count) < 0)
return -1;
@ -55,8 +54,8 @@ int repack_squash(struct audio_repack *repack,
return 0;
}
int repack_squash_swap(struct audio_repack *repack,
const uint8_t *bsrc, uint32_t frame_count)
int repack_squash_swap(struct audio_repack *repack, const uint8_t *bsrc,
uint32_t frame_count)
{
if (check_buffer(repack, frame_count) < 0)
return -1;
@ -66,7 +65,8 @@ int repack_squash_swap(struct audio_repack *repack,
uint16_t *dst = (uint16_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));
__m128i buf =
_mm_shufflelo_epi16(target, _MM_SHUFFLE(2, 3, 1, 0));
_mm_storeu_si128((__m128i *)dst, buf);
dst += 8 - squash;
}
@ -74,20 +74,20 @@ int repack_squash_swap(struct audio_repack *repack,
}
int audio_repack_init(struct audio_repack *repack,
audio_repack_mode_t repack_mode, uint8_t sample_bit)
audio_repack_mode_t repack_mode, uint8_t sample_bit)
{
memset(repack, 0, sizeof(*repack));
if (sample_bit != 16)
return -1;
int _audio_repack_ch[8] = { 3, 4, 5, 6, 5, 6, 8, 8 };
int _audio_repack_ch[8] = {3, 4, 5, 6, 5, 6, 8, 8};
repack->base_src_size = 8 * (16 / 8);
repack->base_dst_size = _audio_repack_ch[repack_mode] * (16 / 8);
repack->extra_dst_size = 8 - _audio_repack_ch[repack_mode];
repack->repack_func = &repack_squash;
if (repack_mode == repack_mode_8to5ch_swap ||
repack_mode == repack_mode_8to6ch_swap ||
repack_mode == repack_mode_8ch_swap)
repack_mode == repack_mode_8to6ch_swap ||
repack_mode == repack_mode_8ch_swap)
repack->repack_func = &repack_squash_swap;
return 0;

View file

@ -11,22 +11,22 @@ extern "C" {
struct audio_repack;
typedef int (*audio_repack_func_t)(struct audio_repack *,
const uint8_t *, uint32_t);
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;
uint8_t *packet_buffer;
uint32_t packet_size;
uint32_t base_src_size;
uint32_t base_dst_size;
uint32_t extra_dst_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_8to3ch=0,
repack_mode_8to3ch = 0,
repack_mode_8to4ch,
repack_mode_8to5ch,
repack_mode_8to6ch,
@ -39,7 +39,8 @@ enum _audio_repack_mode {
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);
audio_repack_mode_t repack_mode,
uint8_t sample_bit);
extern void audio_repack_free(struct audio_repack *repack);
#ifdef __cplusplus

View file

@ -10,16 +10,13 @@ public:
{
audio_repack_init(&arepack, repack_mode, 16);
}
inline ~AudioRepacker()
{
audio_repack_free(&arepack);
}
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;}
inline operator struct audio_repack *() { return &arepack; }
inline struct audio_repack *operator->() { return &arepack; }
};

View file

@ -1,41 +1,41 @@
#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 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")
#define TEXT_COLOR_SPACE_DEFAULT obs_module_text("ColorSpace.Default")
#define TEXT_COLOR_RANGE obs_module_text("ColorRange")
#define TEXT_COLOR_RANGE_DEFAULT obs_module_text("ColorRange.Default")
#define TEXT_COLOR_RANGE_PARTIAL obs_module_text("ColorRange.Partial")
#define TEXT_COLOR_RANGE_FULL obs_module_text("ColorRange.Full")
#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_2_1CH obs_module_text("ChannelFormat.2_1ch")
#define TEXT_CHANNEL_FORMAT_4_0CH obs_module_text("ChannelFormat.4_0ch")
#define TEXT_CHANNEL_FORMAT_4_1CH obs_module_text("ChannelFormat.4_1ch")
#define TEXT_CHANNEL_FORMAT_5_1CH obs_module_text("ChannelFormat.5_1ch")
#define TEXT_CHANNEL_FORMAT_7_1CH obs_module_text("ChannelFormat.7_1ch")
#define TEXT_BUFFERING obs_module_text("Buffering")
#define TEXT_DWNS obs_module_text("DeactivateWhenNotShowing")
#define TEXT_AUTO_START obs_module_text("AutoStart")
#define TEXT_ENABLE_KEYER obs_module_text("Keyer")
#define TEXT_SWAP obs_module_text("SwapFC-LFE")
#define TEXT_SWAP_TOOLTIP obs_module_text("SwapFC-LFE.Tooltip")
#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")
#define TEXT_COLOR_SPACE_DEFAULT obs_module_text("ColorSpace.Default")
#define TEXT_COLOR_RANGE obs_module_text("ColorRange")
#define TEXT_COLOR_RANGE_DEFAULT obs_module_text("ColorRange.Default")
#define TEXT_COLOR_RANGE_PARTIAL obs_module_text("ColorRange.Partial")
#define TEXT_COLOR_RANGE_FULL obs_module_text("ColorRange.Full")
#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_2_1CH obs_module_text("ChannelFormat.2_1ch")
#define TEXT_CHANNEL_FORMAT_4_0CH obs_module_text("ChannelFormat.4_0ch")
#define TEXT_CHANNEL_FORMAT_4_1CH obs_module_text("ChannelFormat.4_1ch")
#define TEXT_CHANNEL_FORMAT_5_1CH obs_module_text("ChannelFormat.5_1ch")
#define TEXT_CHANNEL_FORMAT_7_1CH obs_module_text("ChannelFormat.7_1ch")
#define TEXT_BUFFERING obs_module_text("Buffering")
#define TEXT_DWNS obs_module_text("DeactivateWhenNotShowing")
#define TEXT_AUTO_START obs_module_text("AutoStart")
#define TEXT_ENABLE_KEYER obs_module_text("Keyer")
#define TEXT_SWAP obs_module_text("SwapFC-LFE")
#define TEXT_SWAP_TOOLTIP obs_module_text("SwapFC-LFE.Tooltip")

View file

@ -17,4 +17,6 @@ ChannelFormat.5_1ch="5.1ch"
ChannelFormat.7_1ch="7.1ch"
DeactivateWhenNotShowing="التعطيل عندما لا يكون ظاهراً"
AutoStart="البدء تلقائياً مع التشغيل"
VideoConnection="مدخل الفيديو"
AudioConnection="مدخل الصوت"

View file

@ -1,4 +1,4 @@
BlackmagicDevice="Blackmagic-Gerät"
BlackmagicDevice="BlackmagicGerät"
Device="Gerät"
Mode="Modus"
Buffering="Puffern benutzen"
@ -11,16 +11,16 @@ ColorRange.Partial="Begrenzt"
ColorRange.Full="Voll"
ChannelFormat="Kanal"
ChannelFormat.None="Keins"
ChannelFormat.2_0ch="2 Kanal"
ChannelFormat.2_1ch="2.1 Kanal"
ChannelFormat.4_0ch="4 Kanal"
ChannelFormat.4_1ch="4.1 Kanal"
ChannelFormat.5_1ch="5.1 Kanal"
ChannelFormat.7_1ch="7.1 Kanal"
ChannelFormat.2_0ch="2Kanal"
ChannelFormat.2_1ch="2.1Kanal"
ChannelFormat.4_0ch="4Kanal"
ChannelFormat.4_1ch="4.1Kanal"
ChannelFormat.5_1ch="5.1Kanal"
ChannelFormat.7_1ch="7.1Kanal"
DeactivateWhenNotShowing="Deaktivieren, wenn die Quelle nicht angezeigt wird"
AutoStart="Automatisch beim Öffnen starten"
SwapFC-LFE="FC und LFE tauschen"
SwapFC-LFE.Tooltip="Vorderen Front-Center-Kanal und LFE-Kanal tauschen"
SwapFC-LFE.Tooltip="Vorderen FrontCenterKanal und LFEKanal tauschen"
VideoConnection="Videoverbindung"
AudioConnection="Audioverbindung"

View file

@ -1,5 +1,26 @@
BlackmagicDevice="Dispositivo Blackmagic"
Device="Dispositivo"
Mode="Modo"
Buffering="Utilizar o almacenamento no búfer"
Buffering="Utilizar o almacenamento na memoria temporal"
PixelFormat="Formato do píxel"
ColorSpace="Espazo de cor"
ColorSpace.Default="Predeterminado"
ColorRange="Gama de cores"
ColorRange.Default="Predeterminado"
ColorRange.Partial="Parcial"
ColorRange.Full="Total"
ChannelFormat="Canle"
ChannelFormat.None="Ningún"
ChannelFormat.2_0ch="2ch"
ChannelFormat.2_1ch="2.1ch"
ChannelFormat.4_0ch="4ch"
ChannelFormat.4_1ch="4.1ch"
ChannelFormat.5_1ch="5.1ch"
ChannelFormat.7_1ch="7.1ch"
DeactivateWhenNotShowing="Desactivado cando non se amose"
AutoStart="Comezar no inicio"
SwapFC-LFE="Intercambiar FC e LFE"
SwapFC-LFE.Tooltip="Intercambiar a canle central frontal e a canle LFE"
VideoConnection="Conexión de vídeo"
AudioConnection="Conexión de son"

View file

@ -2,7 +2,13 @@ BlackmagicDevice="Dispozitiv Blackmagic"
Device="Dispozitiv"
Mode="Mod"
Buffering="Folosește zona tampon"
PixelFormat="Formatul pixelilor"
PixelFormat="Format pentru pixeli"
ColorSpace="Spațiu de culori"
ColorSpace.Default="Implicit"
ColorRange="Gamă de culori"
ColorRange.Default="Implicit"
ColorRange.Partial="Parțială"
ColorRange.Full="Completă"
VideoConnection="Conexiune video"
AudioConnection="Conexiune audio"

View file

@ -2,4 +2,25 @@ BlackmagicDevice="Blackmagic naprave"
Device="Naprava"
Mode="Način"
Buffering="Uporabi medpomnilnik"
PixelFormat="Oblika sl. točk"
ColorSpace="Barvni prostor"
ColorSpace.Default="Privzeto"
ColorRange="Barvni razpon"
ColorRange.Default="Privzeto"
ColorRange.Partial="Delno"
ColorRange.Full="Polno"
ChannelFormat="Kanal"
ChannelFormat.None="Brez"
ChannelFormat.2_0ch="2 kan."
ChannelFormat.2_1ch="2.1 kan."
ChannelFormat.4_0ch="4 kan."
ChannelFormat.4_1ch="4.1 kan."
ChannelFormat.5_1ch="5.1 kan."
ChannelFormat.7_1ch="7.1 kan."
DeactivateWhenNotShowing="Onemogoči, ko ni prikazano"
AutoStart="Samodejno zaženi ob zagonu"
SwapFC-LFE="Zamenjaj SS in nizke tone"
SwapFC-LFE.Tooltip="Zamenjaj sprednji sredinski kanal in kanal z nizkimi toni"
VideoConnection="Slikovna povezava"
AudioConnection="Zvočna povezava"

View file

@ -3,7 +3,9 @@ Device="Пристрій"
Mode="Режим"
Buffering="Увімкнути буферизацію"
PixelFormat="Формат пікселів"
ColorSpace="Колірний простір"
ColorSpace.Default="За замовчуванням"
ColorRange="Колірний діапазон"
ColorRange.Default="За замовчуванням"
ColorRange.Partial="Частковий"
ColorRange.Full="Повний"

View file

@ -54,8 +54,8 @@ DeckLinkDevice *DeckLinkDeviceDiscovery::FindByHash(const char *hash)
return ret;
}
HRESULT STDMETHODCALLTYPE DeckLinkDeviceDiscovery::DeckLinkDeviceArrived(
IDeckLink *device)
HRESULT STDMETHODCALLTYPE
DeckLinkDeviceDiscovery::DeckLinkDeviceArrived(IDeckLink *device)
{
DeckLinkDevice *newDev = new DeckLinkDevice(device);
if (!newDev->Init()) {
@ -73,8 +73,8 @@ HRESULT STDMETHODCALLTYPE DeckLinkDeviceDiscovery::DeckLinkDeviceArrived(
return S_OK;
}
HRESULT STDMETHODCALLTYPE DeckLinkDeviceDiscovery::DeckLinkDeviceRemoved(
IDeckLink *device)
HRESULT STDMETHODCALLTYPE
DeckLinkDeviceDiscovery::DeckLinkDeviceRemoved(IDeckLink *device)
{
std::lock_guard<std::recursive_mutex> lock(deviceMutex);
@ -98,7 +98,7 @@ ULONG STDMETHODCALLTYPE DeckLinkDeviceDiscovery::AddRef(void)
}
HRESULT STDMETHODCALLTYPE DeckLinkDeviceDiscovery::QueryInterface(REFIID iid,
LPVOID *ppv)
LPVOID *ppv)
{
HRESULT result = E_NOINTERFACE;
@ -110,7 +110,7 @@ HRESULT STDMETHODCALLTYPE DeckLinkDeviceDiscovery::QueryInterface(REFIID iid,
AddRef();
result = S_OK;
} else if (memcmp(&iid, &IID_IDeckLinkDeviceNotificationCallback,
sizeof(REFIID)) == 0) {
sizeof(REFIID)) == 0) {
*ppv = (IDeckLinkDeviceNotificationCallback *)this;
AddRef();
result = S_OK;

View file

@ -9,7 +9,7 @@
class DeckLinkDevice;
typedef void (*DeviceChangeCallback)(void *param, DeckLinkDevice *device,
bool added);
bool added);
struct DeviceChangeInfo {
DeviceChangeCallback callback;
@ -19,11 +19,11 @@ struct DeviceChangeInfo {
class DeckLinkDeviceDiscovery : public IDeckLinkDeviceNotificationCallback {
protected:
ComPtr<IDeckLinkDiscovery> discovery;
long refCount = 1;
bool initialized = false;
long refCount = 1;
bool initialized = false;
std::recursive_mutex deviceMutex;
std::vector<DeckLinkDevice*> devices;
std::vector<DeckLinkDevice *> devices;
std::vector<DeviceChangeInfo> callbacks;
public:
@ -44,8 +44,7 @@ public:
info.param = param;
for (DeviceChangeInfo &curCB : callbacks) {
if (curCB.callback == callback &&
curCB.param == param)
if (curCB.callback == callback && curCB.param == param)
return;
}
@ -60,7 +59,7 @@ public:
DeviceChangeInfo &curCB = callbacks[i];
if (curCB.callback == callback &&
curCB.param == param) {
curCB.param == param) {
callbacks.erase(callbacks.begin() + i);
return;
}
@ -69,9 +68,9 @@ public:
DeckLinkDevice *FindByHash(const char *hash);
inline void Lock() {deviceMutex.lock();}
inline void Unlock() {deviceMutex.unlock();}
inline const std::vector<DeckLinkDevice*> &GetDevices() const
inline void Lock() { deviceMutex.lock(); }
inline void Unlock() { deviceMutex.unlock(); }
inline const std::vector<DeckLinkDevice *> &GetDevices() const
{
return devices;
}

View file

@ -13,7 +13,8 @@
static inline enum video_format ConvertPixelFormat(BMDPixelFormat format)
{
switch (format) {
case bmdFormat8BitBGRA: return VIDEO_FORMAT_BGRX;
case bmdFormat8BitBGRA:
return VIDEO_FORMAT_BGRX;
default:
case bmdFormat8BitYUV:;
@ -38,7 +39,8 @@ static inline int ConvertChannelFormat(speaker_layout format)
}
}
static inline audio_repack_mode_t ConvertRepackFormat(speaker_layout format, bool swap)
static inline audio_repack_mode_t ConvertRepackFormat(speaker_layout format,
bool swap)
{
switch (format) {
case SPEAKERS_2POINT1:
@ -46,11 +48,11 @@ static inline audio_repack_mode_t ConvertRepackFormat(speaker_layout format, boo
case SPEAKERS_4POINT0:
return repack_mode_8to4ch;
case SPEAKERS_4POINT1:
return swap? repack_mode_8to5ch_swap:repack_mode_8to5ch;
return swap ? repack_mode_8to5ch_swap : repack_mode_8to5ch;
case SPEAKERS_5POINT1:
return swap ? repack_mode_8to6ch_swap : repack_mode_8to6ch;
case SPEAKERS_7POINT1:
return swap ? repack_mode_8ch_swap: repack_mode_8ch;
return swap ? repack_mode_8ch_swap : repack_mode_8ch;
default:
assert(false && "No repack requested");
return (audio_repack_mode_t)-1;
@ -58,21 +60,18 @@ static inline audio_repack_mode_t ConvertRepackFormat(speaker_layout format, boo
}
DeckLinkDeviceInstance::DeckLinkDeviceInstance(DecklinkBase *decklink_,
DeckLinkDevice *device_) :
currentFrame(), currentPacket(), decklink(decklink_), device(device_)
DeckLinkDevice *device_)
: currentFrame(), currentPacket(), decklink(decklink_), device(device_)
{
currentPacket.samples_per_sec = 48000;
currentPacket.speakers = SPEAKERS_STEREO;
currentPacket.format = AUDIO_FORMAT_16BIT;
currentPacket.speakers = SPEAKERS_STEREO;
currentPacket.format = AUDIO_FORMAT_16BIT;
}
DeckLinkDeviceInstance::~DeckLinkDeviceInstance()
{
}
DeckLinkDeviceInstance::~DeckLinkDeviceInstance() {}
void DeckLinkDeviceInstance::HandleAudioPacket(
IDeckLinkAudioInputPacket *audioPacket,
const uint64_t timestamp)
IDeckLinkAudioInputPacket *audioPacket, const uint64_t timestamp)
{
if (audioPacket == nullptr)
return;
@ -83,11 +82,12 @@ void DeckLinkDeviceInstance::HandleAudioPacket(
return;
}
const uint32_t frameCount = (uint32_t)audioPacket->GetSampleFrameCount();
currentPacket.frames = frameCount;
currentPacket.timestamp = timestamp;
const uint32_t frameCount =
(uint32_t)audioPacket->GetSampleFrameCount();
currentPacket.frames = frameCount;
currentPacket.timestamp = timestamp;
if (decklink && !static_cast<DeckLinkInput*>(decklink)->buffering) {
if (decklink && !static_cast<DeckLinkInput *>(decklink)->buffering) {
currentPacket.timestamp = os_gettime_ns();
currentPacket.timestamp -=
(uint64_t)frameCount * 1000000000ULL /
@ -99,8 +99,9 @@ void DeckLinkDeviceInstance::HandleAudioPacket(
if (channelFormat != SPEAKERS_UNKNOWN &&
channelFormat != SPEAKERS_MONO &&
channelFormat != SPEAKERS_STEREO &&
(channelFormat != SPEAKERS_7POINT1 || static_cast<DeckLinkInput*>(decklink)->swap)
&& maxdevicechannel >= 8) {
(channelFormat != SPEAKERS_7POINT1 ||
static_cast<DeckLinkInput *>(decklink)->swap) &&
maxdevicechannel >= 8) {
if (audioRepacker->repack((uint8_t *)bytes, frameCount) < 0) {
LOG(LOG_ERROR, "Failed to convert audio packet data");
@ -112,13 +113,15 @@ void DeckLinkDeviceInstance::HandleAudioPacket(
}
nextAudioTS = timestamp +
((uint64_t)frameCount * 1000000000ULL / 48000ULL) + 1;
((uint64_t)frameCount * 1000000000ULL / 48000ULL) + 1;
obs_source_output_audio(static_cast<DeckLinkInput*>(decklink)->GetSource(), &currentPacket);
obs_source_output_audio(
static_cast<DeckLinkInput *>(decklink)->GetSource(),
&currentPacket);
}
void DeckLinkDeviceInstance::HandleVideoFrame(
IDeckLinkVideoInputFrame *videoFrame, const uint64_t timestamp)
IDeckLinkVideoInputFrame *videoFrame, const uint64_t timestamp)
{
if (videoFrame == nullptr)
return;
@ -129,13 +132,15 @@ void DeckLinkDeviceInstance::HandleVideoFrame(
return;
}
currentFrame.data[0] = (uint8_t *)bytes;
currentFrame.data[0] = (uint8_t *)bytes;
currentFrame.linesize[0] = (uint32_t)videoFrame->GetRowBytes();
currentFrame.width = (uint32_t)videoFrame->GetWidth();
currentFrame.height = (uint32_t)videoFrame->GetHeight();
currentFrame.timestamp = timestamp;
currentFrame.width = (uint32_t)videoFrame->GetWidth();
currentFrame.height = (uint32_t)videoFrame->GetHeight();
currentFrame.timestamp = timestamp;
obs_source_output_video2(static_cast<DeckLinkInput*>(decklink)->GetSource(), &currentFrame);
obs_source_output_video2(
static_cast<DeckLinkInput *>(decklink)->GetSource(),
&currentFrame);
}
void DeckLinkDeviceInstance::FinalizeStream()
@ -145,8 +150,7 @@ void DeckLinkDeviceInstance::FinalizeStream()
if (channelFormat != SPEAKERS_UNKNOWN)
input->DisableAudioInput();
if (audioRepacker != nullptr)
{
if (audioRepacker != nullptr) {
delete audioRepacker;
audioRepacker = nullptr;
}
@ -163,7 +167,7 @@ void DeckLinkDeviceInstance::SetupVideoFormat(DeckLinkDeviceMode *mode_)
currentFrame.format = ConvertPixelFormat(pixelFormat);
colorSpace = static_cast<DeckLinkInput*>(decklink)->GetColorSpace();
colorSpace = static_cast<DeckLinkInput *>(decklink)->GetColorSpace();
if (colorSpace == VIDEO_CS_DEFAULT) {
const BMDDisplayModeFlags flags = mode_->GetDisplayModeFlags();
if (flags & bmdDisplayModeColorspaceRec709)
@ -176,24 +180,25 @@ void DeckLinkDeviceInstance::SetupVideoFormat(DeckLinkDeviceMode *mode_)
activeColorSpace = colorSpace;
}
colorRange = static_cast<DeckLinkInput*>(decklink)->GetColorRange();
colorRange = static_cast<DeckLinkInput *>(decklink)->GetColorRange();
currentFrame.range = colorRange;
video_format_get_parameters(activeColorSpace, colorRange,
currentFrame.color_matrix, currentFrame.color_range_min,
currentFrame.color_range_max);
currentFrame.color_matrix,
currentFrame.color_range_min,
currentFrame.color_range_max);
#ifdef LOG_SETUP_VIDEO_FORMAT
LOG(LOG_INFO, "Setup video format: %s, %s, %s",
pixelFormat == bmdFormat8BitYUV ? "YUV" : "RGB",
activeColorSpace == VIDEO_CS_709 ? "BT.709" : "BT.601",
colorRange == VIDEO_RANGE_FULL ? "full" : "limited");
pixelFormat == bmdFormat8BitYUV ? "YUV" : "RGB",
activeColorSpace == VIDEO_CS_709 ? "BT.709" : "BT.601",
colorRange == VIDEO_RANGE_FULL ? "full" : "limited");
#endif
}
bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_,
BMDVideoConnection bmdVideoConnection,
BMDAudioConnection bmdAudioConnection)
BMDVideoConnection bmdVideoConnection,
BMDAudioConnection bmdAudioConnection)
{
if (mode != nullptr)
return false;
@ -205,33 +210,33 @@ 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)
{
(void **)&deckLinkConfiguration);
if (result != S_OK) {
LOG(LOG_ERROR,
"Could not obtain the IDeckLinkConfiguration interface: %08x\n",
result);
"Could not obtain the IDeckLinkConfiguration interface: %08x\n",
result);
} else {
if (bmdVideoConnection > 0) {
result = deckLinkConfiguration->SetInt(
bmdDeckLinkConfigVideoInputConnection, bmdVideoConnection);
bmdDeckLinkConfigVideoInputConnection,
bmdVideoConnection);
if (result != S_OK) {
LOG(LOG_ERROR,
"Couldn't set input video port to %d\n\n",
bmdVideoConnection);
"Couldn't set input video port to %d\n\n",
bmdVideoConnection);
}
}
if (bmdAudioConnection > 0) {
result = deckLinkConfiguration->SetInt(
bmdDeckLinkConfigAudioInputConnection, bmdAudioConnection);
bmdDeckLinkConfigAudioInputConnection,
bmdAudioConnection);
if (result != S_OK) {
LOG(LOG_ERROR,
"Couldn't set input audio port to %d\n\n",
bmdVideoConnection);
"Couldn't set input audio port to %d\n\n",
bmdVideoConnection);
}
}
}
@ -248,12 +253,13 @@ bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_,
flags = bmdVideoInputEnableFormatDetection;
} else {
displayMode = mode_->GetDisplayMode();
pixelFormat = static_cast<DeckLinkInput*>(decklink)->GetPixelFormat();
pixelFormat =
static_cast<DeckLinkInput *>(decklink)->GetPixelFormat();
flags = bmdVideoInputFlagDefault;
}
const HRESULT videoResult = input->EnableVideoInput(displayMode,
pixelFormat, flags);
const HRESULT videoResult =
input->EnableVideoInput(displayMode, pixelFormat, flags);
if (videoResult != S_OK) {
LOG(LOG_ERROR, "Failed to enable video input");
return false;
@ -261,28 +267,30 @@ bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_,
SetupVideoFormat(mode_);
channelFormat = static_cast<DeckLinkInput*>(decklink)->GetChannelFormat();
channelFormat =
static_cast<DeckLinkInput *>(decklink)->GetChannelFormat();
currentPacket.speakers = channelFormat;
swap = static_cast<DeckLinkInput*>(decklink)->swap;
swap = static_cast<DeckLinkInput *>(decklink)->swap;
int maxdevicechannel = device->GetMaxChannel();
if (channelFormat != SPEAKERS_UNKNOWN) {
const int channel = ConvertChannelFormat(channelFormat);
const HRESULT audioResult = input->EnableAudioInput(
bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger,
channel);
bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger,
channel);
if (audioResult != S_OK)
LOG(LOG_WARNING, "Failed to enable audio input; continuing...");
LOG(LOG_WARNING,
"Failed to enable audio input; continuing...");
if (channelFormat != SPEAKERS_UNKNOWN &&
channelFormat != SPEAKERS_MONO &&
channelFormat != SPEAKERS_STEREO &&
(channelFormat != SPEAKERS_7POINT1 || swap)
&& maxdevicechannel >= 8) {
(channelFormat != SPEAKERS_7POINT1 || swap) &&
maxdevicechannel >= 8) {
const audio_repack_mode_t repack_mode = ConvertRepackFormat
(channelFormat, swap);
const audio_repack_mode_t repack_mode =
ConvertRepackFormat(channelFormat, swap);
audioRepacker = new AudioRepacker(repack_mode);
}
}
@ -310,7 +318,7 @@ bool DeckLinkDeviceInstance::StopCapture(void)
return false;
LOG(LOG_INFO, "Stopping capture of '%s'...",
GetDevice()->GetDisplayName().c_str());
GetDevice()->GetDisplayName().c_str());
input->StopStreams();
FinalizeStream();
@ -331,18 +339,15 @@ bool DeckLinkDeviceInstance::StartOutput(DeckLinkDeviceMode *mode_)
return false;
const HRESULT videoResult = output->EnableVideoOutput(
mode_->GetDisplayMode(),
bmdVideoOutputFlagDefault);
mode_->GetDisplayMode(), bmdVideoOutputFlagDefault);
if (videoResult != S_OK) {
LOG(LOG_ERROR, "Failed to enable video output");
return false;
}
const HRESULT audioResult = output->EnableAudioOutput(
bmdAudioSampleRate48kHz,
bmdAudioSampleType16bitInteger,
2,
bmdAudioOutputStreamTimestamped);
bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, 2,
bmdAudioOutputStreamTimestamped);
if (audioResult != S_OK) {
LOG(LOG_ERROR, "Failed to enable audio output");
return false;
@ -362,7 +367,7 @@ bool DeckLinkDeviceInstance::StartOutput(DeckLinkDeviceMode *mode_)
}
}
auto decklinkOutput = dynamic_cast<DeckLinkOutput*>(decklink);
auto decklinkOutput = dynamic_cast<DeckLinkOutput *>(decklink);
if (decklinkOutput == nullptr)
return false;
@ -378,13 +383,11 @@ bool DeckLinkDeviceInstance::StartOutput(DeckLinkDeviceMode *mode_)
HRESULT result;
result = output->CreateVideoFrame(decklinkOutput->GetWidth(),
decklinkOutput->GetHeight(),
rowBytes,
pixelFormat,
bmdFrameFlagDefault,
&decklinkOutputFrame);
decklinkOutput->GetHeight(), rowBytes,
pixelFormat, bmdFrameFlagDefault,
&decklinkOutputFrame);
if (result != S_OK) {
blog(LOG_ERROR ,"failed to make frame 0x%X", result);
blog(LOG_ERROR, "failed to make frame 0x%X", result);
return false;
}
@ -397,7 +400,7 @@ bool DeckLinkDeviceInstance::StopOutput()
return false;
LOG(LOG_INFO, "Stopping output of '%s'...",
GetDevice()->GetDisplayName().c_str());
GetDevice()->GetDisplayName().c_str());
output->DisableVideoOutput();
output->DisableAudioOutput();
@ -412,12 +415,12 @@ bool DeckLinkDeviceInstance::StopOutput()
void DeckLinkDeviceInstance::DisplayVideoFrame(video_data *frame)
{
auto decklinkOutput = dynamic_cast<DeckLinkOutput*>(decklink);
auto decklinkOutput = dynamic_cast<DeckLinkOutput *>(decklink);
if (decklinkOutput == nullptr)
return;
uint8_t *destData;
decklinkOutputFrame->GetBytes((void**)&destData);
decklinkOutputFrame->GetBytes((void **)&destData);
uint8_t *outData = frame->data[0];
@ -426,8 +429,8 @@ void DeckLinkDeviceInstance::DisplayVideoFrame(video_data *frame)
rowBytes = decklinkOutput->GetWidth() * 4;
}
std::copy(outData, outData + (decklinkOutput->GetHeight() *
rowBytes), destData);
std::copy(outData, outData + (decklinkOutput->GetHeight() * rowBytes),
destData);
output->DisplayVideoFrameSync(decklinkOutputFrame);
}
@ -435,16 +438,15 @@ void DeckLinkDeviceInstance::DisplayVideoFrame(video_data *frame)
void DeckLinkDeviceInstance::WriteAudio(audio_data *frames)
{
uint32_t sampleFramesWritten;
output->WriteAudioSamplesSync(frames->data[0],
frames->frames,
&sampleFramesWritten);
output->WriteAudioSamplesSync(frames->data[0], frames->frames,
&sampleFramesWritten);
}
#define TIME_BASE 1000000000
HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::VideoInputFrameArrived(
IDeckLinkVideoInputFrame *videoFrame,
IDeckLinkAudioInputPacket *audioPacket)
IDeckLinkVideoInputFrame *videoFrame,
IDeckLinkAudioInputPacket *audioPacket)
{
BMDTimeValue videoTS = 0;
BMDTimeValue videoDur = 0;
@ -481,9 +483,8 @@ HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::VideoInputFrameArrived(
}
HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::VideoInputFormatChanged(
BMDVideoInputFormatChangedEvents events,
IDeckLinkDisplayMode *newMode,
BMDDetectedVideoInputFormatFlags detectedSignalFlags)
BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *newMode,
BMDDetectedVideoInputFormatFlags detectedSignalFlags)
{
input->PauseStreams();
@ -506,8 +507,8 @@ HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::VideoInputFormatChanged(
}
}
const HRESULT videoResult = input->EnableVideoInput(displayMode,
pixelFormat, bmdVideoInputEnableFormatDetection);
const HRESULT videoResult = input->EnableVideoInput(
displayMode, pixelFormat, bmdVideoInputEnableFormatDetection);
if (videoResult != S_OK) {
LOG(LOG_ERROR, "Failed to enable video input");
input->StopStreams();
@ -530,7 +531,7 @@ ULONG STDMETHODCALLTYPE DeckLinkDeviceInstance::AddRef(void)
}
HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::QueryInterface(REFIID iid,
LPVOID *ppv)
LPVOID *ppv)
{
HRESULT result = E_NOINTERFACE;
@ -542,7 +543,7 @@ HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::QueryInterface(REFIID iid,
AddRef();
result = S_OK;
} else if (memcmp(&iid, &IID_IDeckLinkNotificationCallback,
sizeof(REFIID)) == 0) {
sizeof(REFIID)) == 0) {
*ppv = (IDeckLinkNotificationCallback *)this;
AddRef();
result = S_OK;

View file

@ -1,6 +1,7 @@
#pragma once
#define LOG(level, message, ...) blog(level, "%s: " message, "decklink", ##__VA_ARGS__)
#define LOG(level, message, ...) \
blog(level, "%s: " message, "decklink", ##__VA_ARGS__)
#include <obs-module.h>
#include "decklink-device.hpp"
@ -13,25 +14,25 @@ class DeckLinkDeviceInstance : public IDeckLinkInputCallback {
protected:
struct obs_source_frame2 currentFrame;
struct obs_source_audio currentPacket;
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;
video_colorspace activeColorSpace = VIDEO_CS_DEFAULT;
video_range_type colorRange = VIDEO_RANGE_DEFAULT;
ComPtr<IDeckLinkInput> input;
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;
video_colorspace activeColorSpace = VIDEO_CS_DEFAULT;
video_range_type colorRange = VIDEO_RANGE_DEFAULT;
ComPtr<IDeckLinkInput> input;
ComPtr<IDeckLinkOutput> output;
volatile long refCount = 1;
int64_t audioOffset = 0;
uint64_t nextAudioTS = 0;
uint64_t lastVideoTS = 0;
AudioRepacker *audioRepacker = nullptr;
speaker_layout channelFormat = SPEAKERS_STEREO;
bool swap;
volatile long refCount = 1;
int64_t audioOffset = 0;
uint64_t nextAudioTS = 0;
uint64_t lastVideoTS = 0;
AudioRepacker *audioRepacker = nullptr;
speaker_layout channelFormat = SPEAKERS_STEREO;
bool swap;
IDeckLinkMutableVideoFrame *decklinkOutputFrame = nullptr;
@ -39,45 +40,63 @@ protected:
void SetupVideoFormat(DeckLinkDeviceMode *mode_);
void HandleAudioPacket(IDeckLinkAudioInputPacket *audioPacket,
const uint64_t timestamp);
const uint64_t timestamp);
void HandleVideoFrame(IDeckLinkVideoInputFrame *videoFrame,
const uint64_t timestamp);
const uint64_t timestamp);
public:
DeckLinkDeviceInstance(DecklinkBase *decklink, DeckLinkDevice *device);
virtual ~DeckLinkDeviceInstance();
inline DeckLinkDevice *GetDevice() const {return device;}
inline DeckLinkDevice *GetDevice() const { return device; }
inline long long GetActiveModeId() const
{
return mode ? mode->GetId() : 0;
}
inline BMDPixelFormat GetActivePixelFormat() const {return pixelFormat;}
inline video_colorspace GetActiveColorSpace() const {return colorSpace;}
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 BMDPixelFormat GetActivePixelFormat() const
{
return pixelFormat;
}
inline video_colorspace GetActiveColorSpace() const
{
return colorSpace;
}
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;}
inline DeckLinkDeviceMode *GetMode() const { return mode; }
bool StartCapture(DeckLinkDeviceMode *mode,
BMDVideoConnection bmdVideoConnection,
BMDAudioConnection bmdAudioConnection);
BMDVideoConnection bmdVideoConnection,
BMDAudioConnection bmdAudioConnection);
bool StopCapture(void);
bool StartOutput(DeckLinkDeviceMode *mode_);
bool StopOutput(void);
HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(
IDeckLinkVideoInputFrame *videoFrame,
IDeckLinkAudioInputPacket *audioPacket);
HRESULT STDMETHODCALLTYPE
VideoInputFrameArrived(IDeckLinkVideoInputFrame *videoFrame,
IDeckLinkAudioInputPacket *audioPacket);
HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(
BMDVideoInputFormatChangedEvents events,
IDeckLinkDisplayMode *newMode,
BMDDetectedVideoInputFormatFlags detectedSignalFlags);
BMDVideoInputFormatChangedEvents events,
IDeckLinkDisplayMode *newMode,
BMDDetectedVideoInputFormatFlags detectedSignalFlags);
ULONG STDMETHODCALLTYPE AddRef(void);
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv);

View file

@ -1,7 +1,7 @@
#include "decklink-device-mode.hpp"
DeckLinkDeviceMode::DeckLinkDeviceMode(IDeckLinkDisplayMode *mode,
long long id) : id(id), mode(mode)
DeckLinkDeviceMode::DeckLinkDeviceMode(IDeckLinkDisplayMode *mode, long long id)
: id(id), mode(mode)
{
if (mode == nullptr)
return;
@ -13,8 +13,8 @@ DeckLinkDeviceMode::DeckLinkDeviceMode(IDeckLinkDisplayMode *mode,
DeckLinkStringToStdString(decklinkStringName, name);
}
DeckLinkDeviceMode::DeckLinkDeviceMode(const std::string& name, long long id) :
id(id), mode(nullptr), name(name)
DeckLinkDeviceMode::DeckLinkDeviceMode(const std::string &name, long long id)
: id(id), mode(nullptr), name(name)
{
}
@ -61,7 +61,7 @@ long long DeckLinkDeviceMode::GetId(void) const
return id;
}
const std::string& DeckLinkDeviceMode::GetName(void) const
const std::string &DeckLinkDeviceMode::GetName(void) const
{
return name;
}

View file

@ -4,23 +4,23 @@
#include <string>
#define MODE_ID_AUTO -1
#define MODE_ID_AUTO -1
class DeckLinkDeviceMode {
protected:
long long id;
long long id;
IDeckLinkDisplayMode *mode;
std::string name;
std::string name;
public:
DeckLinkDeviceMode(IDeckLinkDisplayMode *mode, long long id);
DeckLinkDeviceMode(const std::string& name, long long id);
DeckLinkDeviceMode(const std::string &name, long long id);
virtual ~DeckLinkDeviceMode(void);
BMDDisplayMode GetDisplayMode(void) const;
BMDDisplayModeFlags GetDisplayModeFlags(void) const;
long long GetId(void) const;
const std::string& GetName(void) const;
const std::string &GetName(void) const;
void SetMode(IDeckLinkDisplayMode *mode);

View file

@ -4,9 +4,7 @@
#include <util/threading.h>
DeckLinkDevice::DeckLinkDevice(IDeckLink *device_) : device(device_)
{
}
DeckLinkDevice::DeckLinkDevice(IDeckLink *device_) : device(device_) {}
DeckLinkDevice::~DeckLinkDevice(void)
{
@ -34,15 +32,15 @@ bool DeckLinkDevice::Init()
{
ComPtr<IDeckLinkAttributes> attributes;
const HRESULT result = device->QueryInterface(IID_IDeckLinkAttributes,
(void **)&attributes);
(void **)&attributes);
if (result == S_OK) {
decklink_bool_t detectable = false;
if (attributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection,
&detectable) == S_OK && !!detectable) {
DeckLinkDeviceMode *mode = new DeckLinkDeviceMode(
"Auto",
MODE_ID_AUTO);
&detectable) == S_OK &&
!!detectable) {
DeckLinkDeviceMode *mode =
new DeckLinkDeviceMode("Auto", MODE_ID_AUTO);
inputModes.push_back(mode);
inputModeIdMap[MODE_ID_AUTO] = mode;
}
@ -50,7 +48,8 @@ bool DeckLinkDevice::Init()
// Find input modes
ComPtr<IDeckLinkInput> input;
if (device->QueryInterface(IID_IDeckLinkInput, (void **) &input) == S_OK) {
if (device->QueryInterface(IID_IDeckLinkInput, (void **)&input) ==
S_OK) {
IDeckLinkDisplayModeIterator *modeIterator;
if (input->GetDisplayModeIterator(&modeIterator) == S_OK) {
IDeckLinkDisplayMode *displayMode;
@ -61,7 +60,8 @@ bool DeckLinkDevice::Init()
continue;
DeckLinkDeviceMode *mode =
new DeckLinkDeviceMode(displayMode, modeId);
new DeckLinkDeviceMode(displayMode,
modeId);
inputModes.push_back(mode);
inputModeIdMap[modeId] = mode;
displayMode->Release();
@ -74,19 +74,20 @@ bool DeckLinkDevice::Init()
// Get supported video connections
attributes->GetInt(BMDDeckLinkVideoInputConnections,
&supportedVideoInputConnections);
&supportedVideoInputConnections);
attributes->GetInt(BMDDeckLinkVideoOutputConnections,
&supportedVideoOutputConnections);
&supportedVideoOutputConnections);
// Get supported audio connections
attributes->GetInt(BMDDeckLinkAudioInputConnections,
&supportedAudioInputConnections);
&supportedAudioInputConnections);
attributes->GetInt(BMDDeckLinkAudioOutputConnections,
&supportedAudioOutputConnections);
&supportedAudioOutputConnections);
// find output modes
ComPtr<IDeckLinkOutput> output;
if (device->QueryInterface(IID_IDeckLinkOutput, (void **) &output) == S_OK) {
if (device->QueryInterface(IID_IDeckLinkOutput, (void **)&output) ==
S_OK) {
IDeckLinkDisplayModeIterator *modeIterator;
if (output->GetDisplayModeIterator(&modeIterator) == S_OK) {
@ -98,7 +99,8 @@ bool DeckLinkDevice::Init()
continue;
DeckLinkDeviceMode *mode =
new DeckLinkDeviceMode(displayMode, modeId);
new DeckLinkDeviceMode(displayMode,
modeId);
outputModes.push_back(mode);
outputModeIdMap[modeId] = mode;
displayMode->Release();
@ -111,9 +113,9 @@ bool DeckLinkDevice::Init()
// get keyer support
attributes->GetFlag(BMDDeckLinkSupportsExternalKeying,
&supportsExternalKeyer);
&supportsExternalKeyer);
attributes->GetFlag(BMDDeckLinkSupportsInternalKeying,
&supportsInternalKeyer);
&supportsInternalKeyer);
// Sub Device Counts
attributes->GetInt(BMDDeckLinkSubDeviceIndex, &subDeviceIndex);
@ -139,7 +141,8 @@ bool DeckLinkDevice::Init()
/* 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)
else if (attributes->GetInt(BMDDeckLinkMaximumAudioChannels,
&channels) == S_OK)
maxChannel = (int32_t)channels;
else
maxChannel = 2;
@ -149,7 +152,7 @@ bool DeckLinkDevice::Init()
* BMDDeckLinkPersistentID for newer ones */
int64_t value;
if (attributes->GetInt(BMDDeckLinkPersistentID, &value) != S_OK &&
if (attributes->GetInt(BMDDeckLinkPersistentID, &value) != S_OK &&
attributes->GetInt(BMDDeckLinkTopologicalID, &value) != S_OK)
return true;
@ -161,14 +164,15 @@ bool DeckLinkDevice::Init()
bool DeckLinkDevice::GetInput(IDeckLinkInput **input)
{
if (device->QueryInterface(IID_IDeckLinkInput, (void**)input) != S_OK)
if (device->QueryInterface(IID_IDeckLinkInput, (void **)input) != S_OK)
return false;
return true;
}
bool DeckLinkDevice::GetOutput(IDeckLinkOutput **output)
{
if (device->QueryInterface(IID_IDeckLinkOutput, (void**)output) != S_OK)
if (device->QueryInterface(IID_IDeckLinkOutput, (void **)output) !=
S_OK)
return false;
return true;
@ -176,9 +180,10 @@ bool DeckLinkDevice::GetOutput(IDeckLinkOutput **output)
bool DeckLinkDevice::GetKeyer(IDeckLinkKeyer **deckLinkKeyer)
{
if (device->QueryInterface(IID_IDeckLinkKeyer, (void**)deckLinkKeyer) != S_OK)
{
fprintf(stderr, "Could not obtain the IDeckLinkKeyer interface\n");
if (device->QueryInterface(IID_IDeckLinkKeyer,
(void **)deckLinkKeyer) != S_OK) {
fprintf(stderr,
"Could not obtain the IDeckLinkKeyer interface\n");
return false;
}
@ -205,22 +210,24 @@ DeckLinkDeviceMode *DeckLinkDevice::FindOutputMode(long long id)
return outputModeIdMap[id];
}
const std::string& DeckLinkDevice::GetDisplayName(void)
const std::string &DeckLinkDevice::GetDisplayName(void)
{
return displayName;
}
const std::string& DeckLinkDevice::GetHash(void) const
const std::string &DeckLinkDevice::GetHash(void) const
{
return hash;
}
const std::vector<DeckLinkDeviceMode *>& DeckLinkDevice::GetInputModes(void) const
const std::vector<DeckLinkDeviceMode *> &
DeckLinkDevice::GetInputModes(void) const
{
return inputModes;
}
const std::vector<DeckLinkDeviceMode *>& DeckLinkDevice::GetOutputModes(void) const
const std::vector<DeckLinkDeviceMode *> &
DeckLinkDevice::GetOutputModes(void) const
{
return outputModes;
}
@ -235,7 +242,6 @@ int64_t DeckLinkDevice::GetAudioInputConnections()
return supportedAudioInputConnections;
}
bool DeckLinkDevice::GetSupportsExternalKeyer(void) const
{
return supportsExternalKeyer;
@ -256,7 +262,7 @@ int64_t DeckLinkDevice::GetSubDeviceIndex()
return subDeviceIndex;
}
const std::string& DeckLinkDevice::GetName(void) const
const std::string &DeckLinkDevice::GetName(void) const
{
return name;
}

View file

@ -7,28 +7,26 @@
#include <vector>
#include <stdint.h>
class DeckLinkDevice {
ComPtr<IDeckLink> device;
ComPtr<IDeckLink> device;
std::map<long long, DeckLinkDeviceMode *> inputModeIdMap;
std::vector<DeckLinkDeviceMode *> inputModes;
std::vector<DeckLinkDeviceMode *> inputModes;
std::map<long long, DeckLinkDeviceMode *> outputModeIdMap;
std::vector<DeckLinkDeviceMode *> outputModes;
std::string name;
std::string displayName;
std::string hash;
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;
std::vector<DeckLinkDeviceMode *> outputModes;
std::string name;
std::string displayName;
std::string hash;
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;
public:
DeckLinkDevice(IDeckLink *device);
@ -41,10 +39,10 @@ public:
DeckLinkDeviceMode *FindInputMode(long long id);
DeckLinkDeviceMode *FindOutputMode(long long id);
const std::string& GetDisplayName(void);
const std::string& GetHash(void) const;
const std::vector<DeckLinkDeviceMode *>& GetInputModes(void) const;
const std::vector<DeckLinkDeviceMode *>& GetOutputModes(void) const;
const std::string &GetDisplayName(void);
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;
@ -53,15 +51,12 @@ public:
int64_t GetSubDeviceIndex();
int GetKeyerMode(void);
void SetKeyerMode(int newKeyerMode);
const std::string& GetName(void) const;
const std::string &GetName(void) const;
int32_t GetMaxChannel(void) const;
bool GetInput(IDeckLinkInput **input);
bool GetOutput(IDeckLinkOutput **output);
bool GetKeyer(IDeckLinkKeyer **keyer);
inline bool IsDevice(IDeckLink *device_)
{
return device_ == device;
}
inline bool IsDevice(IDeckLink *device_) { return device_ == device; }
};

View file

@ -6,11 +6,11 @@ void fill_out_devices(obs_property_t *list)
{
deviceEnum->Lock();
const std::vector<DeckLinkDevice*> &devices = deviceEnum->GetDevices();
const std::vector<DeckLinkDevice *> &devices = deviceEnum->GetDevices();
for (DeckLinkDevice *device : devices) {
obs_property_list_add_string(list,
device->GetDisplayName().c_str(),
device->GetHash().c_str());
device->GetDisplayName().c_str(),
device->GetHash().c_str());
}
deviceEnum->Unlock();

View file

@ -48,7 +48,8 @@ static bool decklink_output_start(void *data)
decklink->audio_samplerate = aoi.samples_per_sec;
decklink->audio_planes = 2;
decklink->audio_size = get_audio_size(AUDIO_FORMAT_16BIT, aoi.speakers, 1);
decklink->audio_size =
get_audio_size(AUDIO_FORMAT_16BIT, aoi.speakers, 1);
decklink->start_timestamp = 0;
@ -68,7 +69,7 @@ static bool decklink_output_start(void *data)
to.format = VIDEO_FORMAT_UYVY;
}
to.width = mode->GetWidth();
to.height = mode->GetHeight();
to.height = mode->GetHeight();
obs_output_set_video_conversion(decklink->GetOutput(), &to);
@ -78,7 +79,7 @@ static bool decklink_output_start(void *data)
struct audio_convert_info conversion = {};
conversion.format = AUDIO_FORMAT_16BIT;
conversion.speakers = SPEAKERS_STEREO;
conversion.samples_per_sec = 48000; // Only format the decklink supports
conversion.samples_per_sec = 48000; // Only format the decklink supports
obs_output_set_audio_conversion(decklink->GetOutput(), &conversion);
@ -112,14 +113,14 @@ static void decklink_output_raw_video(void *data, struct video_data *frame)
}
static bool prepare_audio(DeckLinkOutput *decklink,
const struct audio_data *frame,
struct audio_data *output)
const struct audio_data *frame,
struct audio_data *output)
{
*output = *frame;
if (frame->timestamp < decklink->start_timestamp) {
uint64_t duration = (uint64_t)frame->frames * 1000000000 /
(uint64_t)decklink->audio_samplerate;
(uint64_t)decklink->audio_samplerate;
uint64_t end_ts = frame->timestamp + duration;
uint64_t cutoff;
@ -132,8 +133,8 @@ static bool prepare_audio(DeckLinkOutput *decklink,
cutoff *= (uint64_t)decklink->audio_samplerate / 1000000000;
for (size_t i = 0; i < decklink->audio_planes; i++)
output->data[i] += decklink->audio_size *
(uint32_t)cutoff;
output->data[i] +=
decklink->audio_size * (uint32_t)cutoff;
output->frames -= (uint32_t)cutoff;
}
@ -156,7 +157,8 @@ static void decklink_output_raw_audio(void *data, struct audio_data *frames)
}
static bool decklink_output_device_changed(obs_properties_t *props,
obs_property_t *list, obs_data_t *settings)
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);
@ -193,13 +195,13 @@ static bool decklink_output_device_changed(obs_properties_t *props,
obs_property_list_item_disable(modeList, 0, true);
obs_property_list_item_disable(keyerList, 0, true);
} else {
const std::vector<DeckLinkDeviceMode*> &modes =
device->GetOutputModes();
const std::vector<DeckLinkDeviceMode *> &modes =
device->GetOutputModes();
for (DeckLinkDeviceMode *mode : modes) {
obs_property_list_add_int(modeList,
mode->GetName().c_str(),
mode->GetId());
mode->GetName().c_str(),
mode->GetId());
}
obs_property_list_add_int(keyerList, "Disabled", 0);
@ -222,22 +224,26 @@ static obs_properties_t *decklink_output_properties(void *unused)
obs_properties_t *props = obs_properties_create();
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_output_device_changed);
TEXT_DEVICE,
OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
obs_property_set_modified_callback(list,
decklink_output_device_changed);
fill_out_devices(list);
obs_properties_add_list(props,
MODE_ID, TEXT_MODE, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_properties_add_list(props, MODE_ID, TEXT_MODE, OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_properties_add_bool(props, AUTO_START, TEXT_AUTO_START);
obs_properties_add_list(props, KEYER, TEXT_ENABLE_KEYER, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_properties_add_list(props, KEYER, TEXT_ENABLE_KEYER,
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
return props;
}
static const char *decklink_output_get_name(void*)
static const char *decklink_output_get_name(void *)
{
return obs_module_text("BlackmagicDevice");
}
@ -246,17 +252,17 @@ struct obs_output_info create_decklink_output_info()
{
struct obs_output_info decklink_output_info = {};
decklink_output_info.id = "decklink_output";
decklink_output_info.flags = OBS_OUTPUT_AV;
decklink_output_info.get_name = decklink_output_get_name;
decklink_output_info.create = decklink_output_create;
decklink_output_info.destroy = decklink_output_destroy;
decklink_output_info.start = decklink_output_start;
decklink_output_info.stop = decklink_output_stop;
decklink_output_info.id = "decklink_output";
decklink_output_info.flags = OBS_OUTPUT_AV;
decklink_output_info.get_name = decklink_output_get_name;
decklink_output_info.create = decklink_output_create;
decklink_output_info.destroy = decklink_output_destroy;
decklink_output_info.start = decklink_output_start;
decklink_output_info.stop = decklink_output_stop;
decklink_output_info.get_properties = decklink_output_properties;
decklink_output_info.raw_video = decklink_output_raw_video;
decklink_output_info.raw_audio = decklink_output_raw_audio;
decklink_output_info.update = decklink_output_update;
decklink_output_info.raw_video = decklink_output_raw_video;
decklink_output_info.raw_audio = decklink_output_raw_audio;
decklink_output_info.update = decklink_output_update;
return decklink_output_info;
}

View file

@ -15,7 +15,8 @@ static void decklink_enable_buffering(DeckLinkInput *decklink, bool enabled)
decklink->buffering = enabled;
}
static void decklink_deactivate_when_not_showing(DeckLinkInput *decklink, bool dwns)
static void decklink_deactivate_when_not_showing(DeckLinkInput *decklink,
bool dwns)
{
decklink->dwns = dwns;
}
@ -26,7 +27,7 @@ static void *decklink_create(obs_data_t *settings, obs_source_t *source)
obs_source_set_async_decoupled(source, true);
decklink_enable_buffering(decklink,
obs_data_get_bool(settings, BUFFERING));
obs_data_get_bool(settings, BUFFERING));
obs_source_update(source, settings);
return decklink;
@ -43,16 +44,18 @@ 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,
COLOR_SPACE);
video_range_type colorRange = (video_range_type)obs_data_get_int(settings,
COLOR_RANGE);
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, COLOR_SPACE);
video_range_type colorRange =
(video_range_type)obs_data_get_int(settings, COLOR_RANGE);
int chFmtInt = (int)obs_data_get_int(settings, CHANNEL_FORMAT);
if (chFmtInt == 7)
@ -63,10 +66,10 @@ static void decklink_update(void *data, obs_data_t *settings)
speaker_layout channelFormat = (speaker_layout)chFmtInt;
decklink_enable_buffering(decklink,
obs_data_get_bool(settings, BUFFERING));
obs_data_get_bool(settings, BUFFERING));
decklink_deactivate_when_not_showing(decklink,
obs_data_get_bool(settings, DEACTIVATE_WNS));
decklink_deactivate_when_not_showing(
decklink, obs_data_get_bool(settings, DEACTIVATE_WNS));
ComPtr<DeckLinkDevice> device;
device.Set(deviceEnum->FindByHash(hash));
@ -88,8 +91,9 @@ 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->videoConnection,
decklink->audioConnection);
decklink->Activate(device, decklink->id,
decklink->videoConnection,
decklink->audioConnection);
}
}
static void decklink_hide(void *data)
@ -111,13 +115,13 @@ static void decklink_get_defaults(obs_data_t *settings)
obs_data_set_default_bool(settings, SWAP, false);
}
static const char *decklink_get_name(void*)
static const char *decklink_get_name(void *)
{
return obs_module_text("BlackmagicDevice");
}
static bool decklink_device_changed(obs_properties_t *props,
obs_property_t *list, obs_data_t *settings)
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);
@ -140,10 +144,10 @@ 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 *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);
@ -154,9 +158,9 @@ static bool decklink_device_changed(obs_properties_t *props,
obs_property_list_clear(channelList);
obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_NONE,
SPEAKERS_UNKNOWN);
SPEAKERS_UNKNOWN);
obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_2_0CH,
SPEAKERS_STEREO);
SPEAKERS_STEREO);
ComPtr<DeckLinkDevice> device;
device.Set(deviceEnum->FindByHash(hash));
@ -168,60 +172,75 @@ static bool decklink_device_changed(obs_properties_t *props,
obs_property_list_item_disable(modeList, 0, true);
} else {
const BMDVideoConnection BMDVideoConnections[] = {
bmdVideoConnectionSDI, bmdVideoConnectionHDMI,
bmdVideoConnectionOpticalSDI, bmdVideoConnectionComponent,
bmdVideoConnectionComposite, bmdVideoConnectionSVideo
};
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);
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
};
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);
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();
const std::vector<DeckLinkDeviceMode *> &modes =
device->GetInputModes();
for (DeckLinkDeviceMode *mode : modes) {
obs_property_list_add_int(modeList,
mode->GetName().c_str(),
mode->GetId());
mode->GetName().c_str(),
mode->GetId());
}
if (device->GetMaxChannel() >= 8) {
obs_property_list_add_int(channelList,
TEXT_CHANNEL_FORMAT_2_1CH, SPEAKERS_2POINT1);
TEXT_CHANNEL_FORMAT_2_1CH,
SPEAKERS_2POINT1);
obs_property_list_add_int(channelList,
TEXT_CHANNEL_FORMAT_4_0CH, SPEAKERS_4POINT0);
TEXT_CHANNEL_FORMAT_4_0CH,
SPEAKERS_4POINT0);
obs_property_list_add_int(channelList,
TEXT_CHANNEL_FORMAT_4_1CH, SPEAKERS_4POINT1);
TEXT_CHANNEL_FORMAT_4_1CH,
SPEAKERS_4POINT1);
obs_property_list_add_int(channelList,
TEXT_CHANNEL_FORMAT_5_1CH, SPEAKERS_5POINT1);
TEXT_CHANNEL_FORMAT_5_1CH,
SPEAKERS_5POINT1);
obs_property_list_add_int(channelList,
TEXT_CHANNEL_FORMAT_7_1CH, SPEAKERS_7POINT1);
TEXT_CHANNEL_FORMAT_7_1CH,
SPEAKERS_7POINT1);
}
}
return true;
}
static bool mode_id_changed(obs_properties_t *props,
obs_property_t *list, obs_data_t *settings)
static bool mode_id_changed(obs_properties_t *props, obs_property_t *list,
obs_data_t *settings)
{
long long id = obs_data_get_int(settings, MODE_ID);
@ -236,56 +255,65 @@ 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,
TEXT_DEVICE, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
TEXT_DEVICE,
OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
obs_property_set_modified_callback(list, decklink_device_changed);
fill_out_devices(list);
obs_properties_add_list(props, VIDEO_CONNECTION, TEXT_VIDEO_CONNECTION,
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
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);
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_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_modified_callback(list, mode_id_changed);
list = obs_properties_add_list(props, PIXEL_FORMAT,
TEXT_PIXEL_FORMAT, OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
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);
list = obs_properties_add_list(props, COLOR_SPACE, TEXT_COLOR_SPACE,
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_list_add_int(list, TEXT_COLOR_SPACE_DEFAULT, VIDEO_CS_DEFAULT);
OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_list_add_int(list, TEXT_COLOR_SPACE_DEFAULT,
VIDEO_CS_DEFAULT);
obs_property_list_add_int(list, "BT.601", VIDEO_CS_601);
obs_property_list_add_int(list, "BT.709", VIDEO_CS_709);
list = obs_properties_add_list(props, COLOR_RANGE, TEXT_COLOR_RANGE,
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_list_add_int(list, TEXT_COLOR_RANGE_DEFAULT, VIDEO_RANGE_DEFAULT);
obs_property_list_add_int(list, TEXT_COLOR_RANGE_PARTIAL, VIDEO_RANGE_PARTIAL);
obs_property_list_add_int(list, TEXT_COLOR_RANGE_FULL, VIDEO_RANGE_FULL);
OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_list_add_int(list, TEXT_COLOR_RANGE_DEFAULT,
VIDEO_RANGE_DEFAULT);
obs_property_list_add_int(list, TEXT_COLOR_RANGE_PARTIAL,
VIDEO_RANGE_PARTIAL);
obs_property_list_add_int(list, TEXT_COLOR_RANGE_FULL,
VIDEO_RANGE_FULL);
list = obs_properties_add_list(props, CHANNEL_FORMAT,
TEXT_CHANNEL_FORMAT, OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
TEXT_CHANNEL_FORMAT, OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_NONE,
SPEAKERS_UNKNOWN);
SPEAKERS_UNKNOWN);
obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_2_0CH,
SPEAKERS_STEREO);
SPEAKERS_STEREO);
obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_2_1CH,
SPEAKERS_2POINT1);
SPEAKERS_2POINT1);
obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_4_0CH,
SPEAKERS_4POINT0);
SPEAKERS_4POINT0);
obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_4_1CH,
SPEAKERS_4POINT1);
SPEAKERS_4POINT1);
obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_5_1CH,
SPEAKERS_5POINT1);
SPEAKERS_5POINT1);
obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_7_1CH,
SPEAKERS_7POINT1);
SPEAKERS_7POINT1);
obs_property_t *swap = obs_properties_add_bool(props, SWAP, TEXT_SWAP);
obs_property_set_long_description(swap, TEXT_SWAP_TOOLTIP);
@ -298,21 +326,22 @@ static obs_properties_t *decklink_get_properties(void *data)
return props;
}
struct obs_source_info create_decklink_source_info()
{
struct obs_source_info decklink_source_info = {};
decklink_source_info.id = "decklink-input";
decklink_source_info.type = OBS_SOURCE_TYPE_INPUT;
decklink_source_info.output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO | OBS_SOURCE_DO_NOT_DUPLICATE;
decklink_source_info.create = decklink_create;
decklink_source_info.destroy = decklink_destroy;
decklink_source_info.get_defaults = decklink_get_defaults;
decklink_source_info.get_name = decklink_get_name;
decklink_source_info.id = "decklink-input";
decklink_source_info.type = OBS_SOURCE_TYPE_INPUT;
decklink_source_info.output_flags = OBS_SOURCE_ASYNC_VIDEO |
OBS_SOURCE_AUDIO |
OBS_SOURCE_DO_NOT_DUPLICATE;
decklink_source_info.create = decklink_create;
decklink_source_info.destroy = decklink_destroy;
decklink_source_info.get_defaults = decklink_get_defaults;
decklink_source_info.get_name = decklink_get_name;
decklink_source_info.get_properties = decklink_get_properties;
decklink_source_info.update = decklink_update;
decklink_source_info.show = decklink_show;
decklink_source_info.hide = decklink_hide;
decklink_source_info.update = decklink_update;
decklink_source_info.show = decklink_show;
decklink_source_info.hide = decklink_hide;
return decklink_source_info;
}

View file

@ -0,0 +1,3 @@
Language: Cpp
SortIncludes: false
DisableFormat: true

View file

@ -1,6 +1,6 @@
#include "../platform.hpp"
bool DeckLinkStringToStdString(decklink_string_t input, std::string& output)
bool DeckLinkStringToStdString(decklink_string_t input, std::string &output)
{
if (input == nullptr)
return false;

View file

@ -0,0 +1,3 @@
Language: Cpp
SortIncludes: false
DisableFormat: true

View file

@ -1,7 +1,7 @@
#include "../platform.hpp"
#include <util/apple/cfstring-utils.h>
bool DeckLinkStringToStdString(decklink_string_t input, std::string& output)
bool DeckLinkStringToStdString(decklink_string_t input, std::string &output)
{
const CFStringRef string = static_cast<CFStringRef>(input);

View file

@ -24,4 +24,4 @@ typedef const char *decklink_string_t;
#include <string>
bool DeckLinkStringToStdString(decklink_string_t input, std::string& output);
bool DeckLinkStringToStdString(decklink_string_t input, std::string &output);

View file

@ -3,41 +3,41 @@
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";
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";
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";
}
}

View file

@ -5,13 +5,13 @@
IDeckLinkDiscovery *CreateDeckLinkDiscoveryInstance(void)
{
IDeckLinkDiscovery *instance;
const HRESULT result = CoCreateInstance(CLSID_CDeckLinkDiscovery,
nullptr, CLSCTX_ALL, IID_IDeckLinkDiscovery,
(void **)&instance);
const HRESULT result =
CoCreateInstance(CLSID_CDeckLinkDiscovery, nullptr, CLSCTX_ALL,
IID_IDeckLinkDiscovery, (void **)&instance);
return result == S_OK ? instance : nullptr;
}
bool DeckLinkStringToStdString(decklink_string_t input, std::string& output)
bool DeckLinkStringToStdString(decklink_string_t input, std::string &output)
{
if (input == nullptr)
return false;