obs-studio/plugins/decklink/plugin-main.cpp
jp9000 6285a47726 (API Change) libobs: Pass type data to get_name callbacks
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.
2015-09-16 09:21:12 -07:00

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;
}