From 5f2c0c8ea72e3376ff0d8367a92f8bb900f5a19b Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Thu, 13 Oct 2016 20:10:09 +0900 Subject: [PATCH] decodebin3: More SELECTION_LOCK when linking to slot Since there can be multiple parsebin in a decodebin3, linking parsebin with MultiQueueSlot should be protected also. https://bugzilla.gnome.org/show_bug.cgi?id=772855 --- gst/playback/gstdecodebin3-parse.c | 31 ++++++++++++++++++++++++++---- gst/playback/gstdecodebin3.c | 1 + 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/gst/playback/gstdecodebin3-parse.c b/gst/playback/gstdecodebin3-parse.c index a54cf82942..b07b50524d 100644 --- a/gst/playback/gstdecodebin3-parse.c +++ b/gst/playback/gstdecodebin3-parse.c @@ -228,8 +228,10 @@ parse_chain_output_probe (GstPad * pad, GstPadProbeInfo * info, gst_object_unref (input->active_stream); input->active_stream = stream; /* We have the beginning of a stream, get a multiqueue slot and link to it */ + g_mutex_lock (&input->dbin->selection_lock); slot = get_slot_for_input (input->dbin, input); link_input_to_slot (input, slot); + g_mutex_unlock (&input->dbin->selection_lock); } else gst_object_unref (stream); } @@ -252,7 +254,11 @@ parse_chain_output_probe (GstPad * pad, GstPadProbeInfo * info, check_all_streams_for_eos (input->dbin); ret = GST_PAD_PROBE_DROP; } else { - MultiQueueSlot *slot = get_slot_for_input (input->dbin, input); + MultiQueueSlot *slot; + + g_mutex_lock (&input->dbin->selection_lock); + slot = get_slot_for_input (input->dbin, input); + g_mutex_unlock (&input->dbin->selection_lock); slot->drain_eos = input->drain_eos; @@ -353,7 +359,9 @@ remove_input_stream (GstDecodebin3 * dbin, DecodebinInputStream * stream) } } + g_mutex_lock (&dbin->selection_lock); slot = get_slot_for_input (dbin, stream); + g_mutex_unlock (&dbin->selection_lock); if (slot) { slot->pending_stream = NULL; slot->input = NULL; @@ -377,7 +385,7 @@ parsebin_buffer_probe (GstPad * pad, GstPadProbeInfo * info, DecodebinInput * input) { GstDecodebin3 *dbin = input->dbin; - GList *tmp; + GList *tmp, *unused_slot = NULL; GST_FIXME_OBJECT (dbin, "Need a lock !"); @@ -430,8 +438,12 @@ parsebin_buffer_probe (GstPad * pad, GstPadProbeInfo * info, input_stream = create_input_stream (dbin, stream, ppad->pad, ppad->input); /* See if we can link it straight away */ input_stream->active_stream = stream; + + g_mutex_lock (&dbin->selection_lock); slot = get_slot_for_input (dbin, input_stream); link_input_to_slot (input_stream, slot); + g_mutex_unlock (&dbin->selection_lock); + /* Remove the buffer and event probe */ gst_pad_remove_probe (ppad->pad, ppad->buffer_probe); gst_pad_remove_probe (ppad->pad, ppad->event_probe); @@ -443,15 +455,26 @@ parsebin_buffer_probe (GstPad * pad, GstPadProbeInfo * info, input->pending_pads = NULL; /* Weed out unused multiqueue slots */ + g_mutex_lock (&dbin->selection_lock); for (tmp = dbin->slots; tmp; tmp = tmp->next) { MultiQueueSlot *slot = (MultiQueueSlot *) tmp->data; GST_LOG_OBJECT (dbin, "Slot %d input:%p drain_eos:%d", slot->id, slot->input, slot->drain_eos); if (slot->input == NULL) { - GST_DEBUG_OBJECT (slot->sink_pad, "Sending EOS to unused slot"); - gst_pad_send_event (slot->sink_pad, gst_event_new_eos ()); + unused_slot = + g_list_append (unused_slot, gst_object_ref (slot->sink_pad)); } } + g_mutex_unlock (&dbin->selection_lock); + + for (tmp = unused_slot; tmp; tmp = tmp->next) { + GstPad *sink_pad = (GstPad *) tmp->data; + GST_DEBUG_OBJECT (sink_pad, "Sending EOS to unused slot"); + gst_pad_send_event (sink_pad, gst_event_new_eos ()); + } + + if (unused_slot) + g_list_free_full (unused_slot, (GDestroyNotify) gst_object_unref); return GST_PAD_PROBE_OK; } diff --git a/gst/playback/gstdecodebin3.c b/gst/playback/gstdecodebin3.c index cd6dde6213..61bc8602a6 100644 --- a/gst/playback/gstdecodebin3.c +++ b/gst/playback/gstdecodebin3.c @@ -1596,6 +1596,7 @@ fail: } } +/* Must be called with SELECTION_LOCK */ static MultiQueueSlot * get_slot_for_input (GstDecodebin3 * dbin, DecodebinInputStream * input) {