[gst-cvs] gstreamer: basesrc: fix race in PLAYING->PAUSED->PLAYING
Wim Taymans
wtay at kemper.freedesktop.org
Thu Oct 15 07:35:09 PDT 2009
Module: gstreamer
Branch: master
Commit: e9f2714ff946b3260439d981747b2159dcc4e00a
URL: http://cgit.freedesktop.org/gstreamer/gstreamer/commit/?id=e9f2714ff946b3260439d981747b2159dcc4e00a
Author: Wim Taymans <wim.taymans at collabora.co.uk>
Date: Thu Oct 15 16:30:36 2009 +0200
basesrc: fix race in PLAYING->PAUSED->PLAYING
When we quickly switch from PLAYING to PAUSED and back to PLAYING it's possible
in some cases that the task refuses to start, This is because when we go to
PAUSED, we unschedule the clock timeout, which could return UNSCHEDULED when
we're back to PLAYING, causing the task to PAUSE again with a wrong-state.
This patch checks if we are running when we return with an UNSCHEDULED return
value and if we are, try to create a new buffer.
Fixes #597550
---
libs/gst/base/gstbasesrc.c | 22 ++++++++++++++++------
1 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/libs/gst/base/gstbasesrc.c b/libs/gst/base/gstbasesrc.c
index 8c78ba9..e2fd520 100644
--- a/libs/gst/base/gstbasesrc.c
+++ b/libs/gst/base/gstbasesrc.c
@@ -1934,6 +1934,7 @@ gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
bclass = GST_BASE_SRC_GET_CLASS (src);
+again:
if (src->is_live) {
while (G_UNLIKELY (!src->live_running)) {
ret = gst_base_src_wait_playing (src);
@@ -2011,14 +2012,23 @@ gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
break;
case GST_CLOCK_UNSCHEDULED:
/* this case is triggered when we were waiting for the clock and
- * it got unlocked because we did a state change. We return
- * WRONG_STATE in this case to stop the dataflow also get rid of the
- * produced buffer. */
- GST_DEBUG_OBJECT (src,
- "clock was unscheduled (%d), returning WRONG_STATE", status);
+ * it got unlocked because we did a state change. In any case, get rid of
+ * the buffer. */
gst_buffer_unref (*buf);
*buf = NULL;
- ret = GST_FLOW_WRONG_STATE;
+ if (!src->live_running) {
+ /* We return WRONG_STATE when we are not running to stop the dataflow also
+ * get rid of the produced buffer. */
+ GST_DEBUG_OBJECT (src,
+ "clock was unscheduled (%d), returning WRONG_STATE", status);
+ ret = GST_FLOW_WRONG_STATE;
+ } else {
+ /* If we are running when this happens, we quickly switched between
+ * pause and playing. We try to produce a new buffer */
+ GST_DEBUG_OBJECT (src,
+ "clock was unscheduled (%d), but we are running", status);
+ goto again;
+ }
break;
default:
/* all other result values are unexpected and errors */
More information about the Gstreamer-commits
mailing list