From fc511eb45dbd549bd8bf001a1bc0b0f763b6d02f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 18 Aug 2011 09:17:04 +0200 Subject: [PATCH] baseaudiodecoder: Delay sending of serialized events to finish_frame() --- omx/gstbaseaudiodecoder.c | 50 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/omx/gstbaseaudiodecoder.c b/omx/gstbaseaudiodecoder.c index fb670dc..f67de7a 100644 --- a/omx/gstbaseaudiodecoder.c +++ b/omx/gstbaseaudiodecoder.c @@ -233,6 +233,9 @@ struct _GstBaseAudioDecoderPrivate /* context storage */ GstBaseAudioDecoderContext ctx; + + /* pending serialized sink events, will be sent from finish_frame() */ + GList *pending_events; }; @@ -400,6 +403,10 @@ gst_base_audio_decoder_reset (GstBaseAudioDecoder * dec, gboolean full) } gst_segment_init (&dec->segment, GST_FORMAT_TIME); + + g_list_foreach (dec->priv->pending_events, (GFunc) gst_event_unref, NULL); + g_list_free (dec->priv->pending_events); + dec->priv->pending_events = NULL; } g_queue_foreach (&dec->priv->frames, (GFunc) gst_buffer_unref, NULL); @@ -690,6 +697,20 @@ gst_base_audio_decoder_finish_frame (GstBaseAudioDecoder * dec, GstBuffer * buf, buf ? GST_BUFFER_SIZE (buf) : -1, buf ? GST_BUFFER_SIZE (buf) / ctx->state.bpf : -1, frames); + if (priv->pending_events) { + GList *pending_events, *l; + + GST_OBJECT_LOCK (dec); + pending_events = priv->pending_events; + priv->pending_events = NULL; + GST_OBJECT_UNLOCK (dec); + + GST_DEBUG_OBJECT (dec, "Pushing pending events"); + for (l = priv->pending_events; l; l = l->next) + gst_pad_push_event (dec->srcpad, l->data); + g_list_free (pending_events); + } + /* output shoud be whole number of sample frames */ if (G_LIKELY (buf && ctx->state.bpf)) { if (GST_BUFFER_SIZE (buf) % ctx->state.bpf) @@ -1358,6 +1379,12 @@ gst_base_audio_decoder_sink_eventfunc (GstBaseAudioDecoder * dec, case GST_EVENT_FLUSH_STOP: /* prepare for fresh start */ gst_base_audio_decoder_flush (dec, TRUE); + + GST_OBJECT_LOCK (dec); + g_list_foreach (dec->priv->pending_events, (GFunc) gst_event_unref, NULL); + g_list_free (dec->priv->pending_events); + dec->priv->pending_events = NULL; + GST_OBJECT_UNLOCK (dec); break; case GST_EVENT_EOS: @@ -1391,8 +1418,27 @@ gst_base_audio_decoder_sink_event (GstPad * pad, GstEvent * event) if (!handled) handled = gst_base_audio_decoder_sink_eventfunc (dec, event); - if (!handled) - ret = gst_pad_event_default (pad, event); + if (!handled) { + /* Forward non-serialized events and EOS/FLUSH_STOP immediately. + * For EOS this is required because no buffer or serialized event + * will come after EOS and nothing could trigger another + * _finish_frame() call. + * + * For FLUSH_STOP this is required because it is expected + * to be forwarded immediately and no buffers are queued anyway. + */ + if (!GST_EVENT_IS_SERIALIZED (event) + || GST_EVENT_TYPE (event) == GST_EVENT_EOS + || GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) { + ret = gst_pad_event_default (pad, event); + } else { + GST_OBJECT_LOCK (dec); + dec->priv->pending_events = + g_list_append (dec->priv->pending_events, event); + GST_OBJECT_UNLOCK (dec); + ret = TRUE; + } + } GST_DEBUG_OBJECT (dec, "event handled"); -- 2.7.4