updsrc: set udp buffer size forcibly
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>
Fri, 17 Aug 2018 12:05:04 +0000 (14:05 +0200)
committerNicolas Dufresne <nicolas.dufresne@collabora.com>
Fri, 17 Aug 2018 17:46:42 +0000 (13:46 -0400)
The udp buffer size is limited to a maximum of around 100K.
Some apps need to set the force bufsize for their own operation.
Use the SO_RCVBUFFORCE option in order to override the rmem_max limit
of linux kernel. Require user to have the CAP_NET_ADMIN privilege to
work.

Original patch from Kyungnam Bae <kyungnam.bae@lge.com>

https://bugzilla.gnome.org/show_bug.cgi?id=727067

gst/udp/gstudpsrc.c

index ee9bd44..53c8e48 100644 (file)
@@ -1406,26 +1406,48 @@ gst_udpsrc_open (GstUDPSrc * src)
 
   {
     gint val;
+    GError *opt_err = NULL;
+    gboolean force_rcvbuf = FALSE;
 
     if (src->buffer_size != 0) {
-      GError *opt_err = NULL;
-
       GST_INFO_OBJECT (src, "setting udp buffer of %d bytes", src->buffer_size);
       /* 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. */
       if (!g_socket_set_option (src->used_socket, SOL_SOCKET, SO_RCVBUF,
               src->buffer_size, &opt_err)) {
+        GST_INFO_OBJECT (src,
+            "Could not create a buffer of requested %d bytes (%s) try forcing",
+            src->buffer_size, opt_err->message);
+        g_clear_error (&opt_err);
+        force_rcvbuf = TRUE;
+      }
+    }
+
+    val = gst_udpsrc_get_rcvbuf (src);
+    if (val < src->buffer_size)
+      force_rcvbuf = TRUE;
+
+    if (force_rcvbuf) {
+      GST_INFO_OBJECT (src,
+          "forcibly setting udp buffer of %d bytes", src->buffer_size);
+
+      /* Will only work with CAP_NET_ADMIN privilege */
+      if (!g_socket_set_option (src->used_socket, SOL_SOCKET, SO_RCVBUFFORCE,
+              src->buffer_size, &opt_err)) {
         GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL),
-            ("Could not create a buffer of requested %d bytes: %s",
+            ("Could not create a buffer of requested %d bytes (%s). Need net.admin privilege?",
                 src->buffer_size, opt_err->message));
-        g_error_free (opt_err);
-        opt_err = NULL;
+        g_clear_error (&opt_err);
       }
     }
 
     val = gst_udpsrc_get_rcvbuf (src);
-    if (val)
+    if (val < src->buffer_size)
+      GST_WARNING_OBJECT (src,
+          "have udp buffer of %d bytes while %d were requested",
+          val, src->buffer_size);
+    else
       GST_INFO_OBJECT (src, "have udp buffer of %d bytes", val);
   }