From 9b4a022dee7351f1f1a5f9d6323253bc769aa556 Mon Sep 17 00:00:00 2001 From: Guillaume Desmottes Date: Fri, 17 Aug 2018 14:05:04 +0200 Subject: [PATCH] updsrc: set udp buffer size forcibly 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 https://bugzilla.gnome.org/show_bug.cgi?id=727067 --- gst/udp/gstudpsrc.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c index ee9bd44166..53c8e48347 100644 --- a/gst/udp/gstudpsrc.c +++ b/gst/udp/gstudpsrc.c @@ -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_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL), - ("Could not create a buffer of requested %d bytes: %s", - src->buffer_size, opt_err->message)); - g_error_free (opt_err); - opt_err = NULL; + 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) + 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). Need net.admin privilege?", + src->buffer_size, opt_err->message)); + g_clear_error (&opt_err); + } + } + + val = gst_udpsrc_get_rcvbuf (src); + 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); }