From 63108730a59c270e5ddce051722755ca1596ef14 Mon Sep 17 00:00:00 2001 From: Jan Urbanski Date: Tue, 14 Apr 2009 17:04:06 +0200 Subject: [PATCH] multifdsink: add property to resend streamheaders Adds a new property in multifdsink, resend-streamheader. If this property is false, the multifdsink will not send the streamheader if there's already one set for a particular client. There are some formats in which every stream needs to start with a certain blob, but you can't inject this blob at leisure. If the producer wants to change the blob in question and sets in as the streamheader on the outgoing buffers' caps, new clients of multifdsink will get the new streamheader, but old clients will break, because they'll see the blob in the middle of the stream. The property is true by default, so existing code will not see any difference. Fixes #578118. --- gst/tcp/gstmultifdsink.c | 49 ++++++++++++++++++++++++++++++++-------- gst/tcp/gstmultifdsink.h | 2 ++ 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/gst/tcp/gstmultifdsink.c b/gst/tcp/gstmultifdsink.c index 60a2398d5f..22dc9cb80c 100644 --- a/gst/tcp/gstmultifdsink.c +++ b/gst/tcp/gstmultifdsink.c @@ -181,6 +181,8 @@ enum #define DEFAULT_QOS_DSCP -1 #define DEFAULT_HANDLE_READ TRUE +#define DEFAULT_RESEND_STREAMHEADER TRUE + enum { PROP_0, @@ -214,6 +216,8 @@ enum PROP_HANDLE_READ, + PROP_RESEND_STREAMHEADER, + PROP_LAST }; @@ -490,8 +494,8 @@ gst_multi_fd_sink_class_init (GstMultiFdSinkClass * klass) g_object_class_install_property (gobject_class, PROP_QOS_DSCP, g_param_spec_int ("qos-dscp", "QoS diff srv code point", "Quality of Service, differentiated services code point (-1 default)", - -1, 63, DEFAULT_QOS_DSCP, G_PARAM_READWRITE)); - + -1, 63, DEFAULT_QOS_DSCP, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstMultiFdSink::handle-read * @@ -502,7 +506,19 @@ gst_multi_fd_sink_class_init (GstMultiFdSinkClass * klass) g_object_class_install_property (gobject_class, PROP_HANDLE_READ, g_param_spec_boolean ("handle-read", "Handle Read", "Handle client reads and discard the data", - DEFAULT_HANDLE_READ, G_PARAM_READWRITE)); + DEFAULT_HANDLE_READ, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstMultiFdSink::resend-streamheader + * + * Resend the streamheaders to existing clients when they change. + * + * Since: 0.10.23 + */ + g_object_class_install_property (gobject_class, PROP_RESEND_STREAMHEADER, + g_param_spec_boolean ("resend-streamheader", "Resend streamheader", + "Resend the streamheader if it changes in the caps", + DEFAULT_RESEND_STREAMHEADER, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstMultiFdSink::add: @@ -695,6 +711,8 @@ gst_multi_fd_sink_init (GstMultiFdSink * this, GstMultiFdSinkClass * klass) this->qos_dscp = DEFAULT_QOS_DSCP; this->handle_read = DEFAULT_HANDLE_READ; + this->resend_streamheader = DEFAULT_RESEND_STREAMHEADER; + this->header_flags = 0; } @@ -1367,14 +1385,21 @@ gst_multi_fd_sink_client_queue_buffer (GstMultiFdSink * sink, send_streamheader = TRUE; } else { /* both old and new caps have streamheader set */ - sh1 = gst_structure_get_value (s, "streamheader"); - s = gst_caps_get_structure (caps, 0); - sh2 = gst_structure_get_value (s, "streamheader"); - if (gst_value_compare (sh1, sh2) != GST_VALUE_EQUAL) { + if (!sink->resend_streamheader) { GST_DEBUG_OBJECT (sink, - "[fd %5d] new streamheader different from old, sending", + "[fd %5d] asked to not resend the streamheader, not sending", client->fd.fd); - send_streamheader = TRUE; + send_streamheader = FALSE; + } else { + sh1 = gst_structure_get_value (s, "streamheader"); + s = gst_caps_get_structure (caps, 0); + sh2 = gst_structure_get_value (s, "streamheader"); + if (gst_value_compare (sh1, sh2) != GST_VALUE_EQUAL) { + GST_DEBUG_OBJECT (sink, + "[fd %5d] new streamheader different from old, sending", + client->fd.fd); + send_streamheader = TRUE; + } } } } @@ -2685,6 +2710,9 @@ gst_multi_fd_sink_set_property (GObject * object, guint prop_id, case PROP_HANDLE_READ: multifdsink->handle_read = g_value_get_boolean (value); break; + case PROP_RESEND_STREAMHEADER: + multifdsink->resend_streamheader = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -2767,6 +2795,9 @@ gst_multi_fd_sink_get_property (GObject * object, guint prop_id, GValue * value, case PROP_HANDLE_READ: g_value_set_boolean (value, multifdsink->handle_read); break; + case PROP_RESEND_STREAMHEADER: + g_value_set_boolean (value, multifdsink->resend_streamheader); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); diff --git a/gst/tcp/gstmultifdsink.h b/gst/tcp/gstmultifdsink.h index 7bad542b73..d2d9ce4e5b 100644 --- a/gst/tcp/gstmultifdsink.h +++ b/gst/tcp/gstmultifdsink.h @@ -235,6 +235,8 @@ struct _GstMultiFdSink { gint64 time_min; /* min time to queue */ gint buffers_min; /* min number of buffers to queue */ + gboolean resend_streamheader; /* resend streamheader if it changes */ + /* stats */ gint buffers_queued; /* number of queued buffers */ gint bytes_queued; /* number of queued bytes */