API changed from: obs_source_info::get_name(void) obs_output_info::get_name(void) obs_encoder_info::get_name(void) obs_service_info::get_name(void) API changed to: obs_source_info::get_name(void *type_data) obs_output_info::get_name(void *type_data) obs_encoder_info::get_name(void *type_data) obs_service_info::get_name(void *type_data) This allows the type data to be used when getting the name of the object (useful for plugin wrappers primarily). NOTE: Though a parameter was added, this is backward-compatible with older plugins due to calling convention. The new parameter will simply be ignored by older plugins, and the stack (if used) will be cleaned up by the caller.
175 lines
4.3 KiB
C++
175 lines
4.3 KiB
C++
#include "decklink.hpp"
|
|
#include "decklink-device.hpp"
|
|
#include "decklink-device-discovery.hpp"
|
|
|
|
#include <obs-module.h>
|
|
|
|
OBS_DECLARE_MODULE()
|
|
OBS_MODULE_USE_DEFAULT_LOCALE("decklink", "en-US")
|
|
|
|
static DeckLinkDeviceDiscovery *deviceEnum = nullptr;
|
|
|
|
static void decklink_enable_buffering(DeckLink *decklink, bool enabled)
|
|
{
|
|
obs_source_t *source = decklink->GetSource();
|
|
uint32_t flags = obs_source_get_flags(source);
|
|
if (enabled)
|
|
flags &= ~OBS_SOURCE_FLAG_UNBUFFERED;
|
|
else
|
|
flags |= OBS_SOURCE_FLAG_UNBUFFERED;
|
|
obs_source_set_flags(source, flags);
|
|
}
|
|
|
|
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_source_update(source, settings);
|
|
return decklink;
|
|
}
|
|
|
|
static void decklink_destroy(void *data)
|
|
{
|
|
DeckLink *decklink = (DeckLink *)data;
|
|
delete decklink;
|
|
}
|
|
|
|
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");
|
|
|
|
decklink_enable_buffering(decklink,
|
|
obs_data_get_bool(settings, "buffering"));
|
|
|
|
ComPtr<DeckLinkDevice> device;
|
|
device.Set(deviceEnum->FindByHash(hash));
|
|
|
|
decklink->Activate(device, id);
|
|
}
|
|
|
|
static void decklink_get_defaults(obs_data_t *settings)
|
|
{
|
|
obs_data_set_default_bool(settings, "buffering", true);
|
|
}
|
|
|
|
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)
|
|
{
|
|
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;
|
|
|
|
for (size_t i = 0; i < itemCount; i++) {
|
|
const char *curHash = obs_property_list_item_string(list, i);
|
|
if (strcmp(hash, curHash) == 0) {
|
|
itemFound = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!itemFound) {
|
|
obs_property_list_insert_string(list, 0, name, hash);
|
|
obs_property_list_item_disable(list, 0, true);
|
|
}
|
|
|
|
list = obs_properties_get(props, "mode_id");
|
|
|
|
obs_property_list_clear(list);
|
|
|
|
ComPtr<DeckLinkDevice> device;
|
|
device.Set(deviceEnum->FindByHash(hash));
|
|
|
|
if (!device) {
|
|
obs_property_list_add_int(list, mode, modeId);
|
|
obs_property_list_item_disable(list, 0, true);
|
|
} else {
|
|
const std::vector<DeckLinkDeviceMode*> &modes =
|
|
device->GetModes();
|
|
|
|
for (DeckLinkDeviceMode *mode : modes) {
|
|
obs_property_list_add_int(list,
|
|
mode->GetName().c_str(),
|
|
mode->GetId());
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static void fill_out_devices(obs_property_t *list)
|
|
{
|
|
deviceEnum->Lock();
|
|
|
|
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());
|
|
}
|
|
|
|
deviceEnum->Unlock();
|
|
}
|
|
|
|
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_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);
|
|
|
|
obs_properties_add_bool(props, "buffering",
|
|
obs_module_text("Buffering"));
|
|
|
|
UNUSED_PARAMETER(data);
|
|
return props;
|
|
}
|
|
|
|
bool obs_module_load(void)
|
|
{
|
|
deviceEnum = new DeckLinkDeviceDiscovery();
|
|
if (!deviceEnum->Init())
|
|
return true;
|
|
|
|
struct obs_source_info info = {};
|
|
info.id = "decklink-input";
|
|
info.type = OBS_SOURCE_TYPE_INPUT;
|
|
info.output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO;
|
|
info.create = decklink_create;
|
|
info.destroy = decklink_destroy;
|
|
info.get_defaults = decklink_get_defaults;
|
|
info.get_name = decklink_get_name;
|
|
info.get_properties = decklink_get_properties;
|
|
info.update = decklink_update;
|
|
|
|
obs_register_source(&info);
|
|
|
|
return true;
|
|
}
|
|
|
|
void obs_module_unload(void)
|
|
{
|
|
delete deviceEnum;
|
|
}
|