summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2011-09-26 15:42:14 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2011-09-26 15:42:14 +0200
commit61ffd7cb42b072a3fde7e262a61589e0992c568f (patch)
tree0098353b6d4f52aa2fa430de3b498a08badcdfef
parent11e375486e07cfa0686a97b5cf6110909b3a828c (diff)
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.
-rw-r--r--gst-libs/gst/audio/gstaudioencoder.c54
1 files changed, 51 insertions, 3 deletions
diff --git a/gst-libs/gst/audio/gstaudioencoder.c b/gst-libs/gst/audio/gstaudioencoder.c
index 9a3d75c0f..c5c65247a 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");