mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-04 09:42:19 +00:00
decklink: don't limit number of devices to 16
There is no fixed limitation for the number of devices on the decklink API side according to BlackMagic. Many PC motherboards are able support 6 decklink cards each with up to 8 inputs so a limit of 16 might well be too low. https://bugzilla.gnome.org/show_bug.cgi?id=777239
This commit is contained in:
parent
c7e34a0b2f
commit
9bb905620c
1 changed files with 48 additions and 44 deletions
|
@ -30,8 +30,6 @@
|
||||||
#include "gstdecklinkaudiosrc.h"
|
#include "gstdecklinkaudiosrc.h"
|
||||||
#include "gstdecklinkvideosrc.h"
|
#include "gstdecklinkvideosrc.h"
|
||||||
|
|
||||||
#define GST_DECKLINK_MAX_DEVICES 16
|
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_decklink_debug);
|
GST_DEBUG_CATEGORY_STATIC (gst_decklink_debug);
|
||||||
#define GST_CAT_DEFAULT gst_decklink_debug
|
#define GST_CAT_DEFAULT gst_decklink_debug
|
||||||
|
|
||||||
|
@ -1119,8 +1117,7 @@ gst_decklink_com_thread (gpointer data)
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
static GOnce devices_once = G_ONCE_INIT;
|
static GOnce devices_once = G_ONCE_INIT;
|
||||||
static int n_devices;
|
static GArray *devices; /* array of Device */
|
||||||
static Device devices[GST_DECKLINK_MAX_DEVICES];
|
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
init_devices (gpointer data)
|
init_devices (gpointer data)
|
||||||
|
@ -1149,29 +1146,32 @@ init_devices (gpointer data)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
devices = g_array_new (FALSE, TRUE, sizeof (Device));
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
ret = iterator->Next (&decklink);
|
ret = iterator->Next (&decklink);
|
||||||
while (ret == S_OK) {
|
while (ret == S_OK) {
|
||||||
g_mutex_init (&devices[i].input.lock);
|
Device dev;
|
||||||
g_mutex_init (&devices[i].output.lock);
|
|
||||||
g_cond_init (&devices[i].output.cond);
|
memset (&dev, 0, sizeof (Device));
|
||||||
|
|
||||||
|
g_mutex_init (&dev.input.lock);
|
||||||
|
g_mutex_init (&dev.output.lock);
|
||||||
|
g_cond_init (&dev.output.cond);
|
||||||
|
|
||||||
ret = decklink->QueryInterface (IID_IDeckLinkInput,
|
ret = decklink->QueryInterface (IID_IDeckLinkInput,
|
||||||
(void **) &devices[i].input.input);
|
(void **) &dev.input.input);
|
||||||
if (ret != S_OK) {
|
if (ret != S_OK) {
|
||||||
GST_WARNING ("selected device does not have input interface: 0x%08lx",
|
GST_WARNING ("selected device does not have input interface: 0x%08lx",
|
||||||
(unsigned long) ret);
|
(unsigned long) ret);
|
||||||
} else {
|
} else {
|
||||||
IDeckLinkDisplayModeIterator *mode_iter;
|
IDeckLinkDisplayModeIterator *mode_iter;
|
||||||
|
|
||||||
devices[i].input.device = decklink;
|
dev.input.device = decklink;
|
||||||
devices[i].input.
|
dev.input.
|
||||||
input->SetCallback (new GStreamerDecklinkInputCallback (&devices[i].
|
input->SetCallback (new GStreamerDecklinkInputCallback (&dev.input));
|
||||||
input));
|
|
||||||
|
|
||||||
if ((ret =
|
if ((ret = dev.input.input->GetDisplayModeIterator (&mode_iter)) == S_OK) {
|
||||||
devices[i].input.input->GetDisplayModeIterator (&mode_iter)) ==
|
|
||||||
S_OK) {
|
|
||||||
IDeckLinkDisplayMode *mode;
|
IDeckLinkDisplayMode *mode;
|
||||||
|
|
||||||
GST_DEBUG ("Input %d supports:", i);
|
GST_DEBUG ("Input %d supports:", i);
|
||||||
|
@ -1194,22 +1194,20 @@ init_devices (gpointer data)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = decklink->QueryInterface (IID_IDeckLinkOutput,
|
ret = decklink->QueryInterface (IID_IDeckLinkOutput,
|
||||||
(void **) &devices[i].output.output);
|
(void **) &dev.output.output);
|
||||||
if (ret != S_OK) {
|
if (ret != S_OK) {
|
||||||
GST_WARNING ("selected device does not have output interface: 0x%08lx",
|
GST_WARNING ("selected device does not have output interface: 0x%08lx",
|
||||||
(unsigned long) ret);
|
(unsigned long) ret);
|
||||||
} else {
|
} else {
|
||||||
IDeckLinkDisplayModeIterator *mode_iter;
|
IDeckLinkDisplayModeIterator *mode_iter;
|
||||||
|
|
||||||
devices[i].output.device = decklink;
|
dev.output.device = decklink;
|
||||||
devices[i].output.clock =
|
dev.output.clock =
|
||||||
gst_decklink_clock_new ("GstDecklinkOutputClock");
|
gst_decklink_clock_new ("GstDecklinkOutputClock");
|
||||||
GST_DECKLINK_CLOCK_CAST (devices[i].output.clock)->output =
|
GST_DECKLINK_CLOCK_CAST (dev.output.clock)->output =
|
||||||
&devices[i].output;
|
&dev.output;
|
||||||
|
|
||||||
if ((ret =
|
if ((ret = dev.output.output->GetDisplayModeIterator (&mode_iter)) == S_OK) {
|
||||||
devices[i].output.output->GetDisplayModeIterator (&mode_iter)) ==
|
|
||||||
S_OK) {
|
|
||||||
IDeckLinkDisplayMode *mode;
|
IDeckLinkDisplayMode *mode;
|
||||||
|
|
||||||
GST_DEBUG ("Output %d supports:", i);
|
GST_DEBUG ("Output %d supports:", i);
|
||||||
|
@ -1232,7 +1230,7 @@ init_devices (gpointer data)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = decklink->QueryInterface (IID_IDeckLinkConfiguration,
|
ret = decklink->QueryInterface (IID_IDeckLinkConfiguration,
|
||||||
(void **) &devices[i].input.config);
|
(void **) &dev.input.config);
|
||||||
if (ret != S_OK) {
|
if (ret != S_OK) {
|
||||||
GST_WARNING ("selected device does not have config interface: 0x%08lx",
|
GST_WARNING ("selected device does not have config interface: 0x%08lx",
|
||||||
(unsigned long) ret);
|
(unsigned long) ret);
|
||||||
|
@ -1240,28 +1238,30 @@ init_devices (gpointer data)
|
||||||
char *serial_number;
|
char *serial_number;
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
devices[i].input.
|
dev.input.
|
||||||
config->GetString (bmdDeckLinkConfigDeviceInformationSerialNumber,
|
config->GetString (bmdDeckLinkConfigDeviceInformationSerialNumber,
|
||||||
(COMSTR_T *) & serial_number);
|
(COMSTR_T *) & serial_number);
|
||||||
if (ret == S_OK) {
|
if (ret == S_OK) {
|
||||||
CONVERT_COM_STRING (serial_number);
|
CONVERT_COM_STRING (serial_number);
|
||||||
devices[i].output.hw_serial_number = g_strdup (serial_number);
|
dev.output.hw_serial_number = g_strdup (serial_number);
|
||||||
devices[i].input.hw_serial_number = g_strdup (serial_number);
|
dev.input.hw_serial_number = g_strdup (serial_number);
|
||||||
GST_DEBUG ("device %d has serial number %s", i, serial_number);
|
GST_DEBUG ("device %d has serial number %s", i, serial_number);
|
||||||
FREE_COM_STRING (serial_number);
|
FREE_COM_STRING (serial_number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = decklink->QueryInterface (IID_IDeckLinkAttributes,
|
ret = decklink->QueryInterface (IID_IDeckLinkAttributes,
|
||||||
(void **) &devices[i].input.attributes);
|
(void **) &dev.input.attributes);
|
||||||
devices[i].output.attributes = devices[i].input.attributes;
|
dev.output.attributes = dev.input.attributes;
|
||||||
if (ret != S_OK) {
|
if (ret != S_OK) {
|
||||||
GST_WARNING ("selected device does not have attributes interface: "
|
GST_WARNING ("selected device does not have attributes interface: "
|
||||||
"0x%08lx", (unsigned long) ret);
|
"0x%08lx", (unsigned long) ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = decklink->QueryInterface (IID_IDeckLinkKeyer,
|
ret = decklink->QueryInterface (IID_IDeckLinkKeyer,
|
||||||
(void **) &devices[i].output.keyer);
|
(void **) &dev.output.keyer);
|
||||||
|
|
||||||
|
g_array_append_val (devices, dev);
|
||||||
|
|
||||||
/* We only warn of failure to obtain the keyer interface if the keyer
|
/* We only warn of failure to obtain the keyer interface if the keyer
|
||||||
* is enabled by keyer_mode
|
* is enabled by keyer_mode
|
||||||
|
@ -1269,14 +1269,9 @@ init_devices (gpointer data)
|
||||||
|
|
||||||
ret = iterator->Next (&decklink);
|
ret = iterator->Next (&decklink);
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (i == GST_DECKLINK_MAX_DEVICES) {
|
|
||||||
GST_WARNING ("this hardware has more then 10 devices");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n_devices = i;
|
GST_INFO ("Detected %u devices", devices->len);
|
||||||
|
|
||||||
iterator->Release ();
|
iterator->Release ();
|
||||||
|
|
||||||
|
@ -1287,13 +1282,15 @@ GstDecklinkOutput *
|
||||||
gst_decklink_acquire_nth_output (gint n, GstElement * sink, gboolean is_audio)
|
gst_decklink_acquire_nth_output (gint n, GstElement * sink, gboolean is_audio)
|
||||||
{
|
{
|
||||||
GstDecklinkOutput *output;
|
GstDecklinkOutput *output;
|
||||||
|
Device *device;
|
||||||
|
|
||||||
g_once (&devices_once, init_devices, NULL);
|
g_once (&devices_once, init_devices, NULL);
|
||||||
|
|
||||||
if (n >= n_devices)
|
if (n < 0 || (guint) n >= devices->len)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
output = &devices[n].output;
|
device = &g_array_index (devices, Device, n);
|
||||||
|
output = &device->output;
|
||||||
if (!output->output) {
|
if (!output->output) {
|
||||||
GST_ERROR ("Device %d has no output", n);
|
GST_ERROR ("Device %d has no output", n);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1319,11 +1316,13 @@ void
|
||||||
gst_decklink_release_nth_output (gint n, GstElement * sink, gboolean is_audio)
|
gst_decklink_release_nth_output (gint n, GstElement * sink, gboolean is_audio)
|
||||||
{
|
{
|
||||||
GstDecklinkOutput *output;
|
GstDecklinkOutput *output;
|
||||||
|
Device *device;
|
||||||
|
|
||||||
if (n >= n_devices)
|
if (n < 0 || (guint) n >= devices->len)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
output = &devices[n].output;
|
device = &g_array_index (devices, Device, n);
|
||||||
|
output = &device->output;
|
||||||
g_assert (output->output);
|
g_assert (output->output);
|
||||||
|
|
||||||
g_mutex_lock (&output->lock);
|
g_mutex_lock (&output->lock);
|
||||||
|
@ -1343,13 +1342,15 @@ GstDecklinkInput *
|
||||||
gst_decklink_acquire_nth_input (gint n, GstElement * src, gboolean is_audio)
|
gst_decklink_acquire_nth_input (gint n, GstElement * src, gboolean is_audio)
|
||||||
{
|
{
|
||||||
GstDecklinkInput *input;
|
GstDecklinkInput *input;
|
||||||
|
Device *device;
|
||||||
|
|
||||||
g_once (&devices_once, init_devices, NULL);
|
g_once (&devices_once, init_devices, NULL);
|
||||||
|
|
||||||
if (n >= n_devices)
|
if (n < 0 || (guint) n >= devices->len)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
input = &devices[n].input;
|
device = &g_array_index (devices, Device, n);
|
||||||
|
input = &device->input;
|
||||||
if (!input->input) {
|
if (!input->input) {
|
||||||
GST_ERROR ("Device %d has no input", n);
|
GST_ERROR ("Device %d has no input", n);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1377,11 +1378,14 @@ void
|
||||||
gst_decklink_release_nth_input (gint n, GstElement * src, gboolean is_audio)
|
gst_decklink_release_nth_input (gint n, GstElement * src, gboolean is_audio)
|
||||||
{
|
{
|
||||||
GstDecklinkInput *input;
|
GstDecklinkInput *input;
|
||||||
|
Device *device;
|
||||||
|
|
||||||
if (n >= n_devices)
|
if (n < 0 || (guint) n >= devices->len)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
input = &devices[n].input;
|
device = &g_array_index (devices, Device, n);
|
||||||
|
|
||||||
|
input = &device->input;
|
||||||
g_assert (input->input);
|
g_assert (input->input);
|
||||||
|
|
||||||
g_mutex_lock (&input->lock);
|
g_mutex_lock (&input->lock);
|
||||||
|
|
Loading…
Reference in a new issue