Skip to content
Snippets Groups Projects
Commit 4fe51789 authored by Tim-Philipp Müller's avatar Tim-Philipp Müller :tropical_fish:
Browse files

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.
parent 5a5a1f0d
No related branches found
No related tags found
No related merge requests found
......@@ -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;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment