mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-04 09:42:19 +00:00
playsink: use queue to avoid lock in audiotee audio branches
This part of pipeline is: tee name=t ! visualizationbin ! streamsynchronizer name=s t. ! s. streamsynchronizer might block and it could starve the visualization branch of the pipeline when it is enabled. The visualization bin has queues internally but the other branch that links the audiotee directly to the synchronizer is vulnerable to block. Adding a queue between "t. ! s." fixes deadlocks. https://bugzilla.gnome.org/show_bug.cgi?id=749676
This commit is contained in:
parent
af7a311c1c
commit
12ac087807
1 changed files with 54 additions and 2 deletions
|
@ -212,6 +212,8 @@ struct _GstPlaySink
|
|||
gboolean audio_pad_blocked;
|
||||
GstPad *audio_srcpad_stream_synchronizer;
|
||||
GstPad *audio_sinkpad_stream_synchronizer;
|
||||
GstElement *audio_ssync_queue;
|
||||
GstPad *audio_ssync_queue_sinkpad;
|
||||
gulong audio_block_id;
|
||||
gulong audio_notify_caps_id;
|
||||
/* audio tee */
|
||||
|
@ -743,6 +745,18 @@ free_chain (GstPlayChain * chain)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_remove_audio_ssync_queue (GstPlaySink * playsink)
|
||||
{
|
||||
if (playsink->audio_ssync_queue) {
|
||||
gst_element_set_state (playsink->audio_ssync_queue, GST_STATE_NULL);
|
||||
gst_object_unref (playsink->audio_ssync_queue_sinkpad);
|
||||
gst_bin_remove (GST_BIN_CAST (playsink), playsink->audio_ssync_queue);
|
||||
playsink->audio_ssync_queue = NULL;
|
||||
playsink->audio_ssync_queue_sinkpad = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_dispose (GObject * object)
|
||||
{
|
||||
|
@ -3469,6 +3483,8 @@ gst_play_sink_do_reconfigure (GstPlaySink * playsink)
|
|||
playsink->audio_sinkpad_stream_synchronizer = NULL;
|
||||
gst_object_unref (playsink->audio_srcpad_stream_synchronizer);
|
||||
playsink->audio_srcpad_stream_synchronizer = NULL;
|
||||
|
||||
gst_play_sink_remove_audio_ssync_queue (playsink);
|
||||
}
|
||||
|
||||
add_chain (GST_PLAY_CHAIN (playsink->audiochain), FALSE);
|
||||
|
@ -3504,6 +3520,7 @@ gst_play_sink_do_reconfigure (GstPlaySink * playsink)
|
|||
goto no_chain;
|
||||
|
||||
if (!playsink->audio_sinkpad_stream_synchronizer) {
|
||||
GstPad *audio_queue_srcpad;
|
||||
GValue item = { 0, };
|
||||
GstIterator *it;
|
||||
|
||||
|
@ -3518,18 +3535,49 @@ gst_play_sink_do_reconfigure (GstPlaySink * playsink)
|
|||
g_value_unset (&item);
|
||||
g_assert (playsink->audio_srcpad_stream_synchronizer);
|
||||
gst_iterator_free (it);
|
||||
|
||||
if (need_vis) {
|
||||
GST_DEBUG_OBJECT (playsink, "adding audio stream synchronizer queue");
|
||||
playsink->audio_ssync_queue =
|
||||
gst_element_factory_make ("queue", "audiossyncqueue");
|
||||
if (playsink->audio_ssync_queue == NULL) {
|
||||
post_missing_element_message (playsink, "queue");
|
||||
GST_ELEMENT_WARNING (playsink, CORE, MISSING_PLUGIN,
|
||||
(_("Missing element '%s' - check your GStreamer installation."),
|
||||
"queue"),
|
||||
("audio playback and visualizations might not work"));
|
||||
}
|
||||
g_object_set (playsink->audio_ssync_queue, "max-size-buffers",
|
||||
(guint) 1, NULL);
|
||||
gst_bin_add (GST_BIN_CAST (playsink), playsink->audio_ssync_queue);
|
||||
playsink->audio_ssync_queue_sinkpad =
|
||||
gst_element_get_static_pad (playsink->audio_ssync_queue, "sink");
|
||||
audio_queue_srcpad =
|
||||
gst_element_get_static_pad (playsink->audio_ssync_queue, "src");
|
||||
gst_element_sync_state_with_parent (playsink->audio_ssync_queue);
|
||||
gst_pad_link_full (audio_queue_srcpad,
|
||||
playsink->audio_sinkpad_stream_synchronizer,
|
||||
GST_PAD_LINK_CHECK_NOTHING);
|
||||
gst_object_unref (audio_queue_srcpad);
|
||||
}
|
||||
}
|
||||
|
||||
if (playsink->audiochain) {
|
||||
GstPad *sinkpad;
|
||||
|
||||
GST_DEBUG_OBJECT (playsink, "adding audio chain");
|
||||
if (playsink->audio_tee_asrc == NULL) {
|
||||
playsink->audio_tee_asrc =
|
||||
gst_element_get_request_pad (playsink->audio_tee, "src_%u");
|
||||
}
|
||||
|
||||
sinkpad = playsink->audio_ssync_queue_sinkpad;
|
||||
if (!sinkpad)
|
||||
sinkpad = playsink->audio_sinkpad_stream_synchronizer;
|
||||
|
||||
add_chain (GST_PLAY_CHAIN (playsink->audiochain), TRUE);
|
||||
activate_chain (GST_PLAY_CHAIN (playsink->audiochain), TRUE);
|
||||
gst_pad_link_full (playsink->audio_tee_asrc,
|
||||
playsink->audio_sinkpad_stream_synchronizer,
|
||||
gst_pad_link_full (playsink->audio_tee_asrc, sinkpad,
|
||||
GST_PAD_LINK_CHECK_NOTHING);
|
||||
gst_pad_link_full (playsink->audio_srcpad_stream_synchronizer,
|
||||
playsink->audiochain->sinkpad, GST_PAD_LINK_CHECK_NOTHING);
|
||||
|
@ -3555,6 +3603,8 @@ gst_play_sink_do_reconfigure (GstPlaySink * playsink)
|
|||
playsink->audio_sinkpad_stream_synchronizer = NULL;
|
||||
gst_object_unref (playsink->audio_srcpad_stream_synchronizer);
|
||||
playsink->audio_srcpad_stream_synchronizer = NULL;
|
||||
|
||||
gst_play_sink_remove_audio_ssync_queue (playsink);
|
||||
}
|
||||
|
||||
if (playsink->audiochain->sink_volume) {
|
||||
|
@ -4847,6 +4897,8 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
playsink->audio_sinkpad_stream_synchronizer = NULL;
|
||||
gst_object_unref (playsink->audio_srcpad_stream_synchronizer);
|
||||
playsink->audio_srcpad_stream_synchronizer = NULL;
|
||||
|
||||
gst_play_sink_remove_audio_ssync_queue (playsink);
|
||||
}
|
||||
if (playsink->text_sinkpad_stream_synchronizer) {
|
||||
gst_element_release_request_pad (GST_ELEMENT_CAST
|
||||
|
|
Loading…
Reference in a new issue