diff options
author | Nicola Murino | 2019-04-28 08:42:45 +0200 |
---|---|---|
committer | Nicola Murino | 2019-04-28 08:42:45 +0200 |
commit | 587acd63eb78c398f6ca5c9c00dbfa5bde4aecb8 (patch) | |
tree | 5ce2c9d4a9f0f713c8c520ed896ad1cc0d4c07b3 | |
parent | e6e6e350354d814a27aa24968f10f3995a43fb6c (diff) | |
download | aur-587acd63eb78c398f6ca5c9c00dbfa5bde4aecb8.tar.gz |
Add patch to improve nicesrc gstreamer plugin
-rw-r--r-- | .SRCINFO | 4 | ||||
-rw-r--r-- | 0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch | 253 | ||||
-rw-r--r-- | PKGBUILD | 13 |
3 files changed, 266 insertions, 4 deletions
@@ -1,7 +1,7 @@ pkgbase = mingw-w64-libnice pkgdesc = An implementation of the IETF's draft ICE (for p2p UDP data streams) (mingw-w64) pkgver = 0.1.15 - pkgrel = 1 + pkgrel = 2 url = https://nice.freedesktop.org arch = any license = LGPL @@ -14,7 +14,9 @@ pkgbase = mingw-w64-libnice options = !buildflags options = staticlibs source = git+https://gitlab.freedesktop.org/libnice/libnice.git#commit=e25c3e5113c7b7002a78bcca2ecf058bbf7de6d4 + source = 0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch sha256sums = SKIP + sha256sums = 9413dc1b9b681b6e5c274db0267aa4c3bf88b360d0f58edf73f1bad365243f30 pkgname = mingw-w64-libnice diff --git a/0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch b/0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch new file mode 100644 index 000000000000..ee5206caf325 --- /dev/null +++ b/0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch @@ -0,0 +1,253 @@ +From e0583a05ddb65a3c9326266a769678aff82a009a Mon Sep 17 00:00:00 2001 +From: Alessandro Decina <alessandro.d@gmail.com> +Date: Tue, 13 Oct 2015 12:49:19 +1100 +Subject: [PATCH] nicesrc: spin the agent mainloop in a separate thread + +Don't run the mainloop from the srcpad task, since that can get blocked in the +pipeline and cause unnecessary STUN retrasmissions (at best) and completely +block the agent (at worst). +--- + gst/gstnicesrc.c | 158 +++++++++++++++++++++++++++-------------------- + gst/gstnicesrc.h | 4 +- + 2 files changed, 93 insertions(+), 69 deletions(-) + +diff --git a/gst/gstnicesrc.c b/gst/gstnicesrc.c +index 0d39c34..954323c 100644 +--- a/gst/gstnicesrc.c ++++ b/gst/gstnicesrc.c +@@ -48,6 +48,14 @@ GST_DEBUG_CATEGORY_STATIC (nicesrc_debug); + + #define BUFFER_SIZE (65536) + ++static gboolean ++gst_nice_src_start ( ++ GstBaseSrc *basesrc); ++ ++static gboolean ++gst_nice_src_stop ( ++ GstBaseSrc *basesrc); ++ + static GstFlowReturn + gst_nice_src_create ( + GstPushSrc *basesrc, +@@ -57,10 +65,6 @@ static gboolean + gst_nice_src_unlock ( + GstBaseSrc *basesrc); + +-static gboolean +-gst_nice_src_unlock_stop ( +- GstBaseSrc *basesrc); +- + static void + gst_nice_src_set_property ( + GObject *object, +@@ -116,8 +120,9 @@ gst_nice_src_class_init (GstNiceSrcClass *klass) + gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_nice_src_create); + + gstbasesrc_class = (GstBaseSrcClass *) klass; ++ gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_nice_src_start); ++ gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_nice_src_stop); + gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_nice_src_unlock); +- gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_nice_src_unlock_stop); + + gobject_class = (GObjectClass *) klass; + gobject_class->set_property = gst_nice_src_set_property; +@@ -179,9 +184,83 @@ gst_nice_src_init (GstNiceSrc *src) + src->component_id = 0; + src->mainctx = g_main_context_new (); + src->mainloop = g_main_loop_new (src->mainctx, FALSE); +- src->unlocked = FALSE; +- src->idle_source = NULL; + src->outbufs = g_queue_new (); ++ src->agent_io_thread = NULL; ++ g_cond_init (&src->outcond); ++} ++ ++static gpointer ++gst_nice_src_agent_io_thread (gpointer data) ++{ ++ GstNiceSrc *nicesrc = GST_NICE_SRC (data); ++ ++ GST_INFO_OBJECT (nicesrc, "starting agent io thread"); ++ g_main_loop_run (nicesrc->mainloop); ++ GST_INFO_OBJECT (nicesrc, "exiting agent io thread"); ++ ++ return NULL; ++} ++ ++static gboolean ++main_loop_running_cb (gpointer data) ++{ ++ GstNiceSrc *nicesrc = GST_NICE_SRC (data); ++ ++ GST_OBJECT_LOCK (nicesrc); ++ /* _start() and _stop() could both be waiting for the mainloop to start so we ++ * need to broadcast */ ++ g_cond_broadcast (&nicesrc->outcond); ++ GST_OBJECT_UNLOCK (nicesrc); ++ ++ return FALSE; ++} ++ ++static gboolean ++gst_nice_src_start (GstBaseSrc * basesrc) ++{ ++ GstNiceSrc *nicesrc = GST_NICE_SRC (basesrc); ++ GSource *source; ++ gchar *thread_name; ++ ++ GST_OBJECT_LOCK (nicesrc); ++ source = g_idle_source_new (); ++ g_source_set_callback (source, ++ (GSourceFunc) main_loop_running_cb, nicesrc, NULL); ++ g_source_attach (source, nicesrc->mainctx); ++ g_source_unref (source); ++ ++ thread_name = g_strdup_printf ("%s:agent_io", GST_OBJECT_NAME (nicesrc)); ++ nicesrc->agent_io_thread = g_thread_new (thread_name, gst_nice_src_agent_io_thread, nicesrc); ++ g_free (thread_name); ++ /* wait until the agent thread starts spinning the mainloop or _stop() is ++ * called */ ++ while (GST_BASE_SRC_IS_STARTING (basesrc) && ++ !g_main_loop_is_running (nicesrc->mainloop)) ++ g_cond_wait (&nicesrc->outcond, GST_OBJECT_GET_LOCK (nicesrc)); ++ GST_OBJECT_UNLOCK (nicesrc); ++ ++ return TRUE; ++} ++ ++static gboolean ++gst_nice_src_stop (GstBaseSrc * basesrc) ++{ ++ GstNiceSrc *nicesrc = GST_NICE_SRC (basesrc); ++ GThread *agent_io_thread = NULL; ++ ++ GST_OBJECT_LOCK (nicesrc); ++ /* here we wait for the agent thread created in _start() to be scheduled so ++ * that we don't risk calling _quit() first and then _run() on the mainloop */ ++ while (!g_main_loop_is_running (nicesrc->mainloop)) ++ g_cond_wait (&nicesrc->outcond, GST_OBJECT_GET_LOCK (nicesrc)); ++ g_main_loop_quit (nicesrc->mainloop); ++ agent_io_thread = nicesrc->agent_io_thread; ++ nicesrc->agent_io_thread = NULL; ++ GST_OBJECT_UNLOCK (nicesrc); ++ ++ g_thread_join (agent_io_thread); ++ ++ return TRUE; + } + + static void +@@ -207,62 +286,17 @@ gst_nice_src_read_callback (NiceAgent *agent, + #endif + GST_OBJECT_LOCK (nicesrc); + g_queue_push_tail (nicesrc->outbufs, buffer); +- g_main_loop_quit (nicesrc->mainloop); ++ g_cond_signal (&nicesrc->outcond); + GST_OBJECT_UNLOCK (nicesrc); + } + +-static gboolean +-gst_nice_src_unlock_idler (gpointer data) +-{ +- GstNiceSrc *nicesrc = GST_NICE_SRC (data); +- +- GST_OBJECT_LOCK (nicesrc); +- if (nicesrc->unlocked) +- g_main_loop_quit (nicesrc->mainloop); +- +- if (nicesrc->idle_source) { +- g_source_destroy (nicesrc->idle_source); +- g_source_unref (nicesrc->idle_source); +- nicesrc->idle_source = NULL; +- } +- GST_OBJECT_UNLOCK (nicesrc); +- +- return FALSE; +-} +- + static gboolean + gst_nice_src_unlock (GstBaseSrc *src) + { + GstNiceSrc *nicesrc = GST_NICE_SRC (src); + + GST_OBJECT_LOCK (src); +- nicesrc->unlocked = TRUE; +- +- g_main_loop_quit (nicesrc->mainloop); +- +- if (!nicesrc->idle_source) { +- nicesrc->idle_source = g_idle_source_new (); +- g_source_set_priority (nicesrc->idle_source, G_PRIORITY_HIGH); +- g_source_set_callback (nicesrc->idle_source, gst_nice_src_unlock_idler, src, NULL); +- g_source_attach (nicesrc->idle_source, g_main_loop_get_context (nicesrc->mainloop)); +- } +- GST_OBJECT_UNLOCK (src); +- +- return TRUE; +-} +- +-static gboolean +-gst_nice_src_unlock_stop (GstBaseSrc *src) +-{ +- GstNiceSrc *nicesrc = GST_NICE_SRC (src); +- +- GST_OBJECT_LOCK (src); +- nicesrc->unlocked = FALSE; +- if (nicesrc->idle_source) { +- g_source_destroy (nicesrc->idle_source); +- g_source_unref(nicesrc->idle_source); +- } +- nicesrc->idle_source = NULL; ++ g_cond_signal (&nicesrc->outcond); + GST_OBJECT_UNLOCK (src); + + return TRUE; +@@ -278,19 +312,8 @@ gst_nice_src_create ( + GST_LOG_OBJECT (nicesrc, "create called"); + + GST_OBJECT_LOCK (basesrc); +- if (nicesrc->unlocked) { +- GST_OBJECT_UNLOCK (basesrc); +-#if GST_CHECK_VERSION (1,0,0) +- return GST_FLOW_FLUSHING; +-#else +- return GST_FLOW_WRONG_STATE; +-#endif +- } +- if (g_queue_is_empty (nicesrc->outbufs)) { +- GST_OBJECT_UNLOCK (basesrc); +- g_main_loop_run (nicesrc->mainloop); +- GST_OBJECT_LOCK (basesrc); +- } ++ if (g_queue_is_empty (nicesrc->outbufs)) ++ g_cond_wait (&nicesrc->outcond, GST_OBJECT_GET_LOCK (nicesrc)); + + *buffer = g_queue_pop_head (nicesrc->outbufs); + GST_OBJECT_UNLOCK (basesrc); +@@ -330,6 +353,7 @@ gst_nice_src_dispose (GObject *object) + g_queue_free_full (src->outbufs, (GDestroyNotify) gst_buffer_unref); + } + src->outbufs = NULL; ++ g_cond_clear (&src->outcond); + + G_OBJECT_CLASS (gst_nice_src_parent_class)->dispose (object); + } +diff --git a/gst/gstnicesrc.h b/gst/gstnicesrc.h +index 5d3f554..2d9f674 100644 +--- a/gst/gstnicesrc.h ++++ b/gst/gstnicesrc.h +@@ -68,8 +68,8 @@ struct _GstNiceSrc + GMainContext *mainctx; + GMainLoop *mainloop; + GQueue *outbufs; +- gboolean unlocked; +- GSource *idle_source; ++ GCond outcond; ++ GThread *agent_io_thread; + }; + + typedef struct _GstNiceSrcClass GstNiceSrcClass; +-- +2.20.1 + @@ -1,7 +1,7 @@ # Maintainer: drakkan <nicola.murino at gmail dot com> pkgname=mingw-w64-libnice pkgver=0.1.15 -pkgrel=1 +pkgrel=2 pkgdesc="An implementation of the IETF's draft ICE (for p2p UDP data streams) (mingw-w64)" arch=(any) url="https://nice.freedesktop.org" @@ -11,11 +11,18 @@ depends=('mingw-w64-glib2' 'mingw-w64-gnutls') options=('!strip' '!buildflags' 'staticlibs') _commit=e25c3e5113c7b7002a78bcca2ecf058bbf7de6d4 # tags/0.1.15^0 -source=("git+https://gitlab.freedesktop.org/libnice/libnice.git#commit=$_commit") -sha256sums=('SKIP') +source=("git+https://gitlab.freedesktop.org/libnice/libnice.git#commit=$_commit" + "0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch") +sha256sums=('SKIP' + '9413dc1b9b681b6e5c274db0267aa4c3bf88b360d0f58edf73f1bad365243f30') _architectures="i686-w64-mingw32 x86_64-w64-mingw32" +prepare() { + cd "${srcdir}/libnice" + patch -Np1 -i "$srcdir/0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch" +} + build() { cd "${srcdir}/libnice" for _arch in $_architectures; do |