summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <edward@centricular.com>2020-12-11 10:13:59 +0100
committerTim-Philipp Müller <tim@centricular.com>2020-12-11 19:07:47 +0000
commitba3ed444f743cac4252b71568d830bffdf3176a7 (patch)
tree917fc5243e1b538104a10fe1dfc41c758c869219
parentd28f1d7d30dcedadef7a0e4d20027f744b1c4a5f (diff)
downloadgstreamer-plugins-base-ba3ed444f743cac4252b71568d830bffdf3176a7.tar.gz
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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/973>
-rw-r--r--gst/playback/gstdecodebin3-parse.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/gst/playback/gstdecodebin3-parse.c b/gst/playback/gstdecodebin3-parse.c
index 532907da1..85e1de483 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);
+ /* 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 */
- if (peer) {
- gst_pad_send_event (peer, gst_event_new_eos ());
- gst_object_unref (peer);
- }
- GST_FIXME_OBJECT (input->srcpad, "Remove input stream");
+ 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: