Commit 09ca2ec9 authored by Wim Taymans's avatar Wim Taymans
Browse files

gst-libs/gst/audio/: Add flushing mode to the ringbuffer so that it in all...

gst-libs/gst/audio/: Add flushing mode to the ringbuffer so that it in all cases does not try to handle more audio. T...

Original commit message from CVS:
* gst-libs/gst/audio/gstbaseaudiosink.c:
(gst_base_audio_sink_event), (gst_base_audio_sink_get_offset),
(gst_base_audio_sink_render):
* gst-libs/gst/audio/gstringbuffer.c:
(gst_ring_buffer_open_device), (gst_ring_buffer_close_device),
(gst_ring_buffer_set_flushing), (gst_ring_buffer_start),
(gst_ring_buffer_pause_unlocked), (gst_ring_buffer_pause),
(gst_ring_buffer_stop), (wait_segment), (gst_ring_buffer_commit),
(gst_ring_buffer_read):
* gst-libs/gst/audio/gstringbuffer.h:
Add flushing mode to the ringbuffer so that it in all cases does
not try to handle more audio. This makes sure it does not try to
block anymore when flushing and fixes a livelock.
parent c79b8321
2005-10-31 Wim Taymans <wim@fluendo.com>
* gst-libs/gst/audio/gstbaseaudiosink.c:
(gst_base_audio_sink_event), (gst_base_audio_sink_get_offset),
(gst_base_audio_sink_render):
* gst-libs/gst/audio/gstringbuffer.c:
(gst_ring_buffer_open_device), (gst_ring_buffer_close_device),
(gst_ring_buffer_set_flushing), (gst_ring_buffer_start),
(gst_ring_buffer_pause_unlocked), (gst_ring_buffer_pause),
(gst_ring_buffer_stop), (wait_segment), (gst_ring_buffer_commit),
(gst_ring_buffer_read):
* gst-libs/gst/audio/gstringbuffer.h:
Add flushing mode to the ringbuffer so that it in all cases does
not try to handle more audio. This makes sure it does not try to
block anymore when flushing and fixes a livelock.
2005-10-29 Tim-Philipp Müller <tim at centricular dot net>
 
