urisourcebin: Make parsebin activation more reliable

`parsebin` is potentially added by a `typefind` callback.

That `typefind` was activated by a `READY_TO_PAUSED` state change on `urisourcebin`

We want to ensure that it is the "setup_parsebin_for_slot" method that activates
the underlying `parsebin`, and not the external state-change.

Otherwise we would risk a potential deadlock where elements activating in
`parsebin`, and which would cause the upstream `typefind` to switch scheduling
mode, would not be able to acquire the STREAM_LOCK of the `typefind` task.

Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4225

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8511>
This commit is contained in:
Edward Hervey 2025-02-18 15:53:46 +01:00 committed by GStreamer Marge Bot
parent ed693c7435
commit 6454698f82

View File

@ -2129,6 +2129,12 @@ setup_parsebin_for_slot (ChildSrcPadInfo * info, GstPad * originating_pad)
post_missing_plugin_error (GST_ELEMENT_CAST (urisrc), "parsebin");
return FALSE;
}
/* Make sure we limit state changes to happen as atomically as possible. This
* function might be called while a state change is currently taking place. We
* want to ensure we are the one activating (if needed) `parsebin`
*/
gst_element_set_locked_state (info->demuxer, TRUE);
gst_bin_add (GST_BIN_CAST (urisrc), info->demuxer);
info->demuxer_is_parsebin = TRUE;
@ -2156,12 +2162,15 @@ setup_parsebin_for_slot (ChildSrcPadInfo * info, GstPad * originating_pad)
if (info->pre_parse_queue) {
gst_element_sync_state_with_parent (info->pre_parse_queue);
}
/* `parsebin` can be synchronized */
gst_element_set_locked_state (info->demuxer, FALSE);
gst_element_sync_state_with_parent (info->demuxer);
GST_URI_SOURCE_BIN_UNLOCK (urisrc);
return TRUE;
could_not_link:
{
gst_element_set_locked_state (info->demuxer, FALSE);
GST_URI_SOURCE_BIN_UNLOCK (urisrc);
GST_ELEMENT_ERROR (urisrc, CORE, NEGOTIATION,
(NULL), ("Can't link to (pre-)parsebin element"));