summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.com>2018-02-01 19:25:49 +0000
committerTim-Philipp Müller <tim@centricular.com>2018-02-19 16:04:22 +0000
commit4fe51789578e92ca399de3dfaf8c5f5c808f59ae (patch)
treeb5f1f5ef9f88573839304daa481cd866a4879655
parent5a5a1f0dc695865c23650ec671382d10dbb18ac0 (diff)
appsrc: don't signal the GCond if no one is waiting on it
Performance optimisation: Keep track whenever the streaming thread or the application thread are waiting on the GCond for more space or new data, and only signal on the GCond if someone is actually waiting. Avoids unnecessary syscalls and thus context switches.
-rw-r--r--gst-libs/gst/app/gstappsrc.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/gst-libs/gst/app/gstappsrc.c b/gst-libs/gst/app/gstappsrc.c
index a619925c2..94ed6f7a9 100644
--- a/gst-libs/gst/app/gstappsrc.c
+++ b/gst-libs/gst/app/gstappsrc.c
@@ -101,11 +101,19 @@
#include "gstappsrc.h"
+typedef enum
+{
+ NOONE_WAITING,
+ STREAM_WAITING, /* streaming thread is waiting for application thread */
+ APP_WAITING, /* application thread is waiting for streaming thread */
+} GstAppSrcWaitStatus;
+
struct _GstAppSrcPrivate
{
GCond cond;
GMutex mutex;
GstQueueArray *queue;
+ GstAppSrcWaitStatus wait_status;
GstCaps *last_caps;
GstCaps *current_caps;
@@ -569,6 +577,7 @@ gst_app_src_init (GstAppSrc * appsrc)
g_mutex_init (&priv->mutex);
g_cond_init (&priv->cond);
priv->queue = gst_queue_array_new (16);
+ priv->wait_status = NOONE_WAITING;
priv->size = DEFAULT_PROP_SIZE;
priv->duration = DEFAULT_PROP_DURATION;
@@ -1233,7 +1242,8 @@ gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
priv->offset += buf_size;
/* signal that we removed an item */
- g_cond_broadcast (&priv->cond);
+ if (priv->wait_status == APP_WAITING)
+ g_cond_broadcast (&priv->cond);
/* see if we go lower than the empty-percent */
if (priv->min_percent && priv->max_bytes) {
@@ -1267,7 +1277,9 @@ gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
goto eos;
/* nothing to return, wait a while for new data or flushing. */
+ priv->wait_status = STREAM_WAITING;
g_cond_wait (&priv->cond, &priv->mutex);
+ priv->wait_status = NOONE_WAITING;
}
g_mutex_unlock (&priv->mutex);
return ret;
@@ -1828,7 +1840,9 @@ gst_app_src_push_internal (GstAppSrc * appsrc, GstBuffer * buffer,
GST_DEBUG_OBJECT (appsrc, "waiting for free space");
/* we are filled, wait until a buffer gets popped or when we
* flush. */
+ priv->wait_status = APP_WAITING;
g_cond_wait (&priv->cond, &priv->mutex);
+ priv->wait_status = NOONE_WAITING;
} else {
/* no need to wait for free space, we just pump more data into the
* queue hoping that the caller reacts to the enough-data signal and
@@ -1852,7 +1866,10 @@ gst_app_src_push_internal (GstAppSrc * appsrc, GstBuffer * buffer,
gst_queue_array_push_tail (priv->queue, buffer);
priv->queued_bytes += gst_buffer_get_size (buffer);
}
- g_cond_broadcast (&priv->cond);
+
+ if (priv->wait_status == STREAM_WAITING)
+ g_cond_broadcast (&priv->cond);
+
g_mutex_unlock (&priv->mutex);
return GST_FLOW_OK;