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/971>
This commit is contained in:
Edward Hervey 2020-12-11 10:13:59 +01:00 committed by Sebastian Dröge
parent 030ccaedb5
commit 56e05f63f5

View 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);
/* 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: