GstClockTime tolerance;
gboolean plc;
+ /* pending serialized sink events, will be sent from finish_frame() */
+ GList *pending_events;
};
}
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);
buf ? GST_BUFFER_SIZE (buf) : -1,
buf ? GST_BUFFER_SIZE (buf) / ctx->info.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->info.bpf)) {
if (GST_BUFFER_SIZE (buf) % ctx->info.bpf)
case GST_EVENT_FLUSH_STOP:
/* prepare for fresh start */
gst_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:
if (!handled)
handled = gst_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");