From 3db585b2d90e88a35323b0fe0b96d3ea26044afb Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 15 Sep 2006 09:49:14 +0000 Subject: [PATCH] libs/gst/base/gstbasesink.c: Make sure that our internal state is correct when we commit our state asynchronously. Th... Original commit message from CVS: * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_wait_preroll), (gst_base_sink_do_sync), (gst_base_sink_preroll_object): Make sure that our internal state is correct when we commit our state asynchronously. This solves a race where a state change to PLAYING could cause the sink to remain blocked in preroll in some situations. --- ChangeLog | 9 +++++++++ libs/gst/base/gstbasesink.c | 25 ++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 42f3862cbf..beea887556 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-09-15 Wim Taymans + + * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), + (gst_base_sink_wait_preroll), (gst_base_sink_do_sync), + (gst_base_sink_preroll_object): + Make sure that our internal state is correct when we commit our state + asynchronously. This solves a race where a state change to PLAYING + could cause the sink to remain blocked in preroll in some situations. + 2006-09-15 Wim Taymans * tools/gst-inspect.c: (print_element_properties_info), diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index 01fdf4a45d..f473834f23 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -747,6 +747,9 @@ gst_base_sink_commit_state (GstBaseSink * basesink) gboolean post_paused = FALSE; gboolean post_playing = FALSE; + /* we are certainly not playing async anymore now */ + basesink->playing_async = FALSE; + GST_OBJECT_LOCK (basesink); current = GST_STATE (basesink); next = GST_STATE_NEXT (basesink); @@ -820,7 +823,25 @@ gst_base_sink_commit_state (GstBaseSink * basesink) nothing_pending: { - GST_DEBUG_OBJECT (basesink, "nothing to commit"); + /* Depending on the state, set our vars. We get in this situation when the + * state change function got a change to update the state vars before the + * streaming thread did. This is fine but we need to make sure that we + * update the need_preroll var since it was TRUE when we got here and might + * become FALSE if we got to PLAYING. */ + GST_DEBUG_OBJECT (basesink, "nothing to commit, now in %s", + gst_element_state_get_name (current)); + switch (current) { + case GST_STATE_PLAYING: + basesink->need_preroll = FALSE; + break; + case GST_STATE_PAUSED: + basesink->need_preroll = TRUE; + break; + default: + basesink->need_preroll = FALSE; + basesink->flushing = TRUE; + break; + } GST_OBJECT_UNLOCK (basesink); return TRUE; } @@ -1143,7 +1164,6 @@ again: GST_DEBUG_OBJECT (basesink, "prerolling object %p", obj); if (G_LIKELY (basesink->playing_async)) { - basesink->playing_async = FALSE; /* commit state */ if (G_UNLIKELY (!gst_base_sink_commit_state (basesink))) goto stopping; @@ -1615,7 +1635,6 @@ gst_base_sink_preroll_object (GstBaseSink * basesink, GstPad * pad, /* commit state */ if (G_LIKELY (basesink->playing_async)) { - basesink->playing_async = FALSE; if (G_UNLIKELY (!gst_base_sink_commit_state (basesink))) goto stopping; }