summaryrefslogtreecommitdiff
path: root/sys/decklink
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2019-08-06 21:44:35 +0300
committerMathieu Duponchelle <mduponchelle1@gmail.com>2019-08-06 19:05:38 +0000
commitab8bd0aa446e9c09fd5aa2bd802f451324610e22 (patch)
treecc3ca72acd009551f52f78e49c086b0f6452d0da /sys/decklink
parent8257159909c6b7b74eb2e468d74806ff000dff21 (diff)
downloadgstreamer-plugins-bad-ab8bd0aa446e9c09fd5aa2bd802f451324610e22.tar.gz
decklinkaudiosrc/decklinkvideosrc: Do nothing in BaseSrc::negotiate() and always set caps in ::create()
We don't support negotiation with downstream but simply set caps based on the buffers we receive. This prevents renegotiation to other formats, and negotiation to NTSC in mode=auto in the beginning until the first buffer is received. As side-effect of this, also remove various other caps handling code that was working around the behaviour of the default BaseSrc::negotiate().
Diffstat (limited to 'sys/decklink')
-rw-r--r--sys/decklink/gstdecklinkaudiosrc.cpp117
-rw-r--r--sys/decklink/gstdecklinkvideosrc.cpp78
2 files changed, 64 insertions, 131 deletions
diff --git a/sys/decklink/gstdecklinkaudiosrc.cpp b/sys/decklink/gstdecklinkaudiosrc.cpp
index 6413ba50b..2fef934c8 100644
--- a/sys/decklink/gstdecklinkaudiosrc.cpp
+++ b/sys/decklink/gstdecklinkaudiosrc.cpp
@@ -123,10 +123,6 @@ static GstStateChangeReturn
gst_decklink_audio_src_change_state (GstElement * element,
GstStateChange transition);
-static gboolean gst_decklink_audio_src_set_caps (GstBaseSrc * bsrc,
- GstCaps * caps);
-static GstCaps *gst_decklink_audio_src_get_caps (GstBaseSrc * bsrc,
- GstCaps * filter);
static gboolean gst_decklink_audio_src_unlock (GstBaseSrc * bsrc);
static gboolean gst_decklink_audio_src_unlock_stop (GstBaseSrc * bsrc);
static gboolean gst_decklink_audio_src_query (GstBaseSrc * bsrc,
@@ -158,9 +154,8 @@ gst_decklink_audio_src_class_init (GstDecklinkAudioSrcClass * klass)
element_class->change_state =
GST_DEBUG_FUNCPTR (gst_decklink_audio_src_change_state);
- basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_decklink_audio_src_get_caps);
- basesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_decklink_audio_src_set_caps);
basesrc_class->query = GST_DEBUG_FUNCPTR (gst_decklink_audio_src_query);
+ basesrc_class->negotiate = NULL;
basesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_decklink_audio_src_unlock);
basesrc_class->unlock_stop =
GST_DEBUG_FUNCPTR (gst_decklink_audio_src_unlock_stop);
@@ -234,6 +229,8 @@ gst_decklink_audio_src_init (GstDecklinkAudioSrc * self)
gst_base_src_set_live (GST_BASE_SRC (self), TRUE);
gst_base_src_set_format (GST_BASE_SRC (self), GST_FORMAT_TIME);
+ gst_pad_use_fixed_caps (GST_BASE_SRC_PAD (self));
+
g_mutex_init (&self->lock);
g_cond_init (&self->cond);
@@ -332,47 +329,42 @@ gst_decklink_audio_src_finalize (GObject * object)
}
static gboolean
-gst_decklink_audio_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
+gst_decklink_audio_src_start (GstDecklinkAudioSrc * self)
{
- GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (bsrc);
BMDAudioSampleType sample_depth;
- GstCaps *current_caps;
HRESULT ret;
BMDAudioConnection conn = (BMDAudioConnection) - 1;
+ GstCaps *allowed_caps, *caps;
- GST_DEBUG_OBJECT (self, "Setting caps %" GST_PTR_FORMAT, caps);
+ g_mutex_lock (&self->input->lock);
+ if (self->input->audio_enabled) {
+ g_mutex_unlock (&self->input->lock);
+ return TRUE;
+ }
+ g_mutex_unlock (&self->input->lock);
- if ((current_caps = gst_pad_get_current_caps (GST_BASE_SRC_PAD (bsrc)))) {
- GstCaps *curcaps_cp;
- GstStructure *cur_st, *caps_st;
+ /* Negotiate the format / sample depth with downstream */
+ allowed_caps = gst_pad_get_allowed_caps (GST_BASE_SRC_PAD (self));
+ if (!allowed_caps)
+ allowed_caps = gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (self));
- GST_DEBUG_OBJECT (self, "Pad already has caps %" GST_PTR_FORMAT, caps);
+ sample_depth = bmdAudioSampleType32bitInteger;
+ if (!gst_caps_is_empty (allowed_caps)) {
+ GstStructure *s;
- curcaps_cp = gst_caps_make_writable (current_caps);
- cur_st = gst_caps_get_structure (curcaps_cp, 0);
- caps_st = gst_caps_get_structure (caps, 0);
- gst_structure_remove_field (cur_st, "channel-mask");
+ allowed_caps = gst_caps_simplify (allowed_caps);
- if (!gst_structure_can_intersect (caps_st, cur_st)) {
- GST_ERROR_OBJECT (self, "New caps are not compatible with old caps");
- gst_caps_unref (current_caps);
- gst_caps_unref (curcaps_cp);
- return FALSE;
- } else {
- gst_caps_unref (current_caps);
- gst_caps_unref (curcaps_cp);
- return TRUE;
- }
- }
-
- if (!gst_audio_info_from_caps (&self->info, caps))
- return FALSE;
+ s = gst_caps_get_structure (allowed_caps, 0);
- if (self->info.finfo->format == GST_AUDIO_FORMAT_S16LE) {
- sample_depth = bmdAudioSampleType16bitInteger;
- } else {
- sample_depth = bmdAudioSampleType32bitInteger;
+ /* If it's not a string then both formats are supported */
+ if (gst_structure_has_field_typed (s, "format", G_TYPE_STRING)) {
+ const gchar *format = gst_structure_get_string (s, "format");
+ if (g_str_equal (format, "S16LE")) {
+ sample_depth = bmdAudioSampleType16bitInteger;
+ }
+ }
}
+ gst_caps_unref (allowed_caps);
switch (self->connection) {
case GST_DECKLINK_AUDIO_CONNECTION_AUTO:{
@@ -449,12 +441,16 @@ gst_decklink_audio_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
}
ret = self->input->input->EnableAudioInput (bmdAudioSampleRate48kHz,
- sample_depth, self->info.channels);
+ sample_depth, self->channels_found);
if (ret != S_OK) {
GST_WARNING_OBJECT (self, "Failed to enable audio input: 0x%08lx",
(unsigned long) ret);
return FALSE;
}
+ gst_audio_info_set_format (&self->info,
+ sample_depth ==
+ bmdAudioSampleType16bitInteger ? GST_AUDIO_FORMAT_S16LE :
+ GST_AUDIO_FORMAT_S32LE, 48000, self->channels_found, NULL);
g_mutex_lock (&self->input->lock);
self->input->audio_enabled = TRUE;
@@ -462,46 +458,15 @@ gst_decklink_audio_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
self->input->start_streams (self->input->videosrc);
g_mutex_unlock (&self->input->lock);
- return TRUE;
-}
-
-static GstCaps *
-gst_decklink_audio_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
-{
- GstDecklinkAudioSrc *self = GST_DECKLINK_AUDIO_SRC_CAST (bsrc);
- GstCaps *caps;
-
- // We don't support renegotiation
- caps = gst_pad_get_current_caps (GST_BASE_SRC_PAD (bsrc));
-
- if (!caps) {
- GstCaps *channel_filter, *templ;
-
- templ = gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (bsrc));
- if (self->channels_found > 0) {
- channel_filter =
- gst_caps_new_simple ("audio/x-raw", "channels", G_TYPE_INT,
- self->channels_found, NULL);
- } else if (self->channels > 0) {
- channel_filter =
- gst_caps_new_simple ("audio/x-raw", "channels", G_TYPE_INT,
- self->channels, NULL);
- } else {
- channel_filter = gst_caps_new_empty_simple ("audio/x-raw");
- }
- caps = gst_caps_intersect (channel_filter, templ);
- gst_caps_unref (channel_filter);
- gst_caps_unref (templ);
- }
-
- if (filter) {
- GstCaps *tmp =
- gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+ caps = gst_audio_info_to_caps (&self->info);
+ if (!gst_base_src_set_caps (GST_BASE_SRC (self), caps)) {
gst_caps_unref (caps);
- caps = tmp;
+ GST_WARNING_OBJECT (self, "Failed to set caps");
+ return FALSE;
}
+ gst_caps_unref (caps);
- return caps;
+ return TRUE;
}
static void
@@ -615,6 +580,10 @@ gst_decklink_audio_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
static GstStaticCaps hardware_reference =
GST_STATIC_CAPS ("timestamp/x-decklink-hardware");
+ if (!gst_decklink_audio_src_start (self)) {
+ return GST_FLOW_NOT_NEGOTIATED;
+ }
+
retry:
g_mutex_lock (&self->lock);
while (gst_queue_array_is_empty (self->current_packets) && !self->flushing) {
diff --git a/sys/decklink/gstdecklinkvideosrc.cpp b/sys/decklink/gstdecklinkvideosrc.cpp
index cdde7d7a1..4c543acd6 100644
--- a/sys/decklink/gstdecklinkvideosrc.cpp
+++ b/sys/decklink/gstdecklinkvideosrc.cpp
@@ -223,10 +223,6 @@ static GstStateChangeReturn
gst_decklink_video_src_change_state (GstElement * element,
GstStateChange transition);
-static gboolean gst_decklink_video_src_set_caps (GstBaseSrc * bsrc,
- GstCaps * caps);
-static GstCaps *gst_decklink_video_src_get_caps (GstBaseSrc * bsrc,
- GstCaps * filter);
static gboolean gst_decklink_video_src_query (GstBaseSrc * bsrc,
GstQuery * query);
static gboolean gst_decklink_video_src_unlock (GstBaseSrc * bsrc);
@@ -261,9 +257,8 @@ gst_decklink_video_src_class_init (GstDecklinkVideoSrcClass * klass)
element_class->change_state =
GST_DEBUG_FUNCPTR (gst_decklink_video_src_change_state);
- basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_decklink_video_src_get_caps);
- basesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_decklink_video_src_set_caps);
basesrc_class->query = GST_DEBUG_FUNCPTR (gst_decklink_video_src_query);
+ basesrc_class->negotiate = NULL;
basesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_decklink_video_src_unlock);
basesrc_class->unlock_stop =
GST_DEBUG_FUNCPTR (gst_decklink_video_src_unlock_stop);
@@ -408,6 +403,8 @@ gst_decklink_video_src_init (GstDecklinkVideoSrc * self)
gst_base_src_set_live (GST_BASE_SRC (self), TRUE);
gst_base_src_set_format (GST_BASE_SRC (self), GST_FORMAT_TIME);
+ gst_pad_use_fixed_caps (GST_BASE_SRC_PAD (self));
+
g_mutex_init (&self->lock);
g_cond_init (&self->cond);
@@ -574,36 +571,19 @@ gst_decklink_video_src_finalize (GObject * object)
}
static gboolean
-gst_decklink_video_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
+gst_decklink_video_src_start (GstDecklinkVideoSrc * self)
{
- GstDecklinkVideoSrc *self = GST_DECKLINK_VIDEO_SRC_CAST (bsrc);
- GstCaps *current_caps;
const GstDecklinkMode *mode;
BMDVideoInputFlags flags;
HRESULT ret;
BMDPixelFormat format;
- GST_DEBUG_OBJECT (self, "Setting caps %" GST_PTR_FORMAT, caps);
-
- if ((current_caps = gst_pad_get_current_caps (GST_BASE_SRC_PAD (bsrc)))) {
- GST_DEBUG_OBJECT (self, "Pad already has caps %" GST_PTR_FORMAT, caps);
-
- if (!gst_caps_is_equal (caps, current_caps)) {
- GST_DEBUG_OBJECT (self, "New caps, reconfiguring");
- gst_caps_unref (current_caps);
- if (self->mode == GST_DECKLINK_MODE_AUTO) {
- return TRUE;
- } else {
- return FALSE;
- }
- } else {
- gst_caps_unref (current_caps);
- return TRUE;
- }
+ g_mutex_lock (&self->input->lock);
+ if (self->input->video_enabled) {
+ g_mutex_unlock (&self->input->lock);
+ return TRUE;
}
-
- if (!gst_video_info_from_caps (&self->info, caps))
- return FALSE;
+ g_mutex_unlock (&self->input->lock);
if (self->input->config && self->connection != GST_DECKLINK_CONNECTION_AUTO) {
ret = self->input->config->SetInt (bmdDeckLinkConfigVideoInputConnection,
@@ -672,32 +652,6 @@ gst_decklink_video_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
return TRUE;
}
-static GstCaps *
-gst_decklink_video_src_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
-{
- GstDecklinkVideoSrc *self = GST_DECKLINK_VIDEO_SRC_CAST (bsrc);
- GstCaps *mode_caps, *caps;
- BMDPixelFormat format;
- GstDecklinkModeEnum mode;
-
- g_mutex_lock (&self->lock);
- mode = self->caps_mode;
- format = self->caps_format;
- g_mutex_unlock (&self->lock);
-
- mode_caps = gst_decklink_mode_get_caps (mode, format, TRUE);
-
- if (filter) {
- caps =
- gst_caps_intersect_full (filter, mode_caps, GST_CAPS_INTERSECT_FIRST);
- gst_caps_unref (mode_caps);
- } else {
- caps = mode_caps;
- }
-
- return caps;
-}
-
static void
gst_decklink_video_src_update_time_mapping (GstDecklinkVideoSrc * self,
GstClockTime capture_time, GstClockTime stream_time)
@@ -1207,6 +1161,10 @@ gst_decklink_video_src_create (GstPushSrc * bsrc, GstBuffer ** buffer)
static GstStaticCaps hardware_reference =
GST_STATIC_CAPS ("timestamp/x-decklink-hardware");
+ if (!gst_decklink_video_src_start (self)) {
+ return GST_FLOW_NOT_NEGOTIATED;
+ }
+
g_mutex_lock (&self->lock);
retry:
while (gst_queue_array_is_empty (self->current_frames) && !self->flushing) {
@@ -1252,8 +1210,13 @@ retry:
// If we're not flushing, we should have a valid frame from the queue
g_assert (f.frame != NULL);
+ if (!gst_pad_has_current_caps (GST_BASE_SRC_PAD (self))) {
+ caps_changed = TRUE;
+ }
+
if (self->caps_mode != f.mode) {
- if (self->mode == GST_DECKLINK_MODE_AUTO) {
+ if (self->mode == GST_DECKLINK_MODE_AUTO
+ || !gst_pad_has_current_caps (GST_BASE_SRC_PAD (self))) {
GST_DEBUG_OBJECT (self, "Mode changed from %d to %d", self->caps_mode,
f.mode);
caps_changed = TRUE;
@@ -1268,7 +1231,8 @@ retry:
}
}
if (self->caps_format != f.format) {
- if (self->video_format == GST_DECKLINK_VIDEO_FORMAT_AUTO) {
+ if (self->video_format == GST_DECKLINK_VIDEO_FORMAT_AUTO
+ || !gst_pad_has_current_caps (GST_BASE_SRC_PAD (self))) {
GST_DEBUG_OBJECT (self, "Format changed from %d to %d", self->caps_format,
f.format);
caps_changed = TRUE;