diff options
author | Jan Schmidt <jan@centricular.com> | 2021-08-06 19:27:02 +1000 |
---|---|---|
committer | Jan Schmidt <jan@centricular.com> | 2021-08-06 19:27:02 +1000 |
commit | 9be72bdf8ceb18f0c54758db29c65397e4ec42aa (patch) | |
tree | 784c88bf4f44b8d46d5dfbe9a6d859effdf5c0a7 | |
parent | 9427c7f9b87daa38f60143351b11487c0d7b2bf9 (diff) |
playsink: Complete reconfiguration on pad release.
Requesting a new pad can start a reconfiguration cycle, where
playsink will block all input pads and wait for data on them
before doing internal reconfiguration. If a pad is released,
that reconfiguration might never trigger because it's now waiting
for a pad that doesn't exist any more.
In that case, complete the reconfiguration on pad release.
-rw-r--r-- | gst/playback/gstplaysink.c | 84 |
1 files changed, 61 insertions, 23 deletions
diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index e626fcf11..4f7587766 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -193,6 +193,7 @@ struct _GstPlaySink gboolean async_pending; gboolean need_async_start; + gboolean reconfigure_pending; GstPlayFlags flags; @@ -411,6 +412,8 @@ static void gst_play_sink_navigation_init (gpointer g_iface, static void gst_play_sink_colorbalance_init (gpointer g_iface, gpointer g_iface_data); +static gboolean is_raw_pad (GstPad * pad); + static void _do_init (GType type) { @@ -3224,6 +3227,19 @@ gst_play_sink_do_reconfigure (GstPlaySink * playsink) need_text = TRUE; } + if (playsink->video_pad) { + playsink->video_pad_raw = is_raw_pad (playsink->video_pad); + GST_DEBUG_OBJECT (playsink, "Video pad is raw: %d", + playsink->video_pad_raw); + } + + if (playsink->audio_pad) { + playsink->audio_pad_raw = is_raw_pad (playsink->audio_pad); + GST_DEBUG_OBJECT (playsink, "Audio pad is raw: %d", + playsink->audio_pad_raw); + } + + if (((flags & GST_PLAY_FLAG_VIDEO) || (flags & GST_PLAY_FLAG_NATIVE_VIDEO)) && playsink->video_pad) { /* we have video and we are requested to show it */ @@ -3874,6 +3890,9 @@ gst_play_sink_do_reconfigure (GstPlaySink * playsink) update_av_offset (playsink); update_text_offset (playsink); do_async_done (playsink); + + playsink->reconfigure_pending = FALSE; + GST_PLAY_SINK_UNLOCK (playsink); return TRUE; @@ -4326,11 +4345,39 @@ gst_play_sink_reconfigure (GstPlaySink * playsink) video_set_blocked (playsink, TRUE); audio_set_blocked (playsink, TRUE); text_set_blocked (playsink, TRUE); + playsink->reconfigure_pending = TRUE; GST_PLAY_SINK_UNLOCK (playsink); return TRUE; } +/* Called with PLAY_SINK_LOCK */ +static gboolean +gst_play_sink_ready_to_reconfigure_locked (GstPlaySink * playsink) +{ + /* We reconfigure when for ALL streams: + * * there isn't a pad + * * OR the pad is blocked + * * OR there are no pending blocks on that pad + */ + if (playsink->reconfigure_pending == FALSE) + return FALSE; + + if (playsink->video_pad && !playsink->video_pad_blocked + && PENDING_VIDEO_BLOCK (playsink)) + return FALSE; + + if (playsink->audio_pad && !playsink->audio_pad_blocked + && PENDING_AUDIO_BLOCK (playsink)) + return FALSE; + + if (playsink->text_pad && !playsink->text_pad_blocked + && PENDING_TEXT_BLOCK (playsink)) + return FALSE; + + return TRUE; +} + static GstPadProbeReturn sinkpad_blocked_cb (GstPad * blockedpad, GstPadProbeInfo * info, gpointer user_data) @@ -4358,31 +4405,9 @@ sinkpad_blocked_cb (GstPad * blockedpad, GstPadProbeInfo * info, GST_DEBUG_OBJECT (pad, "Text pad blocked"); } - /* We reconfigure when for ALL streams: - * * there isn't a pad - * * OR the pad is blocked - * * OR there are no pending blocks on that pad - */ - - if ((!playsink->video_pad || playsink->video_pad_blocked - || !PENDING_VIDEO_BLOCK (playsink)) && (!playsink->audio_pad - || playsink->audio_pad_blocked || !PENDING_AUDIO_BLOCK (playsink)) - && (!playsink->text_pad || playsink->text_pad_blocked - || !PENDING_TEXT_BLOCK (playsink))) { + if (gst_play_sink_ready_to_reconfigure_locked (playsink)) { GST_DEBUG_OBJECT (playsink, "All pads blocked -- reconfiguring"); - if (playsink->video_pad) { - playsink->video_pad_raw = is_raw_pad (playsink->video_pad); - GST_DEBUG_OBJECT (playsink, "Video pad is raw: %d", - playsink->video_pad_raw); - } - - if (playsink->audio_pad) { - playsink->audio_pad_raw = is_raw_pad (playsink->audio_pad); - GST_DEBUG_OBJECT (playsink, "Audio pad is raw: %d", - playsink->audio_pad_raw); - } - gst_play_sink_do_reconfigure (playsink); video_set_blocked (playsink, FALSE); @@ -4674,6 +4699,19 @@ gst_play_sink_release_pad (GstPlaySink * playsink, GstPad * pad) res = &pad; untarget = FALSE; } + + /* If we have a pending reconfigure, we might have met the conditions + * to reconfigure now */ + if (gst_play_sink_ready_to_reconfigure_locked (playsink)) { + GST_DEBUG_OBJECT (playsink, "All pads blocked -- reconfiguring"); + + gst_play_sink_do_reconfigure (playsink); + + video_set_blocked (playsink, FALSE); + audio_set_blocked (playsink, FALSE); + text_set_blocked (playsink, FALSE); + } + GST_PLAY_SINK_UNLOCK (playsink); if (*res) { |