From 6454698f829ca48da3ba54f386fd6f47cb989476 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Tue, 18 Feb 2025 15:53:46 +0100 Subject: [PATCH] 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: --- .../gst-plugins-base/gst/playback/gsturisourcebin.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/subprojects/gst-plugins-base/gst/playback/gsturisourcebin.c b/subprojects/gst-plugins-base/gst/playback/gsturisourcebin.c index 305eabf209..8870dc6076 100644 --- a/subprojects/gst-plugins-base/gst/playback/gsturisourcebin.c +++ b/subprojects/gst-plugins-base/gst/playback/gsturisourcebin.c @@ -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"));