diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2019-08-06 21:44:35 +0300 |
---|---|---|
committer | Mathieu Duponchelle <mduponchelle1@gmail.com> | 2019-08-06 19:05:38 +0000 |
commit | ab8bd0aa446e9c09fd5aa2bd802f451324610e22 (patch) | |
tree | cc3ca72acd009551f52f78e49c086b0f6452d0da /sys/decklink | |
parent | 8257159909c6b7b74eb2e468d74806ff000dff21 (diff) | |
download | gstreamer-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.cpp | 117 | ||||
-rw-r--r-- | sys/decklink/gstdecklinkvideosrc.cpp | 78 |
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; |