mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-06 07:28:53 +00:00
decklink: implement duplex-mode property
This commit is contained in:
parent
df4205d30f
commit
58dadd1ad0
6 changed files with 278 additions and 0 deletions
|
@ -139,6 +139,24 @@ gst_decklink_video_format_get_type (void)
|
||||||
return (GType) id;
|
return (GType) id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GType
|
||||||
|
gst_decklink_duplex_mode_get_type (void)
|
||||||
|
{
|
||||||
|
static gsize id = 0;
|
||||||
|
static const GEnumValue types[] = {
|
||||||
|
{GST_DECKLINK_DUPLEX_MODE_HALF, "Half-Duplex", "half"},
|
||||||
|
{GST_DECKLINK_DUPLEX_MODE_FULL, "Full-Duplex", "full"},
|
||||||
|
{0, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (g_once_init_enter (&id)) {
|
||||||
|
GType tmp = g_enum_register_static ("GstDecklinkDuplexMode", types);
|
||||||
|
g_once_init_leave (&id, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (GType) id;
|
||||||
|
}
|
||||||
|
|
||||||
GType
|
GType
|
||||||
gst_decklink_timecode_format_get_type (void)
|
gst_decklink_timecode_format_get_type (void)
|
||||||
{
|
{
|
||||||
|
@ -299,6 +317,24 @@ static const struct
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
BMDDuplexMode mode;
|
||||||
|
GstDecklinkDuplexMode gstmode;
|
||||||
|
} duplex_modes[] = {
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
{bmdDuplexModeHalf, GST_DECKLINK_DUPLEX_MODE_HALF},
|
||||||
|
{bmdDuplexModeFull, GST_DECKLINK_DUPLEX_MODE_FULL},
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DuplexModeSetOperationResult
|
||||||
|
{
|
||||||
|
DUPLEX_MODE_SET_UNSUPPORTED,
|
||||||
|
DUPLEX_MODE_SET_SUCCESS,
|
||||||
|
DUPLEX_MODE_SET_FAILURE
|
||||||
|
};
|
||||||
|
|
||||||
static const struct
|
static const struct
|
||||||
{
|
{
|
||||||
BMDTimecodeFormat format;
|
BMDTimecodeFormat format;
|
||||||
|
@ -495,6 +531,25 @@ gst_decklink_timecode_format_to_enum (BMDTimecodeFormat f)
|
||||||
return GST_DECKLINK_TIMECODE_FORMAT_RP188ANY;
|
return GST_DECKLINK_TIMECODE_FORMAT_RP188ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BMDDuplexMode
|
||||||
|
gst_decklink_duplex_mode_from_enum (GstDecklinkDuplexMode m)
|
||||||
|
{
|
||||||
|
return duplex_modes[m].mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GstDecklinkDuplexMode
|
||||||
|
gst_decklink_duplex_mode_to_enum (BMDDuplexMode m)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (duplex_modes); i++) {
|
||||||
|
if (duplex_modes[i].mode == m)
|
||||||
|
return duplex_modes[i].gstmode;
|
||||||
|
}
|
||||||
|
g_assert_not_reached ();
|
||||||
|
return GST_DECKLINK_DUPLEX_MODE_HALF;
|
||||||
|
}
|
||||||
|
|
||||||
const BMDKeyerMode
|
const BMDKeyerMode
|
||||||
gst_decklink_keyer_mode_from_enum (GstDecklinkKeyerMode m)
|
gst_decklink_keyer_mode_from_enum (GstDecklinkKeyerMode m)
|
||||||
{
|
{
|
||||||
|
@ -734,6 +789,15 @@ struct _Device
|
||||||
GstDecklinkInput input;
|
GstDecklinkInput input;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DuplexModeSetOperationResult gst_decklink_configure_duplex_mode (Device *
|
||||||
|
device, BMDDuplexMode duplex_mode);
|
||||||
|
DuplexModeSetOperationResult
|
||||||
|
gst_decklink_configure_duplex_mode_pair_device (Device * device,
|
||||||
|
BMDDuplexMode duplex_mode);
|
||||||
|
Device *gst_decklink_find_device_by_persistent_id (int64_t persistent_id);
|
||||||
|
gboolean gst_decklink_device_has_persistent_id (Device * device,
|
||||||
|
int64_t persistent_id);
|
||||||
|
|
||||||
class GStreamerDecklinkInputCallback:public IDeckLinkInputCallback
|
class GStreamerDecklinkInputCallback:public IDeckLinkInputCallback
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -1319,6 +1383,14 @@ gst_decklink_acquire_nth_output (gint n, GstElement * sink, gboolean is_audio)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_audio) {
|
||||||
|
GstDecklinkVideoSink *videosink = (GstDecklinkVideoSink *) (sink);
|
||||||
|
if (gst_decklink_configure_duplex_mode (device,
|
||||||
|
videosink->duplex_mode) == DUPLEX_MODE_SET_FAILURE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
g_mutex_lock (&output->lock);
|
g_mutex_lock (&output->lock);
|
||||||
if (is_audio && !output->audiosink) {
|
if (is_audio && !output->audiosink) {
|
||||||
output->audiosink = GST_ELEMENT_CAST (gst_object_ref (sink));
|
output->audiosink = GST_ELEMENT_CAST (gst_object_ref (sink));
|
||||||
|
@ -1385,6 +1457,13 @@ gst_decklink_acquire_nth_input (gint n, GstElement * src, gboolean is_audio)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_audio) {
|
||||||
|
GstDecklinkVideoSrc *videosrc = (GstDecklinkVideoSrc *) (src);
|
||||||
|
if (gst_decklink_configure_duplex_mode (device,
|
||||||
|
videosrc->duplex_mode) == DUPLEX_MODE_SET_FAILURE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
g_mutex_lock (&input->lock);
|
g_mutex_lock (&input->lock);
|
||||||
input->input->SetVideoInputFrameMemoryAllocator (new
|
input->input->SetVideoInputFrameMemoryAllocator (new
|
||||||
GStreamerDecklinkMemoryAllocator);
|
GStreamerDecklinkMemoryAllocator);
|
||||||
|
@ -1433,6 +1512,145 @@ gst_decklink_release_nth_input (gint n, GstElement * src, gboolean is_audio)
|
||||||
g_mutex_unlock (&input->lock);
|
g_mutex_unlock (&input->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Probes if duplex-mode is supported and sets it accordingly. I duplex-mode is not supported
|
||||||
|
* but this device is part of a pair (Duo2- and Quad2-Cards) and Half-Dupley-Mode is requested,
|
||||||
|
* the parent device is also checked and configured accordingly.
|
||||||
|
*
|
||||||
|
* If
|
||||||
|
* - full-duplex-mode is requsted and the device does not support it *or*
|
||||||
|
* - half-duplex-mode is requested and there is not parent-device *or*
|
||||||
|
* - half-duplex-mode is requested and neither the device nor the parent device does support setting
|
||||||
|
* the duplex-mode, DUPLEX_MODE_SET_UNSUPPORTED is returnded.
|
||||||
|
* If the device does support duplex-mode and setting it succeeded, DUPLEX_MODE_SET_SUCCESS is rerturned.
|
||||||
|
* If
|
||||||
|
* - the device does support duplex-mode and setting it failed *or*
|
||||||
|
* - the Device reported a pair-device that does not exist in the system,
|
||||||
|
* DUPLEX_MODE_SET_FAILURE is returned.
|
||||||
|
*/
|
||||||
|
DuplexModeSetOperationResult
|
||||||
|
gst_decklink_configure_duplex_mode (Device * device, BMDDuplexMode duplex_mode)
|
||||||
|
{
|
||||||
|
HRESULT result;
|
||||||
|
bool duplex_supported;
|
||||||
|
int64_t paired_device_id;
|
||||||
|
|
||||||
|
GstDecklinkInput *input = &device->input;
|
||||||
|
|
||||||
|
result =
|
||||||
|
input->attributes->GetFlag (BMDDeckLinkSupportsDuplexModeConfiguration,
|
||||||
|
&duplex_supported);
|
||||||
|
if (result != S_OK) {
|
||||||
|
duplex_supported = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!duplex_supported) {
|
||||||
|
if (duplex_mode == bmdDuplexModeFull) {
|
||||||
|
GST_DEBUG ("Device does not support Full-Duplex-Mode");
|
||||||
|
return DUPLEX_MODE_SET_UNSUPPORTED;
|
||||||
|
} else if (duplex_mode == bmdDuplexModeHalf) {
|
||||||
|
result =
|
||||||
|
input->attributes->GetInt (BMDDeckLinkPairedDevicePersistentID,
|
||||||
|
&paired_device_id);
|
||||||
|
|
||||||
|
if (result == S_OK) {
|
||||||
|
GST_DEBUG ("Device does not support Half-Duplex-Mode but the Device is "
|
||||||
|
"a Part of a Device-Pair, trying to set Half-Duplex-Mode "
|
||||||
|
"on the Parent-Device");
|
||||||
|
|
||||||
|
Device *pair_device =
|
||||||
|
gst_decklink_find_device_by_persistent_id (paired_device_id);
|
||||||
|
if (pair_device == NULL) {
|
||||||
|
GST_ERROR ("Device reported as Pair-Device does not exist");
|
||||||
|
return DUPLEX_MODE_SET_FAILURE;
|
||||||
|
}
|
||||||
|
return gst_decklink_configure_duplex_mode_pair_device (pair_device,
|
||||||
|
duplex_mode);
|
||||||
|
} else {
|
||||||
|
GST_DEBUG ("Device does not support Half-Duplex-Mode");
|
||||||
|
return DUPLEX_MODE_SET_SUCCESS;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
g_assert_not_reached ();
|
||||||
|
} else {
|
||||||
|
GST_DEBUG ("Setting duplex-mode of Device");
|
||||||
|
result = input->config->SetInt (bmdDeckLinkConfigDuplexMode, duplex_mode);
|
||||||
|
|
||||||
|
if (result == S_OK) {
|
||||||
|
GST_DEBUG ("Duplex mode set successful");
|
||||||
|
return DUPLEX_MODE_SET_SUCCESS;
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Setting duplex mode failed");
|
||||||
|
return DUPLEX_MODE_SET_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DuplexModeSetOperationResult
|
||||||
|
gst_decklink_configure_duplex_mode_pair_device (Device * device,
|
||||||
|
BMDDuplexMode duplex_mode)
|
||||||
|
{
|
||||||
|
HRESULT result;
|
||||||
|
bool duplex_supported;
|
||||||
|
|
||||||
|
GstDecklinkInput *input = &device->input;
|
||||||
|
|
||||||
|
result =
|
||||||
|
input->attributes->GetFlag (BMDDeckLinkSupportsDuplexModeConfiguration,
|
||||||
|
&duplex_supported);
|
||||||
|
if (result != S_OK) {
|
||||||
|
duplex_supported = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!duplex_supported) {
|
||||||
|
GST_DEBUG ("Pair-Device does not support Duplex-Mode");
|
||||||
|
return DUPLEX_MODE_SET_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG ("Setting duplex-mode of Pair-Device");
|
||||||
|
result = input->config->SetInt (bmdDeckLinkConfigDuplexMode, duplex_mode);
|
||||||
|
|
||||||
|
if (result == S_OK) {
|
||||||
|
GST_DEBUG ("Duplex mode set successful");
|
||||||
|
return DUPLEX_MODE_SET_SUCCESS;
|
||||||
|
} else {
|
||||||
|
GST_ERROR ("Setting duplex mode failed");
|
||||||
|
return DUPLEX_MODE_SET_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_decklink_device_has_persistent_id (Device * device, int64_t persistent_id)
|
||||||
|
{
|
||||||
|
HRESULT result;
|
||||||
|
int64_t this_device_persistent_id;
|
||||||
|
|
||||||
|
GstDecklinkInput *input = &device->input;
|
||||||
|
|
||||||
|
result =
|
||||||
|
input->attributes->GetInt (BMDDeckLinkPersistentID,
|
||||||
|
&this_device_persistent_id);
|
||||||
|
return (result == S_OK) && (this_device_persistent_id == persistent_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
Device *
|
||||||
|
gst_decklink_find_device_by_persistent_id (int64_t persistent_id)
|
||||||
|
{
|
||||||
|
GST_DEBUG ("Searching Device by persistent ID %" G_GINT64_FORMAT,
|
||||||
|
persistent_id);
|
||||||
|
|
||||||
|
for (guint index = 0; index < devices->len; index++) {
|
||||||
|
Device *device = (Device *) g_ptr_array_index (devices, index);
|
||||||
|
|
||||||
|
if (gst_decklink_device_has_persistent_id (device, persistent_id)) {
|
||||||
|
GST_DEBUG ("Found matching Device %u", index);
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstDecklinkClock, gst_decklink_clock, GST_TYPE_SYSTEM_CLOCK);
|
G_DEFINE_TYPE (GstDecklinkClock, gst_decklink_clock, GST_TYPE_SYSTEM_CLOCK);
|
||||||
|
|
||||||
static GstClockTime gst_decklink_clock_get_internal_time (GstClock * clock);
|
static GstClockTime gst_decklink_clock_get_internal_time (GstClock * clock);
|
||||||
|
|
|
@ -144,6 +144,13 @@ typedef enum {
|
||||||
#define GST_TYPE_DECKLINK_VIDEO_FORMAT (gst_decklink_video_format_get_type ())
|
#define GST_TYPE_DECKLINK_VIDEO_FORMAT (gst_decklink_video_format_get_type ())
|
||||||
GType gst_decklink_video_format_get_type (void);
|
GType gst_decklink_video_format_get_type (void);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GST_DECKLINK_DUPLEX_MODE_HALF, /* bmdDuplexModeHalf */
|
||||||
|
GST_DECKLINK_DUPLEX_MODE_FULL, /* bmdDuplexModeFull */
|
||||||
|
} GstDecklinkDuplexMode;
|
||||||
|
#define GST_TYPE_DECKLINK_DUPLEX_MODE (gst_decklink_duplex_mode_get_type ())
|
||||||
|
GType gst_decklink_duplex_mode_get_type (void);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GST_DECKLINK_TIMECODE_FORMAT_RP188VITC1, /*bmdTimecodeRP188VITC1 */
|
GST_DECKLINK_TIMECODE_FORMAT_RP188VITC1, /*bmdTimecodeRP188VITC1 */
|
||||||
GST_DECKLINK_TIMECODE_FORMAT_RP188VITC2, /*bmdTimecodeRP188VITC2 */
|
GST_DECKLINK_TIMECODE_FORMAT_RP188VITC2, /*bmdTimecodeRP188VITC2 */
|
||||||
|
@ -181,6 +188,8 @@ const GstDecklinkVideoFormat gst_decklink_type_from_video_format (GstVideoFormat
|
||||||
GstVideoFormat gst_decklink_video_format_from_type (BMDPixelFormat pf);
|
GstVideoFormat gst_decklink_video_format_from_type (BMDPixelFormat pf);
|
||||||
const BMDTimecodeFormat gst_decklink_timecode_format_from_enum (GstDecklinkTimecodeFormat f);
|
const BMDTimecodeFormat gst_decklink_timecode_format_from_enum (GstDecklinkTimecodeFormat f);
|
||||||
const GstDecklinkTimecodeFormat gst_decklink_timecode_format_to_enum (BMDTimecodeFormat f);
|
const GstDecklinkTimecodeFormat gst_decklink_timecode_format_to_enum (BMDTimecodeFormat f);
|
||||||
|
const BMDDuplexMode gst_decklink_duplex_mode_from_enum (GstDecklinkDuplexMode m);
|
||||||
|
const GstDecklinkDuplexMode gst_decklink_duplex_mode_to_enum (BMDDuplexMode m);
|
||||||
const BMDKeyerMode gst_decklink_keyer_mode_from_enum (GstDecklinkKeyerMode m);
|
const BMDKeyerMode gst_decklink_keyer_mode_from_enum (GstDecklinkKeyerMode m);
|
||||||
const GstDecklinkKeyerMode gst_decklink_keyer_mode_to_enum (BMDKeyerMode m);
|
const GstDecklinkKeyerMode gst_decklink_keyer_mode_to_enum (BMDKeyerMode m);
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,7 @@ enum
|
||||||
PROP_MODE,
|
PROP_MODE,
|
||||||
PROP_DEVICE_NUMBER,
|
PROP_DEVICE_NUMBER,
|
||||||
PROP_VIDEO_FORMAT,
|
PROP_VIDEO_FORMAT,
|
||||||
|
PROP_DUPLEX_MODE,
|
||||||
PROP_TIMECODE_FORMAT,
|
PROP_TIMECODE_FORMAT,
|
||||||
PROP_KEYER_MODE,
|
PROP_KEYER_MODE,
|
||||||
PROP_KEYER_LEVEL,
|
PROP_KEYER_LEVEL,
|
||||||
|
@ -227,6 +228,20 @@ gst_decklink_video_sink_class_init (GstDecklinkVideoSinkClass * klass)
|
||||||
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
G_PARAM_CONSTRUCT)));
|
G_PARAM_CONSTRUCT)));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_DUPLEX_MODE,
|
||||||
|
g_param_spec_enum ("duplex-mode", "Duplex mode",
|
||||||
|
"Certain DeckLink devices such as the DeckLink Quad 2 and the "
|
||||||
|
"DeckLink Duo 2 support configuration of the duplex mode of "
|
||||||
|
"individual sub-devices."
|
||||||
|
"A sub-device configured as full-duplex will use two connectors, "
|
||||||
|
"which allows simultaneous capture and playback, internal keying, "
|
||||||
|
"and fill & key scenarios."
|
||||||
|
"A half-duplex sub-device will use a single connector as an "
|
||||||
|
"individual capture or playback channel.",
|
||||||
|
GST_TYPE_DECKLINK_DUPLEX_MODE, GST_DECKLINK_DUPLEX_MODE_HALF,
|
||||||
|
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
|
G_PARAM_CONSTRUCT)));
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, PROP_TIMECODE_FORMAT,
|
g_object_class_install_property (gobject_class, PROP_TIMECODE_FORMAT,
|
||||||
g_param_spec_enum ("timecode-format", "Timecode format",
|
g_param_spec_enum ("timecode-format", "Timecode format",
|
||||||
"Timecode format type to use for playback",
|
"Timecode format type to use for playback",
|
||||||
|
@ -284,6 +299,7 @@ gst_decklink_video_sink_init (GstDecklinkVideoSink * self)
|
||||||
self->mode = GST_DECKLINK_MODE_NTSC;
|
self->mode = GST_DECKLINK_MODE_NTSC;
|
||||||
self->device_number = 0;
|
self->device_number = 0;
|
||||||
self->video_format = GST_DECKLINK_VIDEO_FORMAT_8BIT_YUV;
|
self->video_format = GST_DECKLINK_VIDEO_FORMAT_8BIT_YUV;
|
||||||
|
self->duplex_mode = bmdDuplexModeHalf;
|
||||||
/* VITC is legacy, we should expect RP188 in modern use cases */
|
/* VITC is legacy, we should expect RP188 in modern use cases */
|
||||||
self->timecode_format = bmdTimecodeRP188Any;
|
self->timecode_format = bmdTimecodeRP188Any;
|
||||||
self->caption_line = 0;
|
self->caption_line = 0;
|
||||||
|
@ -320,6 +336,11 @@ gst_decklink_video_sink_set_property (GObject * object, guint property_id,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PROP_DUPLEX_MODE:
|
||||||
|
self->duplex_mode =
|
||||||
|
gst_decklink_duplex_mode_from_enum ((GstDecklinkDuplexMode)
|
||||||
|
g_value_get_enum (value));
|
||||||
|
break;
|
||||||
case PROP_TIMECODE_FORMAT:
|
case PROP_TIMECODE_FORMAT:
|
||||||
self->timecode_format =
|
self->timecode_format =
|
||||||
gst_decklink_timecode_format_from_enum ((GstDecklinkTimecodeFormat)
|
gst_decklink_timecode_format_from_enum ((GstDecklinkTimecodeFormat)
|
||||||
|
@ -358,6 +379,10 @@ gst_decklink_video_sink_get_property (GObject * object, guint property_id,
|
||||||
case PROP_VIDEO_FORMAT:
|
case PROP_VIDEO_FORMAT:
|
||||||
g_value_set_enum (value, self->video_format);
|
g_value_set_enum (value, self->video_format);
|
||||||
break;
|
break;
|
||||||
|
case PROP_DUPLEX_MODE:
|
||||||
|
g_value_set_enum (value,
|
||||||
|
gst_decklink_duplex_mode_to_enum (self->duplex_mode));
|
||||||
|
break;
|
||||||
case PROP_TIMECODE_FORMAT:
|
case PROP_TIMECODE_FORMAT:
|
||||||
g_value_set_enum (value,
|
g_value_set_enum (value,
|
||||||
gst_decklink_timecode_format_to_enum (self->timecode_format));
|
gst_decklink_timecode_format_to_enum (self->timecode_format));
|
||||||
|
|
|
@ -52,6 +52,7 @@ struct _GstDecklinkVideoSink
|
||||||
GstDecklinkModeEnum mode;
|
GstDecklinkModeEnum mode;
|
||||||
gint device_number;
|
gint device_number;
|
||||||
GstDecklinkVideoFormat video_format;
|
GstDecklinkVideoFormat video_format;
|
||||||
|
BMDDuplexMode duplex_mode;
|
||||||
BMDTimecodeFormat timecode_format;
|
BMDTimecodeFormat timecode_format;
|
||||||
BMDKeyerMode keyer_mode;
|
BMDKeyerMode keyer_mode;
|
||||||
gint keyer_level;
|
gint keyer_level;
|
||||||
|
|
|
@ -49,6 +49,7 @@ enum
|
||||||
PROP_DEVICE_NUMBER,
|
PROP_DEVICE_NUMBER,
|
||||||
PROP_BUFFER_SIZE,
|
PROP_BUFFER_SIZE,
|
||||||
PROP_VIDEO_FORMAT,
|
PROP_VIDEO_FORMAT,
|
||||||
|
PROP_DUPLEX_MODE,
|
||||||
PROP_TIMECODE_FORMAT,
|
PROP_TIMECODE_FORMAT,
|
||||||
PROP_OUTPUT_STREAM_TIME,
|
PROP_OUTPUT_STREAM_TIME,
|
||||||
PROP_SKIP_FIRST_TIME,
|
PROP_SKIP_FIRST_TIME,
|
||||||
|
@ -187,6 +188,20 @@ gst_decklink_video_src_class_init (GstDecklinkVideoSrcClass * klass)
|
||||||
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
G_PARAM_CONSTRUCT)));
|
G_PARAM_CONSTRUCT)));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_DUPLEX_MODE,
|
||||||
|
g_param_spec_enum ("duplex-mode", "Duplex mode",
|
||||||
|
"Certain DeckLink devices such as the DeckLink Quad 2 and the "
|
||||||
|
"DeckLink Duo 2 support configuration of the duplex mode of "
|
||||||
|
"individual sub-devices."
|
||||||
|
"A sub-device configured as full-duplex will use two connectors, "
|
||||||
|
"which allows simultaneous capture and playback, internal keying, "
|
||||||
|
"and fill & key scenarios."
|
||||||
|
"A half-duplex sub-device will use a single connector as an "
|
||||||
|
"individual capture or playback channel.",
|
||||||
|
GST_TYPE_DECKLINK_DUPLEX_MODE, GST_DECKLINK_DUPLEX_MODE_HALF,
|
||||||
|
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
|
G_PARAM_CONSTRUCT)));
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, PROP_TIMECODE_FORMAT,
|
g_object_class_install_property (gobject_class, PROP_TIMECODE_FORMAT,
|
||||||
g_param_spec_enum ("timecode-format", "Timecode format",
|
g_param_spec_enum ("timecode-format", "Timecode format",
|
||||||
"Timecode format type to use for input",
|
"Timecode format type to use for input",
|
||||||
|
@ -253,6 +268,7 @@ gst_decklink_video_src_init (GstDecklinkVideoSrc * self)
|
||||||
self->device_number = 0;
|
self->device_number = 0;
|
||||||
self->buffer_size = DEFAULT_BUFFER_SIZE;
|
self->buffer_size = DEFAULT_BUFFER_SIZE;
|
||||||
self->video_format = GST_DECKLINK_VIDEO_FORMAT_AUTO;
|
self->video_format = GST_DECKLINK_VIDEO_FORMAT_AUTO;
|
||||||
|
self->duplex_mode = bmdDuplexModeHalf;
|
||||||
self->timecode_format = bmdTimecodeRP188Any;
|
self->timecode_format = bmdTimecodeRP188Any;
|
||||||
self->no_signal = FALSE;
|
self->no_signal = FALSE;
|
||||||
self->output_stream_time = DEFAULT_OUTPUT_STREAM_TIME;
|
self->output_stream_time = DEFAULT_OUTPUT_STREAM_TIME;
|
||||||
|
@ -319,6 +335,10 @@ gst_decklink_video_src_set_property (GObject * object, guint property_id,
|
||||||
("Format %d not supported", self->video_format), (NULL));
|
("Format %d not supported", self->video_format), (NULL));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PROP_DUPLEX_MODE:
|
||||||
|
self->duplex_mode =
|
||||||
|
gst_decklink_duplex_mode_from_enum ((GstDecklinkDuplexMode)
|
||||||
|
g_value_get_enum (value));
|
||||||
break;
|
break;
|
||||||
case PROP_TIMECODE_FORMAT:
|
case PROP_TIMECODE_FORMAT:
|
||||||
self->timecode_format =
|
self->timecode_format =
|
||||||
|
@ -365,6 +385,10 @@ gst_decklink_video_src_get_property (GObject * object, guint property_id,
|
||||||
case PROP_VIDEO_FORMAT:
|
case PROP_VIDEO_FORMAT:
|
||||||
g_value_set_enum (value, self->video_format);
|
g_value_set_enum (value, self->video_format);
|
||||||
break;
|
break;
|
||||||
|
case PROP_DUPLEX_MODE:
|
||||||
|
g_value_set_enum (value,
|
||||||
|
gst_decklink_duplex_mode_to_enum (self->duplex_mode));
|
||||||
|
break;
|
||||||
case PROP_TIMECODE_FORMAT:
|
case PROP_TIMECODE_FORMAT:
|
||||||
g_value_set_enum (value,
|
g_value_set_enum (value,
|
||||||
gst_decklink_timecode_format_to_enum (self->timecode_format));
|
gst_decklink_timecode_format_to_enum (self->timecode_format));
|
||||||
|
|
|
@ -65,6 +65,7 @@ struct _GstDecklinkVideoSrc
|
||||||
|
|
||||||
GstVideoInfo info;
|
GstVideoInfo info;
|
||||||
GstDecklinkVideoFormat video_format;
|
GstDecklinkVideoFormat video_format;
|
||||||
|
BMDDuplexMode duplex_mode;
|
||||||
BMDTimecodeFormat timecode_format;
|
BMDTimecodeFormat timecode_format;
|
||||||
|
|
||||||
GstDecklinkInput *input;
|
GstDecklinkInput *input;
|
||||||
|
|
Loading…
Reference in a new issue