multiudpsink: add buffer-size property
authorWim Taymans <wim.taymans@collabora.co.uk>
Wed, 5 Jan 2011 11:04:03 +0000 (12:04 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 5 Jan 2011 11:05:15 +0000 (12:05 +0100)
Add buffer-size property to configure the kernel send buffer.

gst/udp/gstmultiudpsink.c
gst/udp/gstmultiudpsink.h

index 8a24275..78e491b 100644 (file)
@@ -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)
index 6d4da77..c31dbad 100644 (file)
@@ -80,6 +80,7 @@ struct _GstMultiUDPSink {
   guint16        ss_family;
 
   gboolean       send_duplicates;
+  gint           buffer_size;
 };
 
 struct _GstMultiUDPSinkClass {