decodebin3: Fix clean-up of EOS'd parsebin src pad

In `parse_chain_output_probe()` the corresponding input stream might receive EOS
and thus be removed before the actual pad is removed. So we cannot assert about
this in `parsebin_pad_removed_cb()`.

Also, driving-by, protect `find_input_stream_for_pad()` with the selection lock
similarly to other functions accessing the input streams list.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5887>
This commit is contained in:
Philippe Normand 2024-01-05 12:13:49 +00:00 committed by GStreamer Marge Bot
parent a64f2bf628
commit 952f252104
2 changed files with 18 additions and 4 deletions

View file

@ -545,6 +545,7 @@ parsebin_pad_added_cb (GstElement * demux, GstPad * pad, DecodebinInput * input)
SELECTION_UNLOCK (dbin);
}
/* WITH SELECTION_LOCK TAKEN! */
static DecodebinInputStream *
find_input_stream_for_pad (GstDecodebin3 * dbin, GstPad * pad)
{
@ -568,16 +569,23 @@ parsebin_pad_removed_cb (GstElement * demux, GstPad * pad, DecodebinInput * inp)
if (!GST_PAD_IS_SRC (pad))
return;
SELECTION_LOCK (dbin);
GST_DEBUG_OBJECT (pad, "removed");
input = find_input_stream_for_pad (dbin, pad);
g_assert (input);
if (input == NULL) {
GST_DEBUG_OBJECT (pad,
"Input stream not found, it was cleaned-up earlier after receiving EOS");
SELECTION_UNLOCK (dbin);
return;
}
/* If there are no pending pads, this means we will definitely not need this
* stream anymore */
GST_DEBUG_OBJECT (pad, "Remove input stream %p", input);
SELECTION_LOCK (dbin);
slot = get_slot_for_input (dbin, input);
remove_input_stream (dbin, input);

View file

@ -1233,9 +1233,15 @@ reset_input (GstDecodebin3 * dbin, DecodebinInput * input)
}
if (input->identity) {
GstPad *idpad = gst_element_get_static_pad (input->identity, "src");
DecodebinInputStream *stream = find_input_stream_for_pad (dbin, idpad);
gst_object_unref (idpad);
DecodebinInputStream *stream;
SELECTION_LOCK (dbin);
stream = find_input_stream_for_pad (dbin, idpad);
remove_input_stream (dbin, stream);
SELECTION_UNLOCK (dbin);
gst_object_unref (idpad);
gst_element_set_state (input->identity, GST_STATE_NULL);
gst_bin_remove (GST_BIN (dbin), input->identity);
gst_clear_object (&input->identity);