decodebin3: Ensure we get a collection for parsed inputs

When we are dealing with parsed inputs (i.e. using identity), we need to ensure
that we have a valid stream collection (and therefore DBCollection) before
anything flows dowsntream.

In those cases, we hold onto those events until we get such a collection.

Fixes #3356

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7002>
This commit is contained in:
Edward Hervey 2024-04-29 11:26:48 +02:00 committed by Backport Bot
parent 230d0bf978
commit 175a3d17ba

View file

@ -372,6 +372,10 @@ struct _DecodebinInput
/* TEMPORARY HACK for knowing if upstream is already parsed and identity can /* TEMPORARY HACK for knowing if upstream is already parsed and identity can
* be avoided */ * be avoided */
gboolean input_is_parsed; gboolean input_is_parsed;
/* List of events that need to be pushed once we get the first
* GST_EVENT_STREAM_COLLECTION */
GList *events_waiting_for_collection;
}; };
/* Streams that come from parsebin or identity */ /* Streams that come from parsebin or identity */
@ -1891,6 +1895,10 @@ gst_decodebin_input_reset (DecodebinInput * input)
if (input->collection) if (input->collection)
gst_clear_object (&input->collection); gst_clear_object (&input->collection);
g_list_free_full (input->events_waiting_for_collection,
(GDestroyNotify) gst_event_unref);
input->events_waiting_for_collection = NULL;
input->group_id = GST_GROUP_ID_INVALID; input->group_id = GST_GROUP_ID_INVALID;
} }
@ -2096,6 +2104,15 @@ sink_event_function (GstPad * sinkpad, GstDecodebin3 * dbin, GstEvent * event)
/* If we are waiting to create an identity passthrough, do it now */ /* If we are waiting to create an identity passthrough, do it now */
if (!input->parsebin && !input->identity) if (!input->parsebin && !input->identity)
gst_decodebin_input_setup_identity (input); gst_decodebin_input_setup_identity (input);
/* Drain all pending events */
if (input->events_waiting_for_collection) {
GList *tmp;
for (tmp = input->events_waiting_for_collection; tmp; tmp = tmp->next)
gst_pad_event_default (sinkpad, GST_OBJECT (dbin), tmp->data);
g_list_free (input->events_waiting_for_collection);
input->events_waiting_for_collection = NULL;
}
break; break;
} }
case GST_EVENT_CAPS: case GST_EVENT_CAPS:
@ -2165,6 +2182,16 @@ sink_event_function (GstPad * sinkpad, GstDecodebin3 * dbin, GstEvent * event)
break; break;
} }
/* For parsed inputs, if we are waiting for a collection event, store them for
* now */
if (!input->collection && input->input_is_parsed) {
GST_DEBUG_OBJECT (sinkpad,
"Postponing event until we get a stream collection");
input->events_waiting_for_collection =
g_list_append (input->events_waiting_for_collection, event);
return TRUE;
}
/* Chain to parent function */ /* Chain to parent function */
return gst_pad_event_default (sinkpad, GST_OBJECT (dbin), event); return gst_pad_event_default (sinkpad, GST_OBJECT (dbin), event);
} }