decklink: Add read-only property to read the device serial number

https://bugzilla.gnome.org/show_bug.cgi?id=788510
This commit is contained in:
Sebastian Dröge 2017-10-04 13:53:35 +02:00
parent 739d488cea
commit a563cbbc1c
6 changed files with 80 additions and 3 deletions

View File

@ -1232,6 +1232,18 @@ init_devices (gpointer data)
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);
} else {
char *serial_number;
ret =
devices[i].input.
config->GetString (bmdDeckLinkConfigDeviceInformationSerialNumber,
(COMSTR_T *) & serial_number);
CONVERT_COM_STRING (serial_number);
devices[i].output.hw_serial_number = g_strdup (serial_number);
devices[i].input.hw_serial_number = g_strdup (serial_number);
GST_DEBUG ("device %d has serial number %s", i, serial_number);
FREE_COM_STRING (serial_number);
} }
ret = decklink->QueryInterface (IID_IDeckLinkAttributes, ret = decklink->QueryInterface (IID_IDeckLinkAttributes,

View File

@ -209,6 +209,9 @@ struct _GstDecklinkOutput {
IDeckLinkOutput *output; IDeckLinkOutput *output;
IDeckLinkAttributes *attributes; IDeckLinkAttributes *attributes;
IDeckLinkKeyer *keyer; IDeckLinkKeyer *keyer;
gchar *hw_serial_number;
GstClock *clock; GstClock *clock;
GstClockTime clock_start_time, clock_last_time, clock_epoch; GstClockTime clock_start_time, clock_last_time, clock_epoch;
GstClockTimeDiff clock_offset; GstClockTimeDiff clock_offset;
@ -238,6 +241,8 @@ struct _GstDecklinkInput {
IDeckLinkConfiguration *config; IDeckLinkConfiguration *config;
IDeckLinkAttributes *attributes; IDeckLinkAttributes *attributes;
gchar *hw_serial_number;
/* Everything below protected by mutex */ /* Everything below protected by mutex */
GMutex lock; GMutex lock;

View File

@ -487,6 +487,8 @@ gst_decklink_audio_sink_ringbuffer_open_device (GstAudioRingBuffer * rb)
return FALSE; return FALSE;
} }
g_object_notify (G_OBJECT (self->sink), "hw-serial-number");
gst_decklink_output_set_audio_clock (self->output, gst_decklink_output_set_audio_clock (self->output,
GST_AUDIO_BASE_SINK_CAST (self->sink)->provided_clock); GST_AUDIO_BASE_SINK_CAST (self->sink)->provided_clock);
@ -514,7 +516,8 @@ gst_decklink_audio_sink_ringbuffer_close_device (GstAudioRingBuffer * rb)
enum enum
{ {
PROP_0, PROP_0,
PROP_DEVICE_NUMBER PROP_DEVICE_NUMBER,
PROP_HW_SERIAL_NUMBER
}; };
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
@ -570,6 +573,11 @@ gst_decklink_audio_sink_class_init (GstDecklinkAudioSinkClass * 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_HW_SERIAL_NUMBER,
g_param_spec_string ("hw-serial-number", "Hardware serial number",
"The serial number (hardware ID) of the Decklink card",
NULL, (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
gst_element_class_add_static_pad_template (element_class, &sink_template); gst_element_class_add_static_pad_template (element_class, &sink_template);
gst_element_class_set_static_metadata (element_class, "Decklink Audio Sink", gst_element_class_set_static_metadata (element_class, "Decklink Audio Sink",
@ -619,6 +627,16 @@ gst_decklink_audio_sink_get_property (GObject * object, guint property_id,
case PROP_DEVICE_NUMBER: case PROP_DEVICE_NUMBER:
g_value_set_int (value, self->device_number); g_value_set_int (value, self->device_number);
break; break;
case PROP_HW_SERIAL_NUMBER:{
GstDecklinkAudioSinkRingBuffer *buf =
GST_DECKLINK_AUDIO_SINK_RING_BUFFER_CAST (GST_AUDIO_BASE_SINK_CAST
(self)->ringbuffer);
if (buf && buf->output)
g_value_set_string (value, buf->output->hw_serial_number);
else
g_value_set_string (value, NULL);
break;
}
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;

View File

@ -45,6 +45,7 @@ enum
PROP_DISCONT_WAIT, PROP_DISCONT_WAIT,
PROP_BUFFER_SIZE, PROP_BUFFER_SIZE,
PROP_CHANNELS, PROP_CHANNELS,
PROP_HW_SERIAL_NUMBER
}; };
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("src", static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("src",
@ -184,6 +185,11 @@ gst_decklink_audio_src_class_init (GstDecklinkAudioSrcClass * 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_HW_SERIAL_NUMBER,
g_param_spec_string ("hw-serial-number", "Hardware serial number",
"The serial number (hardware ID) of the Decklink card",
NULL, (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
gst_element_class_add_static_pad_template (element_class, &sink_template); gst_element_class_add_static_pad_template (element_class, &sink_template);
gst_element_class_set_static_metadata (element_class, "Decklink Audio Source", gst_element_class_set_static_metadata (element_class, "Decklink Audio Source",
@ -271,6 +277,12 @@ gst_decklink_audio_src_get_property (GObject * object, guint property_id,
case PROP_CHANNELS: case PROP_CHANNELS:
g_value_set_enum (value, self->channels); g_value_set_enum (value, self->channels);
break; break;
case PROP_HW_SERIAL_NUMBER:
if (self->input)
g_value_set_string (value, self->input->hw_serial_number);
else
g_value_set_string (value, NULL);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@ -792,6 +804,8 @@ gst_decklink_audio_src_open (GstDecklinkAudioSrc * self)
return FALSE; return FALSE;
} }
g_object_notify (G_OBJECT (self), "hw-serial-number");
g_mutex_lock (&self->input->lock); g_mutex_lock (&self->input->lock);
if (self->channels > 0) { if (self->channels > 0) {
self->channels_found = self->channels; self->channels_found = self->channels;

View File

@ -122,7 +122,8 @@ enum
PROP_VIDEO_FORMAT, PROP_VIDEO_FORMAT,
PROP_TIMECODE_FORMAT, PROP_TIMECODE_FORMAT,
PROP_KEYER_MODE, PROP_KEYER_MODE,
PROP_KEYER_LEVEL PROP_KEYER_LEVEL,
PROP_HW_SERIAL_NUMBER
}; };
static void gst_decklink_video_sink_set_property (GObject * object, static void gst_decklink_video_sink_set_property (GObject * object,
@ -243,6 +244,11 @@ 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_HW_SERIAL_NUMBER,
g_param_spec_string ("hw-serial-number", "Hardware serial number",
"The serial number (hardware ID) of the Decklink card",
NULL, (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
templ_caps = gst_decklink_mode_get_template_caps (FALSE); templ_caps = gst_decklink_mode_get_template_caps (FALSE);
templ_caps = gst_caps_make_writable (templ_caps); templ_caps = gst_caps_make_writable (templ_caps);
/* For output we support any framerate and only really care about timestamps */ /* For output we support any framerate and only really care about timestamps */
@ -346,6 +352,12 @@ gst_decklink_video_sink_get_property (GObject * object, guint property_id,
case PROP_KEYER_LEVEL: case PROP_KEYER_LEVEL:
g_value_set_int (value, self->keyer_level); g_value_set_int (value, self->keyer_level);
break; break;
case PROP_HW_SERIAL_NUMBER:
if (self->output)
g_value_set_string (value, self->output->hw_serial_number);
else
g_value_set_string (value, NULL);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@ -762,6 +774,8 @@ gst_decklink_video_sink_open (GstBaseSink * bsink)
return FALSE; return FALSE;
} }
g_object_notify (G_OBJECT (self), "hw-serial-number");
mode = gst_decklink_get_mode (self->mode); mode = gst_decklink_get_mode (self->mode);
g_assert (mode != NULL); g_assert (mode != NULL);

View File

@ -48,7 +48,8 @@ enum
PROP_OUTPUT_STREAM_TIME, PROP_OUTPUT_STREAM_TIME,
PROP_SKIP_FIRST_TIME, PROP_SKIP_FIRST_TIME,
PROP_DROP_NO_SIGNAL_FRAMES, PROP_DROP_NO_SIGNAL_FRAMES,
PROP_SIGNAL PROP_SIGNAL,
PROP_HW_SERIAL_NUMBER
}; };
typedef struct typedef struct
@ -211,6 +212,11 @@ gst_decklink_video_src_class_init (GstDecklinkVideoSrcClass * klass)
"True if there is a valid input signal available", "True if there is a valid input signal available",
FALSE, (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS))); FALSE, (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class, PROP_HW_SERIAL_NUMBER,
g_param_spec_string ("hw-serial-number", "Hardware serial number",
"The serial number (hardware ID) of the Decklink card",
NULL, (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
templ_caps = gst_decklink_mode_get_template_caps (TRUE); templ_caps = gst_decklink_mode_get_template_caps (TRUE);
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, templ_caps)); gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, templ_caps));
@ -359,6 +365,12 @@ gst_decklink_video_src_get_property (GObject * object, guint property_id,
case PROP_SIGNAL: case PROP_SIGNAL:
g_value_set_boolean (value, !self->no_signal); g_value_set_boolean (value, !self->no_signal);
break; break;
case PROP_HW_SERIAL_NUMBER:
if (self->input)
g_value_set_string (value, self->input->hw_serial_number);
else
g_value_set_string (value, NULL);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@ -970,6 +982,8 @@ gst_decklink_video_src_open (GstDecklinkVideoSrc * self)
return FALSE; return FALSE;
} }
g_object_notify (G_OBJECT (self), "hw-serial-number");
mode = gst_decklink_get_mode (self->mode); mode = gst_decklink_get_mode (self->mode);
g_assert (mode != NULL); g_assert (mode != NULL);
g_mutex_lock (&self->input->lock); g_mutex_lock (&self->input->lock);