mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +00:00
base: audioencoder: Keep serialize event behind buffers
If a serialized event arrives behind a buffer, it should not be send before it. This fixes the pending event handling so that only early pending events, the one that arrrived or was generated while the adapter was empty get send before pushing buffer. All other events are not pushed after. This issue lead the latency tracer to think our audio encoder did not have any latency. This was testing with opusenc in a live pipeline. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1266>
This commit is contained in:
parent
e1c0628bb9
commit
6bd1f2753a
1 changed files with 50 additions and 10 deletions
|
@ -171,6 +171,7 @@ typedef struct _GstAudioEncoderContext
|
|||
/* MT-protected (with LOCK) */
|
||||
GstClockTime min_latency;
|
||||
GstClockTime max_latency;
|
||||
gboolean negotiated;
|
||||
|
||||
GList *headers;
|
||||
gboolean new_headers;
|
||||
|
@ -239,6 +240,11 @@ struct _GstAudioEncoderPrivate
|
|||
|
||||
/* 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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -499,8 +505,11 @@ gst_audio_encoder_reset (GstAudioEncoder * enc, gboolean full)
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -597,11 +606,31 @@ gst_audio_encoder_push_event (GstAudioEncoder * enc, GstEvent * event)
|
|||
return gst_pad_push_event (enc->srcpad, event);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -795,9 +824,9 @@ gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf,
|
|||
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 */
|
||||
|
@ -1013,6 +1042,10 @@ gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf,
|
|||
|
||||
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;
|
||||
|
@ -1578,8 +1611,8 @@ gst_audio_encoder_sink_event_default (GstAudioEncoder * enc, GstEvent * event)
|
|||
/* 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;
|
||||
|
@ -1696,8 +1729,13 @@ gst_audio_encoder_sink_event_default (GstAudioEncoder * enc, GstEvent * event)
|
|||
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;
|
||||
}
|
||||
|
@ -2732,10 +2770,10 @@ gst_audio_encoder_negotiate_default (GstAudioEncoder * enc)
|
|||
|
||||
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;) {
|
||||
|
@ -2814,6 +2852,8 @@ gst_audio_encoder_negotiate_unlocked (GstAudioEncoder * enc)
|
|||
if (G_LIKELY (klass->negotiate))
|
||||
ret = klass->negotiate (enc);
|
||||
|
||||
enc->priv->ctx.negotiated = TRUE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue