mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 01:45:33 +00:00
decodebin3: Always ensure we end up with parsebin or identity
This fixes a regression introduced by 6c4f52ea20
There are cases where the input stream will be push-based, time-segment and not
have a collection nor caps. This means the event-based checks are not sufficient
to decide when/where to plug in a identity or parsebin to process the input.
For those corner cases we setup a buffer probe to ensure we always end up with
at least a parsebin
Fixes #3609
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7010>
This commit is contained in:
parent
00536ea232
commit
74dbbe0091
1 changed files with 46 additions and 0 deletions
|
@ -376,6 +376,9 @@ struct _DecodebinInput
|
||||||
/* List of events that need to be pushed once we get the first
|
/* List of events that need to be pushed once we get the first
|
||||||
* GST_EVENT_STREAM_COLLECTION */
|
* GST_EVENT_STREAM_COLLECTION */
|
||||||
GList *events_waiting_for_collection;
|
GList *events_waiting_for_collection;
|
||||||
|
|
||||||
|
/* input buffer probe for detecting whether input has caps or not */
|
||||||
|
gulong input_probe;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Streams that come from parsebin or identity */
|
/* Streams that come from parsebin or identity */
|
||||||
|
@ -1627,6 +1630,23 @@ no_parsebin:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstPadProbeReturn
|
||||||
|
input_pad_buffer_probe (GstPad * pad, GstPadProbeInfo * info,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
DecodebinInput *input = user_data;
|
||||||
|
|
||||||
|
INPUT_LOCK (input->dbin);
|
||||||
|
if (!input->parsebin && !input->identity) {
|
||||||
|
GST_DEBUG_OBJECT (pad, "Push-stream without caps, setting up identity");
|
||||||
|
gst_decodebin_input_ensure_parsebin (input);
|
||||||
|
}
|
||||||
|
input->input_probe = 0;
|
||||||
|
INPUT_UNLOCK (input->dbin);
|
||||||
|
|
||||||
|
return GST_PAD_PROBE_REMOVE;
|
||||||
|
};
|
||||||
|
|
||||||
static GstPadLinkReturn
|
static GstPadLinkReturn
|
||||||
gst_decodebin3_input_pad_link (GstPad * pad, GstObject * parent, GstPad * peer)
|
gst_decodebin3_input_pad_link (GstPad * pad, GstObject * parent, GstPad * peer)
|
||||||
{
|
{
|
||||||
|
@ -1662,6 +1682,15 @@ gst_decodebin3_input_pad_link (GstPad * pad, GstObject * parent, GstPad * peer)
|
||||||
"Can't reconfigure input from push-based to pull-based");
|
"Can't reconfigure input from push-based to pull-based");
|
||||||
res = GST_PAD_LINK_REFUSED;
|
res = GST_PAD_LINK_REFUSED;
|
||||||
}
|
}
|
||||||
|
} else if (input->input_probe == 0) {
|
||||||
|
/* We setup a buffer probe to handle the corner case of push-based
|
||||||
|
* time-based inputs without CAPS/COLLECTION. If we get a buffer without
|
||||||
|
* having figured out if we need identity or parsebin, we will plug in
|
||||||
|
* parsebin */
|
||||||
|
GST_DEBUG_OBJECT (pad, "Setting up buffer probe");
|
||||||
|
input->input_probe =
|
||||||
|
gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER,
|
||||||
|
input_pad_buffer_probe, input, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear stream-collection corresponding to current INPUT. We do not
|
/* Clear stream-collection corresponding to current INPUT. We do not
|
||||||
|
@ -1880,6 +1909,11 @@ gst_decodebin_input_reset (DecodebinInput * input)
|
||||||
if (input->collection)
|
if (input->collection)
|
||||||
gst_clear_object (&input->collection);
|
gst_clear_object (&input->collection);
|
||||||
|
|
||||||
|
if (input->input_probe) {
|
||||||
|
gst_pad_remove_probe (input->ghost_sink, input->input_probe);
|
||||||
|
input->input_probe = 0;
|
||||||
|
}
|
||||||
|
|
||||||
g_list_free_full (input->events_waiting_for_collection,
|
g_list_free_full (input->events_waiting_for_collection,
|
||||||
(GDestroyNotify) gst_event_unref);
|
(GDestroyNotify) gst_event_unref);
|
||||||
input->events_waiting_for_collection = NULL;
|
input->events_waiting_for_collection = NULL;
|
||||||
|
@ -2090,6 +2124,12 @@ sink_event_function (GstPad * sinkpad, GstDecodebin3 * dbin, GstEvent * event)
|
||||||
if (!input->parsebin && !input->identity)
|
if (!input->parsebin && !input->identity)
|
||||||
gst_decodebin_input_setup_identity (input);
|
gst_decodebin_input_setup_identity (input);
|
||||||
|
|
||||||
|
/* Remove buffer probe for caps/collection detection */
|
||||||
|
if (input->input_probe) {
|
||||||
|
gst_pad_remove_probe (sinkpad, input->input_probe);
|
||||||
|
input->input_probe = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Drain all pending events */
|
/* Drain all pending events */
|
||||||
if (input->events_waiting_for_collection) {
|
if (input->events_waiting_for_collection) {
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
|
@ -2109,6 +2149,12 @@ sink_event_function (GstPad * sinkpad, GstDecodebin3 * dbin, GstEvent * event)
|
||||||
break;
|
break;
|
||||||
GST_DEBUG_OBJECT (sinkpad, "new caps %" GST_PTR_FORMAT, newcaps);
|
GST_DEBUG_OBJECT (sinkpad, "new caps %" GST_PTR_FORMAT, newcaps);
|
||||||
|
|
||||||
|
/* Remove buffer probe for caps/collection detection */
|
||||||
|
if (input->input_probe) {
|
||||||
|
gst_pad_remove_probe (sinkpad, input->input_probe);
|
||||||
|
input->input_probe = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* No parsebin or identity present, check if we can avoid creating one */
|
/* No parsebin or identity present, check if we can avoid creating one */
|
||||||
if (!input->parsebin && !input->identity) {
|
if (!input->parsebin && !input->identity) {
|
||||||
if (gst_decodebin_input_requires_parsebin (input, newcaps)) {
|
if (gst_decodebin_input_requires_parsebin (input, newcaps)) {
|
||||||
|
|
Loading…
Reference in a new issue