mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:56:14 +00:00
decodebin3: Handle streams without CAPS or TIME segment
decodebin3 will do its best to figure out whether a parsebin is required to process the incoming stream. The problem is that for push-based stream it could happen that the stream would not provide any caps, resulting in nothing being linked internally. Furthermore, there is the possibility that a stream *with* caps would not be using a TIME segment, which is required for multiqueue to properly work. In order to fix those two issues, we force the usage of parsebin on push-based streams: * When the pad is linked, if upstream can't provide any caps * When we get a non-TIME segment Fixes #2521 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4499>
This commit is contained in:
parent
a82e1fd5ad
commit
fcd4085c25
1 changed files with 35 additions and 5 deletions
|
@ -912,6 +912,7 @@ gst_decodebin3_input_pad_link (GstPad * pad, GstObject * parent, GstPad * peer)
|
||||||
GstDecodebin3 *dbin = (GstDecodebin3 *) parent;
|
GstDecodebin3 *dbin = (GstDecodebin3 *) parent;
|
||||||
GstQuery *query;
|
GstQuery *query;
|
||||||
gboolean pull_mode = FALSE;
|
gboolean pull_mode = FALSE;
|
||||||
|
gboolean has_caps = TRUE;
|
||||||
GstPadLinkReturn res = GST_PAD_LINK_OK;
|
GstPadLinkReturn res = GST_PAD_LINK_OK;
|
||||||
DecodebinInput *input = g_object_get_data (G_OBJECT (pad), "decodebin.input");
|
DecodebinInput *input = g_object_get_data (G_OBJECT (pad), "decodebin.input");
|
||||||
|
|
||||||
|
@ -928,12 +929,26 @@ gst_decodebin3_input_pad_link (GstPad * pad, GstObject * parent, GstPad * peer)
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dbin, "Upstream can do pull-based : %d", pull_mode);
|
GST_DEBUG_OBJECT (dbin, "Upstream can do pull-based : %d", pull_mode);
|
||||||
|
|
||||||
/* If upstream *can* do pull-based, we always use a parsebin. If not, we will
|
if (!pull_mode) {
|
||||||
* delay that decision to a later stage (caps/stream/collection event
|
/* If push-based, query if it will provide some caps */
|
||||||
* processing) to figure out if one is really needed or whether an identity
|
query = gst_query_new_caps (NULL);
|
||||||
* element will be enough */
|
if (gst_pad_query (peer, query)) {
|
||||||
|
GstCaps *rescaps = NULL;
|
||||||
|
gst_query_parse_caps_result (query, &rescaps);
|
||||||
|
if (!rescaps || gst_caps_is_any (rescaps) || gst_caps_is_empty (rescaps)) {
|
||||||
|
GST_DEBUG_OBJECT (dbin, "Upstream can't provide caps");
|
||||||
|
has_caps = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gst_query_unref (query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If upstream *can* do pull-based OR it doesn't have any caps, we always use
|
||||||
|
* a parsebin. If not, we will delay that decision to a later stage
|
||||||
|
* (caps/stream/collection event processing) to figure out if one is really
|
||||||
|
* needed or whether an identity element will be enough */
|
||||||
INPUT_LOCK (dbin);
|
INPUT_LOCK (dbin);
|
||||||
if (pull_mode) {
|
if (pull_mode || !has_caps) {
|
||||||
if (!ensure_input_parsebin (dbin, input))
|
if (!ensure_input_parsebin (dbin, input))
|
||||||
res = GST_PAD_LINK_REFUSED;
|
res = GST_PAD_LINK_REFUSED;
|
||||||
else if (input->identity) {
|
else if (input->identity) {
|
||||||
|
@ -1410,6 +1425,21 @@ sink_event_function (GstPad * sinkpad, GstDecodebin3 * dbin, GstEvent * event)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case GST_EVENT_SEGMENT:
|
||||||
|
{
|
||||||
|
const GstSegment *segment = NULL;
|
||||||
|
gst_event_parse_segment (event, &segment);
|
||||||
|
|
||||||
|
/* All data reaching multiqueue must be in time format. If it's not, we
|
||||||
|
* need to use a parsebin on the incoming stream.
|
||||||
|
*/
|
||||||
|
if (segment && segment->format != GST_FORMAT_TIME && !input->parsebin) {
|
||||||
|
GST_DEBUG_OBJECT (sinkpad,
|
||||||
|
"Got a non-time segment, forcing parsebin handling");
|
||||||
|
ensure_input_parsebin (dbin, input);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue