From 61ffd7cb42b072a3fde7e262a61589e0992c568f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 26 Sep 2011 15:42:14 +0200 Subject: [PATCH] audioencoder: Delay sending of serialized events to finish_frame() This makes sure that the caps are already set before any serialized events are sent downstream. --- gst-libs/gst/audio/gstaudioencoder.c | 54 ++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/audio/gstaudioencoder.c b/gst-libs/gst/audio/gstaudioencoder.c index 9a3d75c..c5c6524 100644 --- a/gst-libs/gst/audio/gstaudioencoder.c +++ b/gst-libs/gst/audio/gstaudioencoder.c @@ -243,6 +243,8 @@ struct _GstAudioEncoderPrivate /* pending tags */ GstTagList *tags; + /* pending serialized sink events, will be sent from finish_frame() */ + GList *pending_events; }; static void gst_audio_encoder_finalize (GObject * object); @@ -394,6 +396,10 @@ gst_audio_encoder_reset (GstAudioEncoder * enc, gboolean full) if (enc->priv->tags) gst_tag_list_free (enc->priv->tags); enc->priv->tags = NULL; + + g_list_foreach (enc->priv->pending_events, (GFunc) gst_event_unref, NULL); + g_list_free (enc->priv->pending_events); + enc->priv->pending_events = NULL; } gst_segment_init (&enc->segment, GST_FORMAT_TIME); @@ -485,6 +491,19 @@ gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf, /* mark subclass still alive and providing */ priv->got_data = TRUE; + if (priv->pending_events) { + GList *pending_events, *l; + GST_OBJECT_LOCK (enc); + pending_events = priv->pending_events; + priv->pending_events = NULL; + GST_OBJECT_UNLOCK (enc); + + GST_DEBUG_OBJECT (enc, "Pushing pending events"); + for (l = priv->pending_events; l; l = l->next) + gst_pad_push_event (enc->srcpad, l->data); + g_list_free (pending_events); + } + /* remove corresponding samples from input */ if (samples < 0) samples = (enc->priv->offset / ctx->info.bpf); @@ -1192,6 +1211,13 @@ gst_audio_encoder_sink_eventfunc (GstAudioEncoder * enc, GstEvent * event) klass->flush (enc); /* and get (re)set for the sequel */ gst_audio_encoder_reset (enc, FALSE); + + GST_OBJECT_LOCK (enc); + g_list_foreach (enc->priv->pending_events, (GFunc) gst_event_unref, NULL); + g_list_free (enc->priv->pending_events); + enc->priv->pending_events = NULL; + GST_OBJECT_UNLOCK (enc); + break; case GST_EVENT_EOS: @@ -1209,7 +1235,10 @@ gst_audio_encoder_sink_eventfunc (GstAudioEncoder * enc, GstEvent * event) gst_tag_list_remove_tag (tags, GST_TAG_AUDIO_CODEC); event = gst_event_new_tag (tags); - gst_pad_push_event (enc->srcpad, event); + GST_OBJECT_LOCK (enc); + enc->priv->pending_events = + g_list_append (enc->priv->pending_events, event); + GST_OBJECT_UNLOCK (enc); handled = TRUE; break; } @@ -1241,8 +1270,27 @@ gst_audio_encoder_sink_event (GstPad * pad, GstEvent * event) if (!handled) handled = gst_audio_encoder_sink_eventfunc (enc, 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 (enc); + enc->priv->pending_events = + g_list_append (enc->priv->pending_events, event); + GST_OBJECT_UNLOCK (enc); + ret = TRUE; + } + } GST_DEBUG_OBJECT (enc, "event handled"); -- 2.7.4