From 56e05f63f5815c72d831e646786a68afeb01960d Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Fri, 11 Dec 2020 10:13:59 +0100 Subject: [PATCH] decodebin3: Release selection lock when pushing EOS We can't keep the lock otherwise this would lock other actions. In order to keep it safe, we grab a list of peer pads to send EOS to with the lock taken, then send to the peer pads with the lock released. Also make sure the selection lock is taken for another call to this function Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/issues/847 Part-of: --- gst/playback/gstdecodebin3-parse.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/gst/playback/gstdecodebin3-parse.c b/gst/playback/gstdecodebin3-parse.c index 532907da1d..85e1de4831 100644 --- a/gst/playback/gstdecodebin3-parse.c +++ b/gst/playback/gstdecodebin3-parse.c @@ -120,22 +120,37 @@ static void check_all_streams_for_eos (GstDecodebin3 * dbin) { GList *tmp; + GList *outputpads = NULL; if (!all_inputs_are_eos (dbin)) return; /* We know all streams are EOS, properly clean up everything */ + + /* We grab all peer pads *while* the selection lock is taken and then we will + push EOS downstream with the selection lock released */ for (tmp = dbin->input_streams; tmp; tmp = tmp->next) { DecodebinInputStream *input = (DecodebinInputStream *) tmp->data; GstPad *peer = gst_pad_get_peer (input->srcpad); - /* Send EOS and then remove elements */ - if (peer) { - gst_pad_send_event (peer, gst_event_new_eos ()); - gst_object_unref (peer); - } - GST_FIXME_OBJECT (input->srcpad, "Remove input stream"); + /* Keep a reference to the peer pad */ + if (peer) + outputpads = g_list_append (outputpads, peer); } + + SELECTION_UNLOCK (dbin); + /* */ + for (tmp = outputpads; tmp; tmp = tmp->next) { + GstPad *peer = (GstPad *) tmp->data; + + /* Send EOS and then remove elements */ + gst_pad_send_event (peer, gst_event_new_eos ()); + GST_FIXME_OBJECT (peer, "Remove input stream"); + gst_object_unref (peer); + } + SELECTION_LOCK (dbin); + + g_list_free (outputpads); } /* Get the intersection of parser caps and available (sorted) decoders */ @@ -533,7 +548,9 @@ parsebin_pending_event_probe (GstPad * pad, GstPadProbeInfo * info, gst_pad_remove_probe (ppad->pad, ppad->event_probe); g_free (ppad); + SELECTION_LOCK (dbin); check_all_streams_for_eos (dbin); + SELECTION_UNLOCK (dbin); } break; default: