diff --git a/ChangeLog b/ChangeLog index 252b47d851..b7a6363af9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2006-05-08 Wim Taymans + + Patch by: Philippe Rouquier + + * libs/gst/base/gstbasesink.c: (gst_base_sink_set_flushing), + (gst_base_sink_change_state): + call ::unlock before taking the PREROLL_LOCK so we can safely + handle elements that lock in ::render. + Fixes #340174. + 2006-05-08 Edward Hervey * autogen.sh: (CONFIGURE_DEF_OPT): diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index 30232f6b9e..f758bd0add 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -2023,23 +2023,27 @@ static gboolean gst_base_sink_set_flushing (GstBaseSink * basesink, GstPad * pad, gboolean flushing) { - GST_PAD_PREROLL_LOCK (pad); - basesink->flushing = flushing; + if (flushing) { GstBaseSinkClass *bclass; bclass = GST_BASE_SINK_GET_CLASS (basesink); + /* unlock any subclasses, we need to do this before grabbing the + * PREROLL_LOCK since we hold this lock before going into ::render. */ + if (bclass->unlock) + bclass->unlock (basesink); + } + + GST_PAD_PREROLL_LOCK (pad); + basesink->flushing = flushing; + if (flushing) { /* step 1, unblock clock sync (if any) or any other blocking thing */ basesink->need_preroll = TRUE; if (basesink->clock_id) { gst_clock_id_unschedule (basesink->clock_id); } - /* unlock any subclasses */ - if (bclass->unlock) - bclass->unlock (basesink); - /* flush out the data thread if it's locked in finish_preroll */ GST_DEBUG_OBJECT (basesink, "flushing out data thread, need preroll to TRUE"); @@ -2488,15 +2492,18 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: GST_DEBUG_OBJECT (basesink, "PLAYING to PAUSED"); + + /* we need to call ::unlock before locking PREROLL_LOCK + * since we lock it before going into ::render */ + if (bclass->unlock) + bclass->unlock (basesink); + GST_PAD_PREROLL_LOCK (basesink->sinkpad); basesink->need_preroll = TRUE; if (basesink->clock_id) { gst_clock_id_unschedule (basesink->clock_id); } - if (bclass->unlock) - bclass->unlock (basesink); - /* if we don't have a preroll buffer we need to wait for a preroll and * return ASYNC. */ if (gst_base_sink_is_prerolled (basesink)) {