f53df7da64
Code submissions have continually suffered from formatting inconsistencies that constantly have to be addressed. Using clang-format simplifies this by making code formatting more consistent, and allows automation of the code formatting so that maintainers can focus more on the code itself instead of code formatting.
155 lines
4.0 KiB
C++
155 lines
4.0 KiB
C++
#include "DecklinkInput.hpp"
|
|
|
|
#include <util/threading.h>
|
|
|
|
DeckLinkInput::DeckLinkInput(obs_source_t *source,
|
|
DeckLinkDeviceDiscovery *discovery_)
|
|
: DecklinkBase(discovery_), source(source)
|
|
{
|
|
discovery->AddCallback(DeckLinkInput::DevicesChanged, this);
|
|
}
|
|
|
|
DeckLinkInput::~DeckLinkInput(void)
|
|
{
|
|
discovery->RemoveCallback(DeckLinkInput::DevicesChanged, this);
|
|
Deactivate();
|
|
}
|
|
|
|
void DeckLinkInput::DevicesChanged(void *param, DeckLinkDevice *device,
|
|
bool added)
|
|
{
|
|
DeckLinkInput *decklink = reinterpret_cast<DeckLinkInput *>(param);
|
|
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;
|
|
BMDVideoConnection videoConnection;
|
|
BMDAudioConnection audioConnection;
|
|
|
|
settings = obs_source_get_settings(decklink->source);
|
|
hash = obs_data_get_string(settings, "device_hash");
|
|
videoConnection = (BMDVideoConnection)obs_data_get_int(
|
|
settings, "video_connection");
|
|
audioConnection = (BMDAudioConnection)obs_data_get_int(
|
|
settings, "audio_connection");
|
|
mode = obs_data_get_int(settings, "mode_id");
|
|
obs_data_release(settings);
|
|
|
|
if (device->GetHash().compare(hash) == 0) {
|
|
if (!decklink->activateRefs)
|
|
return;
|
|
if (decklink->Activate(device, mode, videoConnection,
|
|
audioConnection))
|
|
os_atomic_dec_long(&decklink->activateRefs);
|
|
}
|
|
|
|
} else if (!added && decklink->instance) {
|
|
if (decklink->instance->GetDevice() == device) {
|
|
os_atomic_inc_long(&decklink->activateRefs);
|
|
decklink->Deactivate();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool DeckLinkInput::Activate(DeckLinkDevice *device, long long modeId,
|
|
BMDVideoConnection bmdVideoConnection,
|
|
BMDAudioConnection bmdAudioConnection)
|
|
{
|
|
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 &&
|
|
instance->GetVideoConnection() == bmdVideoConnection &&
|
|
instance->GetAudioConnection() == bmdAudioConnection &&
|
|
instance->GetActivePixelFormat() == pixelFormat &&
|
|
instance->GetActiveColorSpace() == colorSpace &&
|
|
instance->GetActiveColorRange() == colorRange &&
|
|
instance->GetActiveChannelFormat() == channelFormat &&
|
|
instance->GetActiveSwapState() == swap)
|
|
return false;
|
|
}
|
|
|
|
if (isActive)
|
|
instance->StopCapture();
|
|
|
|
isCapturing = false;
|
|
if (!same)
|
|
instance.Set(new DeckLinkDeviceInstance(this, device));
|
|
|
|
if (instance == nullptr)
|
|
return false;
|
|
|
|
if (GetDevice() == nullptr) {
|
|
LOG(LOG_ERROR,
|
|
"Tried to activate an input with nullptr device.");
|
|
return false;
|
|
}
|
|
|
|
DeckLinkDeviceMode *mode = GetDevice()->FindInputMode(modeId);
|
|
if (mode == nullptr) {
|
|
instance = nullptr;
|
|
return false;
|
|
}
|
|
|
|
if (!instance->StartCapture(mode, bmdVideoConnection,
|
|
bmdAudioConnection)) {
|
|
instance = nullptr;
|
|
return false;
|
|
}
|
|
|
|
os_atomic_inc_long(&activateRefs);
|
|
SaveSettings();
|
|
id = modeId;
|
|
isCapturing = true;
|
|
return true;
|
|
}
|
|
|
|
void DeckLinkInput::Deactivate(void)
|
|
{
|
|
std::lock_guard<std::recursive_mutex> lock(deviceMutex);
|
|
if (instance)
|
|
instance->StopCapture();
|
|
isCapturing = false;
|
|
instance = nullptr;
|
|
|
|
os_atomic_dec_long(&activateRefs);
|
|
}
|
|
|
|
bool DeckLinkInput::Capturing(void)
|
|
{
|
|
return isCapturing;
|
|
}
|
|
|
|
void DeckLinkInput::SaveSettings()
|
|
{
|
|
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);
|
|
}
|
|
|
|
obs_source_t *DeckLinkInput::GetSource(void) const
|
|
{
|
|
return source;
|
|
}
|