diff --git a/subprojects/gst-plugins-bad/ext/srt/gstsrtsink.c b/subprojects/gst-plugins-bad/ext/srt/gstsrtsink.c index b2277a1314..287c1f3964 100644 --- a/subprojects/gst-plugins-bad/ext/srt/gstsrtsink.c +++ b/subprojects/gst-plugins-bad/ext/srt/gstsrtsink.c @@ -138,6 +138,7 @@ gst_srt_sink_finalize (GObject * object) static void gst_srt_sink_init (GstSRTSink * self) { + self->streamconfig_sent = FALSE; self->srtobject = gst_srt_object_new (GST_ELEMENT (self)); gst_srt_object_set_uri (self->srtobject, GST_SRT_DEFAULT_URI, NULL); } @@ -173,6 +174,36 @@ gst_srt_sink_stop (GstBaseSink * bsink) return TRUE; } +typedef struct +{ + GstBuffer *buf; + GstMapInfo *map_info; +} StreamheaderCheckContext; + +static gboolean +is_buffer_different (GstBuffer ** buffer, guint idx, gpointer data) +{ + StreamheaderCheckContext *ctx = (StreamheaderCheckContext *) data; + gboolean retval = FALSE; + g_return_val_if_fail (buffer != NULL, FALSE); + g_return_val_if_fail (GST_IS_BUFFER (*buffer), FALSE); + g_return_val_if_fail (ctx != NULL, FALSE); + g_return_val_if_fail (GST_IS_BUFFER (ctx->buf), FALSE); + g_return_val_if_fail (ctx->map_info != NULL, FALSE); + + if (*buffer == ctx->buf) + return FALSE; + + if (gst_buffer_get_size (*buffer) != gst_buffer_get_size (ctx->buf)) + return TRUE; + + if (gst_buffer_memcmp (*buffer, 0, ctx->map_info->data, ctx->map_info->size) + != 0) + retval = TRUE; + + return retval; +} + static GstFlowReturn gst_srt_sink_render (GstBaseSink * sink, GstBuffer * buffer) { @@ -180,21 +211,38 @@ gst_srt_sink_render (GstBaseSink * sink, GstBuffer * buffer) GstFlowReturn ret = GST_FLOW_OK; GstMapInfo info; GError *error = NULL; + StreamheaderCheckContext ctx = { 0 }; if (g_cancellable_is_cancelled (self->srtobject->cancellable)) { ret = GST_FLOW_FLUSHING; } - if (self->headers && GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_HEADER)) { - GST_DEBUG_OBJECT (self, "Have streamheaders," - " ignoring header %" GST_PTR_FORMAT, buffer); - return GST_FLOW_OK; + if (!self->streamconfig_sent && GST_BUFFER_FLAG_IS_SET (buffer, + GST_BUFFER_FLAG_HEADER)) { + + if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) { + GST_ELEMENT_ERROR (self, RESOURCE, READ, + ("Could not map the input stream"), (NULL)); + return GST_FLOW_ERROR; + } + ctx.map_info = &info; + ctx.buf = buffer; + + if (!gst_buffer_list_foreach (self->headers, is_buffer_different, &ctx)) { + GST_DEBUG_OBJECT (self, "Have streamheaders," + " ignoring header %" GST_PTR_FORMAT, buffer); + return GST_FLOW_OK; + } } - if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) { - GST_ELEMENT_ERROR (self, RESOURCE, READ, - ("Could not map the input stream"), (NULL)); - return GST_FLOW_ERROR; + self->streamconfig_sent = TRUE; + + if (ctx.map_info != &info) { + if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) { + GST_ELEMENT_ERROR (self, RESOURCE, READ, + ("Could not map the input stream"), (NULL)); + return GST_FLOW_ERROR; + } } if (gst_srt_object_write (self->srtobject, self->headers, &info, &error) < 0) { @@ -250,6 +298,7 @@ gst_srt_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) GST_DEBUG_OBJECT (self, "setcaps %" GST_PTR_FORMAT, caps); g_clear_pointer (&self->headers, gst_buffer_list_unref); + self->streamconfig_sent = FALSE; s = gst_caps_get_structure (caps, 0); streamheader = gst_structure_get_value (s, "streamheader"); diff --git a/subprojects/gst-plugins-bad/ext/srt/gstsrtsink.h b/subprojects/gst-plugins-bad/ext/srt/gstsrtsink.h index 68b3bdd96c..923594569a 100644 --- a/subprojects/gst-plugins-bad/ext/srt/gstsrtsink.h +++ b/subprojects/gst-plugins-bad/ext/srt/gstsrtsink.h @@ -48,6 +48,8 @@ struct _GstSRTSink { GstBufferList *headers; GstSRTObject *srtobject; + + gboolean streamconfig_sent; }; struct _GstSRTSinkClass {