From 43c6d0c72afba986a3642e1bda825461c7a971a2 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 5 Jan 2011 12:04:03 +0100 Subject: [PATCH] multiudpsink: add buffer-size property Add buffer-size property to configure the kernel send buffer. --- gst/udp/gstmultiudpsink.c | 53 +++++++++++++++++++++++++++++++++++---- gst/udp/gstmultiudpsink.h | 1 + 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/gst/udp/gstmultiudpsink.c b/gst/udp/gstmultiudpsink.c index 8a24275225..78e491b2b6 100644 --- a/gst/udp/gstmultiudpsink.c +++ b/gst/udp/gstmultiudpsink.c @@ -80,6 +80,7 @@ enum #define DEFAULT_LOOP TRUE #define DEFAULT_QOS_DSCP -1 #define DEFAULT_SEND_DUPLICATES TRUE +#define DEFAULT_BUFFER_SIZE 0 enum { @@ -96,6 +97,7 @@ enum PROP_LOOP, PROP_QOS_DSCP, PROP_SEND_DUPLICATES, + PROP_BUFFER_SIZE, PROP_LAST }; @@ -347,6 +349,11 @@ gst_multiudpsink_class_init (GstMultiUDPSinkClass * klass) "multiple times as well", DEFAULT_SEND_DUPLICATES, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BUFFER_SIZE, + g_param_spec_int ("buffer-size", "Buffer Size", + "Size of the kernel send buffer in bytes, 0=default", 0, G_MAXINT, + DEFAULT_BUFFER_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gstelement_class->change_state = gst_multiudpsink_change_state; gstbasesink_class->render = gst_multiudpsink_render; @@ -773,6 +780,9 @@ gst_multiudpsink_set_property (GObject * object, guint prop_id, case PROP_SEND_DUPLICATES: udpsink->send_duplicates = g_value_get_boolean (value); break; + case PROP_BUFFER_SIZE: + udpsink->buffer_size = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -825,6 +835,9 @@ gst_multiudpsink_get_property (GObject * object, guint prop_id, GValue * value, case PROP_SEND_DUPLICATES: g_value_set_boolean (value, udpsink->send_duplicates); break; + case PROP_BUFFER_SIZE: + g_value_set_int (value, udpsink->buffer_size); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -899,6 +912,12 @@ gst_multiudpsink_init_send (GstMultiUDPSink * sink) guint bc_val; GList *clients; GstUDPClient *client; + int sndsize, ret; +#ifdef G_OS_WIN32 + gint len; +#else + guint len; +#endif if (sink->sockfd == -1) { GST_DEBUG_OBJECT (sink, "creating sockets"); @@ -914,11 +933,6 @@ gst_multiudpsink_init_send (GstMultiUDPSink * sink) sink->externalfd = FALSE; } else { struct sockaddr_storage myaddr; -#ifdef G_OS_WIN32 - gint len; -#else - guint len; -#endif GST_DEBUG_OBJECT (sink, "using configured socket"); /* we use the configured socket, try to get some info about it */ @@ -932,6 +946,35 @@ gst_multiudpsink_init_send (GstMultiUDPSink * sink) sink->externalfd = TRUE; } + len = sizeof (sndsize); + if (sink->buffer_size != 0) { + sndsize = sink->buffer_size; + + GST_DEBUG_OBJECT (sink, "setting udp buffer of %d bytes", sndsize); + /* set buffer size, Note that on Linux this is typically limited to a + * maximum of around 100K. Also a minimum of 128 bytes is required on + * Linux. */ + ret = + setsockopt (sink->sockfd, SOL_SOCKET, SO_SNDBUF, (void *) &sndsize, + len); + if (ret != 0) { + GST_ELEMENT_WARNING (sink, RESOURCE, SETTINGS, (NULL), + ("Could not create a buffer of requested %d bytes, %d: %s (%d)", + sndsize, ret, g_strerror (errno), errno)); + } + } + + /* read the value of the receive buffer. Note that on linux this returns 2x the + * value we set because the kernel allocates extra memory for metadata. + * The default on Linux is about 100K (which is about 50K without metadata) */ + ret = + getsockopt (sink->sockfd, SOL_SOCKET, SO_SNDBUF, (void *) &sndsize, &len); + if (ret == 0) + GST_DEBUG_OBJECT (sink, "have udp buffer of %d bytes", sndsize); + else + GST_DEBUG_OBJECT (sink, "could not get udp buffer size"); + + bc_val = 1; if (setsockopt (sink->sock, SOL_SOCKET, SO_BROADCAST, &bc_val, sizeof (bc_val)) < 0) diff --git a/gst/udp/gstmultiudpsink.h b/gst/udp/gstmultiudpsink.h index 6d4da77e95..c31dbad83a 100644 --- a/gst/udp/gstmultiudpsink.h +++ b/gst/udp/gstmultiudpsink.h @@ -80,6 +80,7 @@ struct _GstMultiUDPSink { guint16 ss_family; gboolean send_duplicates; + gint buffer_size; }; struct _GstMultiUDPSinkClass {