/* MT-protected (with LOCK) */
GstClockTime min_latency;
GstClockTime max_latency;
+ gboolean negotiated;
GList *headers;
gboolean new_headers;
/* pending serialized sink events, will be sent from finish_frame() */
GList *pending_events;
+
+ /* these are initial events or events that came in while there was nothing
+ * in the adapter. these events shall be sent after negotiation but before
+ * we push the following buffer. */
+ GList *early_pending_events;
};
enc->priv->tags_merge_mode = GST_TAG_MERGE_APPEND;
enc->priv->tags_changed = FALSE;
- g_list_foreach (enc->priv->pending_events, (GFunc) gst_event_unref, NULL);
- g_list_free (enc->priv->pending_events);
+ g_list_free_full (enc->priv->early_pending_events,
+ (GDestroyNotify) gst_event_unref);
+ enc->priv->early_pending_events = NULL;
+ g_list_free_full (enc->priv->pending_events,
+ (GDestroyNotify) gst_event_unref);
enc->priv->pending_events = NULL;
}
}
static inline void
+gst_audio_encoder_push_early_pending_events (GstAudioEncoder * enc)
+{
+ GstAudioEncoderPrivate *priv = enc->priv;
+
+ if (priv->early_pending_events) {
+ GList *pending_events, *l;
+
+ pending_events = priv->early_pending_events;
+ priv->early_pending_events = NULL;
+
+ GST_DEBUG_OBJECT (enc, "Pushing early pending events");
+ for (l = pending_events; l; l = l->next)
+ gst_audio_encoder_push_event (enc, l->data);
+ g_list_free (pending_events);
+ }
+}
+
+static inline void
gst_audio_encoder_push_pending_events (GstAudioEncoder * enc)
{
GstAudioEncoderPrivate *priv = enc->priv;
+ gst_audio_encoder_push_early_pending_events (enc);
+
if (priv->pending_events) {
GList *pending_events, *l;
if (G_LIKELY (buf))
priv->got_data = TRUE;
- gst_audio_encoder_push_pending_events (enc);
+ gst_audio_encoder_push_early_pending_events (enc);
- /* send after pending events, which likely includes segment event */
+ /* send after early pending events, which likely includes segment event */
gst_audio_encoder_check_and_push_pending_tags (enc);
/* remove corresponding samples from input */
ret = gst_pad_push (enc->srcpad, buf);
GST_LOG_OBJECT (enc, "buffer pushed: %s", gst_flow_get_name (ret));
+
+ /* Now push the events that followed after the buffer got into the
+ * adapter. */
+ gst_audio_encoder_push_pending_events (enc);
} else {
/* merely advance samples, most work for that already done above */
priv->samples += samples;
/* and follow along with segment */
enc->input_segment = seg;
- enc->priv->pending_events =
- g_list_append (enc->priv->pending_events, event);
+ enc->priv->early_pending_events =
+ g_list_append (enc->priv->early_pending_events, event);
GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
res = TRUE;
gst_pad_event_default (enc->sinkpad, GST_OBJECT_CAST (enc), event);
} else {
GST_AUDIO_ENCODER_STREAM_LOCK (enc);
- enc->priv->pending_events =
- g_list_append (enc->priv->pending_events, event);
+ if (gst_adapter_available (enc->priv->adapter) == 0) {
+ enc->priv->early_pending_events =
+ g_list_append (enc->priv->early_pending_events, event);
+ } else {
+ enc->priv->pending_events =
+ g_list_append (enc->priv->pending_events, event);
+ }
GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
res = TRUE;
}
GST_DEBUG_OBJECT (enc, "Setting srcpad caps %" GST_PTR_FORMAT, caps);
- if (enc->priv->pending_events) {
+ if (enc->priv->early_pending_events) {
GList **pending_events, *l;
- pending_events = &enc->priv->pending_events;
+ pending_events = &enc->priv->early_pending_events;
GST_DEBUG_OBJECT (enc, "Pushing pending events");
for (l = *pending_events; l;) {
if (G_LIKELY (klass->negotiate))
ret = klass->negotiate (enc);
+ enc->priv->ctx.negotiated = TRUE;
+
return ret;
}