* ext/ogg/gstoggdemux.c: (gst_ogg_pad_query_convert),
......
......@@ -297,13 +297,12 @@ gst_base_audio_sink_event (GstBaseSink * bsink, GstEvent * event)
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_START:
gst_ring_buffer_pause (sink->ringbuffer);
gst_ring_buffer_clear_all (sink->ringbuffer);
gst_ring_buffer_set_flushing (sink->ringbuffer, TRUE);
break;
case GST_EVENT_FLUSH_STOP:
/* always resync on sample after a flush */
sink->next_sample = -1;
gst_ring_buffer_clear_all (sink->ringbuffer);
gst_ring_buffer_set_flushing (sink->ringbuffer, FALSE);
break;
case GST_EVENT_EOS:
gst_ring_buffer_start (sink->ringbuffer);
......
......@@ -31,6 +31,8 @@ static void gst_ring_buffer_init (GstRingBuffer * ringbuffer);
static void gst_ring_buffer_dispose (GObject * object);
static void gst_ring_buffer_finalize (GObject * object);
static gboolean gst_ring_buffer_pause_unlocked (GstRingBuffer * buf);
static GstObjectClass *parent_class = NULL;
/* ringbuffer abstract base class */
......@@ -608,6 +610,28 @@ gst_ring_buffer_is_acquired (GstRingBuffer * buf)
return res;
}
/**
* gst_ring_buffer_set_flushing:
* @buf: the #GstRingBuffer to flush
*
* Set the ringbuffer to flushing mode or normal mode.
*
* MT safe.
*/
void
gst_ring_buffer_set_flushing (GstRingBuffer * buf, gboolean flushing)
{
GST_LOCK (buf);
buf->flushing = flushing;
gst_ring_buffer_clear_all (buf);
if (flushing) {
gst_ring_buffer_pause_unlocked (buf);
}
GST_UNLOCK (buf);
}
/**
* gst_ring_buffer_start:
......@@ -631,6 +655,9 @@ gst_ring_buffer_start (GstRingBuffer * buf)
GST_DEBUG_OBJECT (buf, "starting ringbuffer");
GST_LOCK (buf);
if (buf->flushing)
goto flushing;
/* if stopped, set to started */
res = g_atomic_int_compare_and_exchange (&buf->state,
GST_RING_BUFFER_STATE_STOPPED, GST_RING_BUFFER_STATE_STARTED);
......@@ -669,29 +696,22 @@ done:
GST_UNLOCK (buf);
return res;
flushing:
{
GST_UNLOCK (buf);
return FALSE;
}
}
/**
* gst_ring_buffer_pause:
* @buf: the #GstRingBuffer to pause
*
* Pause processing samples from the ringbuffer.
*
* Returns: TRUE if the device could be paused, FALSE on error.
*
* MT safe.
*/
gboolean
gst_ring_buffer_pause (GstRingBuffer * buf)
static gboolean
gst_ring_buffer_pause_unlocked (GstRingBuffer * buf)
{
gboolean res = FALSE;
GstRingBufferClass *rclass;
g_return_val_if_fail (buf != NULL, FALSE);
GST_DEBUG_OBJECT (buf, "pausing ringbuffer");
GST_LOCK (buf);
/* if started, set to paused */
res = g_atomic_int_compare_and_exchange (&buf->state,
GST_RING_BUFFER_STATE_STARTED, GST_RING_BUFFER_STATE_PAUSED);
......@@ -718,9 +738,41 @@ gst_ring_buffer_pause (GstRingBuffer * buf)
}
done:
return res;
}
/**
* gst_ring_buffer_pause:
* @buf: the #GstRingBuffer to pause
*
* Pause processing samples from the ringbuffer.
*
* Returns: TRUE if the device could be paused, FALSE on error.
*
* MT safe.
*/
gboolean
gst_ring_buffer_pause (GstRingBuffer * buf)
{
gboolean res = FALSE;
g_return_val_if_fail (buf != NULL, FALSE);
GST_LOCK (buf);
if (buf->flushing)
goto flushing;
res = gst_ring_buffer_pause_unlocked (buf);
GST_UNLOCK (buf);
return res;
flushing:
{
GST_UNLOCK (buf);
return FALSE;
}
}
/**
......@@ -744,6 +796,9 @@ gst_ring_buffer_stop (GstRingBuffer * buf)
GST_DEBUG_OBJECT (buf, "stopping");
GST_LOCK (buf);
if (buf->flushing)
goto flushing;
/* if started, set to stopped */
res = g_atomic_int_compare_and_exchange (&buf->state,
GST_RING_BUFFER_STATE_STARTED, GST_RING_BUFFER_STATE_STOPPED);
......@@ -772,6 +827,12 @@ done:
GST_UNLOCK (buf);
return res;
flushing:
{
GST_UNLOCK (buf);
return FALSE;
}
}
/**
......@@ -916,12 +977,17 @@ wait_segment (GstRingBuffer * buf)
/* take lock first, then update our waiting flag */
GST_LOCK (buf);
if (buf->flushing)
goto flushing;
if (g_atomic_int_compare_and_exchange (&buf->waiting, 0, 1)) {
GST_DEBUG ("waiting..");
if (g_atomic_int_get (&buf->state) != GST_RING_BUFFER_STATE_STARTED)
goto not_started;
GST_RING_BUFFER_WAIT (buf);
if (buf->flushing)
goto flushing;
if (g_atomic_int_get (&buf->state) != GST_RING_BUFFER_STATE_STARTED)
goto not_started;
......@@ -937,6 +1003,12 @@ not_started:
GST_DEBUG ("stopped processing");
return FALSE;
}
flushing:
{
GST_UNLOCK (buf);
GST_DEBUG ("flushing");
return FALSE;
}
}
/**
......
......@@ -172,6 +172,8 @@ struct _GstRingBuffer {
GstRingBufferCallback callback;
gpointer cb_data;
gboolean flushing;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
};
......@@ -224,6 +226,9 @@ gboolean gst_ring_buffer_release (GstRingBuffer *buf);
gboolean gst_ring_buffer_is_acquired (GstRingBuffer *buf);
/* flushing */
void gst_ring_buffer_set_flushing (GstRingBuffer *buf, gboolean flushing);
/* playback/pause */
gboolean gst_ring_buffer_start (GstRingBuffer *buf);
gboolean gst_ring_buffer_pause (GstRingBuffer *buf);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment