yolobs-studio/plugins/decklink/DecklinkInput.cpp

150 lines
3.9 KiB
C++
Raw Normal View History

2019-07-27 12:47:10 +00:00
#include "DecklinkInput.hpp"
2016-02-23 23:16:51 +00:00
#include <util/threading.h>
2019-07-27 12:47:10 +00:00
DeckLinkInput::DeckLinkInput(obs_source_t *source, DeckLinkDeviceDiscovery *discovery_)
: DecklinkBase(discovery_),
source(source)
2016-02-23 23:16:51 +00:00
{
2019-07-27 12:47:10 +00:00
discovery->AddCallback(DeckLinkInput::DevicesChanged, this);
2016-02-23 23:16:51 +00:00
}
2019-07-27 12:47:10 +00:00
DeckLinkInput::~DeckLinkInput(void)
2016-02-23 23:16:51 +00:00
{
2019-07-27 12:47:10 +00:00
discovery->RemoveCallback(DeckLinkInput::DevicesChanged, this);
2016-02-23 23:16:51 +00:00
Deactivate();
}
2019-07-27 12:47:10 +00:00
void DeckLinkInput::DevicesChanged(void *param, DeckLinkDevice *device, bool added)
2016-02-23 23:16:51 +00:00
{
2019-07-27 12:47:10 +00:00
DeckLinkInput *decklink = reinterpret_cast<DeckLinkInput*>(param);
2016-02-23 23:16:51 +00:00
std::lock_guard<std::recursive_mutex> lock(decklink->deviceMutex);
obs_source_update_properties(decklink->source);
if (added && !decklink->instance) {
const char *hash;
long long mode;
obs_data_t *settings;
2019-07-27 12:47:10 +00:00
BMDVideoConnection videoConnection;
BMDAudioConnection audioConnection;
2016-02-23 23:16:51 +00:00
settings = obs_source_get_settings(decklink->source);
hash = obs_data_get_string(settings, "device_hash");
2019-07-27 12:47:10 +00:00
videoConnection = (BMDVideoConnection) obs_data_get_int(settings, "video_connection");
audioConnection = (BMDAudioConnection) obs_data_get_int(settings, "audio_connection");
2016-02-23 23:16:51 +00:00
mode = obs_data_get_int(settings, "mode_id");
obs_data_release(settings);
if (device->GetHash().compare(hash) == 0) {
if (!decklink->activateRefs)
return;
2019-07-27 12:47:10 +00:00
if (decklink->Activate(device, mode, videoConnection, audioConnection))
2016-02-23 23:16:51 +00:00
os_atomic_dec_long(&decklink->activateRefs);
}
} else if (!added && decklink->instance) {
if (decklink->instance->GetDevice() == device) {
os_atomic_inc_long(&decklink->activateRefs);
decklink->Deactivate();
}
}
}
2019-07-27 12:47:10 +00:00
bool DeckLinkInput::Activate(DeckLinkDevice *device, long long modeId,
BMDVideoConnection bmdVideoConnection,
BMDAudioConnection bmdAudioConnection)
2016-02-23 23:16:51 +00:00
{
std::lock_guard<std::recursive_mutex> lock(deviceMutex);
DeckLinkDevice *curDevice = GetDevice();
const bool same = device == curDevice;
const bool isActive = instance != nullptr;
if (same) {
if (!isActive)
return false;
if (instance->GetActiveModeId() == modeId &&
2019-07-27 12:47:10 +00:00
instance->GetVideoConnection() == bmdVideoConnection &&
instance->GetAudioConnection() == bmdAudioConnection &&
2017-06-29 19:01:10 +00:00
instance->GetActivePixelFormat() == pixelFormat &&
2018-02-19 19:54:37 +00:00
instance->GetActiveColorSpace() == colorSpace &&
instance->GetActiveColorRange() == colorRange &&
2019-07-27 12:47:10 +00:00
instance->GetActiveChannelFormat() == channelFormat &&
instance->GetActiveSwapState() == swap)
2016-02-23 23:16:51 +00:00
return false;
}
if (isActive)
instance->StopCapture();
2019-07-27 12:47:10 +00:00
isCapturing = false;
2016-02-23 23:16:51 +00:00
if (!same)
instance.Set(new DeckLinkDeviceInstance(this, device));
if (instance == nullptr)
return false;
2019-07-27 12:47:10 +00:00
if (GetDevice() == nullptr) {
LOG(LOG_ERROR, "Tried to activate an input with nullptr device.");
return false;
}
DeckLinkDeviceMode *mode = GetDevice()->FindInputMode(modeId);
2016-02-23 23:16:51 +00:00
if (mode == nullptr) {
instance = nullptr;
return false;
}
2019-07-27 12:47:10 +00:00
if (!instance->StartCapture(mode, bmdVideoConnection, bmdAudioConnection)) {
2016-02-23 23:16:51 +00:00
instance = nullptr;
return false;
}
os_atomic_inc_long(&activateRefs);
SaveSettings();
2019-07-27 12:47:10 +00:00
id = modeId;
isCapturing = true;
2016-02-23 23:16:51 +00:00
return true;
}
2019-07-27 12:47:10 +00:00
void DeckLinkInput::Deactivate(void)
2016-02-23 23:16:51 +00:00
{
std::lock_guard<std::recursive_mutex> lock(deviceMutex);
if (instance)
instance->StopCapture();
2019-07-27 12:47:10 +00:00
isCapturing = false;
2016-02-23 23:16:51 +00:00
instance = nullptr;
os_atomic_dec_long(&activateRefs);
}
2019-07-27 12:47:10 +00:00
bool DeckLinkInput::Capturing(void)
{
return isCapturing;
}
void DeckLinkInput::SaveSettings()
2016-02-23 23:16:51 +00:00
{
if (!instance)
return;
DeckLinkDevice *device = instance->GetDevice();
DeckLinkDeviceMode *mode = instance->GetMode();
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_name",
device->GetDisplayName().c_str());
obs_data_set_int(settings, "mode_id", instance->GetActiveModeId());
obs_data_set_string(settings, "mode_name", mode->GetName().c_str());
obs_data_release(settings);
}
2019-07-27 12:47:10 +00:00
obs_source_t *DeckLinkInput::GetSource(void) const
2016-02-23 23:16:51 +00:00
{
return source;
}