From 842a6c64c56cfd53064f2dc3d4f4ea81e2438457 Mon Sep 17 00:00:00 2001 From: Alessandro Decina Date: Tue, 24 Aug 2010 11:39:09 +0200 Subject: [PATCH] adder: Make sure FLUSH_STOP is always sent after a flushing seek. Send FLUSH_STOP right after forwarding the seek event upstream if necessary. This makes sure that adder->srcpad is not left flushing if seeking fails or if upstream is blocked. The same fix was already applied to videomixer in 49b2a946. --- gst/adder/gstadder.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/gst/adder/gstadder.c b/gst/adder/gstadder.c index 184421d..3d092e7 100644 --- a/gst/adder/gstadder.c +++ b/gst/adder/gstadder.c @@ -685,6 +685,14 @@ gst_adder_src_event (GstPad * pad, GstEvent * event) /* flushing seek, start flush downstream, the flush will be done * when all pads received a FLUSH_STOP. */ gst_pad_push_event (adder->srcpad, gst_event_new_flush_start ()); + + /* We can't send FLUSH_STOP here since upstream could start pushing data + * after we unlock adder->collect. + * We set flush_stop_pending to TRUE instead and send FLUSH_STOP after + * forwarding the seek upstream or from gst_adder_collected, + * whichever happens first. + */ + adder->flush_stop_pending = TRUE; } GST_DEBUG_OBJECT (adder, "handling seek event: %" GST_PTR_FORMAT, event); @@ -708,10 +716,6 @@ gst_adder_src_event (GstPad * pad, GstEvent * event) * have stopped so that the cookie gets properly updated. */ gst_collect_pads_set_flushing (adder->collect, TRUE); } - /* we might have a pending flush_stop event now. This event will either be - * sent by an upstream element when it completes the seek or we will push - * one in the collected callback ourself */ - adder->flush_stop_pending = flush; GST_OBJECT_UNLOCK (adder->collect); GST_DEBUG_OBJECT (adder, "forwarding seek event: %" GST_PTR_FORMAT, event); @@ -721,10 +725,11 @@ gst_adder_src_event (GstPad * pad, GstEvent * event) /* seek failed. maybe source is a live source. */ GST_DEBUG_OBJECT (adder, "seeking failed"); } - /* FIXME: ideally we would like to send a flush-stop event from here but - * collectpads does not have a method that allows us to do that. Instead - * we forward all flush-stop events we receive on the sinkpads. We might - * be sending too many flush-stop events. */ + if (g_atomic_int_compare_and_exchange (&adder->flush_stop_pending, + TRUE, FALSE)) { + GST_DEBUG_OBJECT (adder, "pending flush stop"); + gst_pad_push_event (adder->srcpad, gst_event_new_flush_stop ()); + } break; } case GST_EVENT_QOS: @@ -1055,9 +1060,10 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data) if (G_UNLIKELY (adder->func == NULL)) goto not_negotiated; - if (adder->flush_stop_pending) { + if (g_atomic_int_compare_and_exchange (&adder->flush_stop_pending, + TRUE, FALSE)) { + GST_DEBUG_OBJECT (adder, "pending flush stop"); gst_pad_push_event (adder->srcpad, gst_event_new_flush_stop ()); - adder->flush_stop_pending = FALSE; } /* get available bytes for reading, this can be 0 which could mean empty -- 2.7.4