decodebin3: Release selection lock when pushing EOS
authorEdward Hervey <edward@centricular.com>
Fri, 11 Dec 2020 09:13:59 +0000 (10:13 +0100)
committerSebastian Dröge <slomo@coaxion.net>
Fri, 11 Dec 2020 18:36:30 +0000 (18:36 +0000)
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/971>

gst/playback/gstdecodebin3-parse.c

index 532907d..85e1de4 100644 (file)
@@ -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: