udpsrc: keep GCancellable fd around instead of re-creating it constantly
authorTim-Philipp Müller <tim@centricular.com>
Tue, 19 May 2015 17:13:16 +0000 (18:13 +0100)
committerTim-Philipp Müller <tim@centricular.com>
Wed, 27 May 2015 16:08:47 +0000 (17:08 +0100)
Otherwise we constantly create/close event file descriptors,
every single time we call g_socket_condition_timed_wait() or
g_socket_receive_message(), i.e. twice per packet received!
This was not particularly good for performance.

Also only create GCancellable on start-up.

gst/udp/gstudpsrc.c
gst/udp/gstudpsrc.h

index 9d205b8..8fdb868 100644 (file)
@@ -323,8 +323,6 @@ gst_udpsrc_init (GstUDPSrc * udpsrc)
   udpsrc->used_socket = UDP_DEFAULT_USED_SOCKET;
   udpsrc->reuse = UDP_DEFAULT_REUSE;
 
-  udpsrc->cancellable = g_cancellable_new ();
-
   /* configure basesrc to be a live source */
   gst_base_src_set_live (GST_BASE_SRC (udpsrc), TRUE);
   /* make basesrc output a segment in time */
@@ -362,10 +360,6 @@ gst_udpsrc_finalize (GObject * object)
     g_object_unref (udpsrc->used_socket);
   udpsrc->used_socket = NULL;
 
-  if (udpsrc->cancellable)
-    g_object_unref (udpsrc->cancellable);
-  udpsrc->cancellable = NULL;
-
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -501,6 +495,26 @@ gst_udpsrc_ensure_mem (GstUDPSrc * src)
   return TRUE;
 }
 
+static void
+gst_udpsrc_create_cancellable (GstUDPSrc * src)
+{
+  GPollFD pollfd;
+
+  src->cancellable = g_cancellable_new ();
+  src->made_cancel_fd = g_cancellable_make_pollfd (src->cancellable, &pollfd);
+}
+
+static void
+gst_udpsrc_free_cancellable (GstUDPSrc * src)
+{
+  if (src->made_cancel_fd) {
+    g_cancellable_release_fd (src->cancellable);
+    src->made_cancel_fd = FALSE;
+  }
+  g_object_unref (src->cancellable);
+  src->cancellable = NULL;
+}
+
 static GstFlowReturn
 gst_udpsrc_create (GstPushSrc * psrc, GstBuffer ** buf)
 {
@@ -898,6 +912,8 @@ gst_udpsrc_open (GstUDPSrc * src)
   GSocketAddress *bind_saddr;
   GError *err = NULL;
 
+  gst_udpsrc_create_cancellable (src);
+
   if (src->socket == NULL) {
     /* need to allocate a socket */
     GST_DEBUG_OBJECT (src, "allocating socket for %s:%d", src->address,
@@ -1139,8 +1155,9 @@ gst_udpsrc_unlock_stop (GstBaseSrc * bsrc)
   src = GST_UDPSRC (bsrc);
 
   GST_LOG_OBJECT (src, "No longer flushing");
-  g_object_unref (src->cancellable);
-  src->cancellable = g_cancellable_new ();
+
+  gst_udpsrc_free_cancellable (src);
+  gst_udpsrc_create_cancellable (src);
 
   return TRUE;
 }
@@ -1184,6 +1201,8 @@ gst_udpsrc_close (GstUDPSrc * src)
 
   gst_udpsrc_reset_memory_allocator (src);
 
+  gst_udpsrc_free_cancellable (src);
+
   return TRUE;
 }
 
index 48976a4..5d7e340 100644 (file)
@@ -66,10 +66,12 @@ struct _GstUDPSrc {
 
   /* our sockets */
   GSocket   *used_socket;
-  GCancellable *cancellable;
   GInetSocketAddress *addr;
   gboolean   external_socket;
 
+  gboolean   made_cancel_fd;
+  GCancellable *cancellable;
+
   /* memory management */
   GstAllocator *allocator;
   GstAllocationParams params;