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.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1940>
This commit is contained in:
Jan Schmidt 2021-08-06 19:27:02 +10:00 committed by GStreamer Marge Bot
parent 8440e2a373
commit 5a074a11f9

View file

@ -194,6 +194,7 @@ struct _GstPlaySink
gboolean async_pending; gboolean async_pending;
gboolean need_async_start; gboolean need_async_start;
gboolean reconfigure_pending;
GstPlayFlags flags; GstPlayFlags flags;
@ -412,6 +413,8 @@ static void gst_play_sink_navigation_init (gpointer g_iface,
static void gst_play_sink_colorbalance_init (gpointer g_iface, static void gst_play_sink_colorbalance_init (gpointer g_iface,
gpointer g_iface_data); gpointer g_iface_data);
static gboolean is_raw_pad (GstPad * pad);
static void static void
_do_init_type (GType type) _do_init_type (GType type)
{ {
@ -3231,6 +3234,19 @@ gst_play_sink_do_reconfigure (GstPlaySink * playsink)
need_text = TRUE; 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) if (((flags & GST_PLAY_FLAG_VIDEO)
|| (flags & GST_PLAY_FLAG_NATIVE_VIDEO)) && playsink->video_pad) { || (flags & GST_PLAY_FLAG_NATIVE_VIDEO)) && playsink->video_pad) {
/* we have video and we are requested to show it */ /* we have video and we are requested to show it */
@ -3881,6 +3897,9 @@ gst_play_sink_do_reconfigure (GstPlaySink * playsink)
update_av_offset (playsink); update_av_offset (playsink);
update_text_offset (playsink); update_text_offset (playsink);
do_async_done (playsink); do_async_done (playsink);
playsink->reconfigure_pending = FALSE;
GST_PLAY_SINK_UNLOCK (playsink); GST_PLAY_SINK_UNLOCK (playsink);
return TRUE; return TRUE;
@ -4333,11 +4352,39 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
video_set_blocked (playsink, TRUE); video_set_blocked (playsink, TRUE);
audio_set_blocked (playsink, TRUE); audio_set_blocked (playsink, TRUE);
text_set_blocked (playsink, TRUE); text_set_blocked (playsink, TRUE);
playsink->reconfigure_pending = TRUE;
GST_PLAY_SINK_UNLOCK (playsink); GST_PLAY_SINK_UNLOCK (playsink);
return TRUE; 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 static GstPadProbeReturn
sinkpad_blocked_cb (GstPad * blockedpad, GstPadProbeInfo * info, sinkpad_blocked_cb (GstPad * blockedpad, GstPadProbeInfo * info,
gpointer user_data) gpointer user_data)
@ -4365,31 +4412,9 @@ sinkpad_blocked_cb (GstPad * blockedpad, GstPadProbeInfo * info,
GST_DEBUG_OBJECT (pad, "Text pad blocked"); GST_DEBUG_OBJECT (pad, "Text pad blocked");
} }
/* We reconfigure when for ALL streams: if (gst_play_sink_ready_to_reconfigure_locked (playsink)) {
* * 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))) {
GST_DEBUG_OBJECT (playsink, "All pads blocked -- reconfiguring"); 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); gst_play_sink_do_reconfigure (playsink);
video_set_blocked (playsink, FALSE); video_set_blocked (playsink, FALSE);
@ -4681,6 +4706,7 @@ gst_play_sink_release_pad (GstPlaySink * playsink, GstPad * pad)
res = &pad; res = &pad;
untarget = FALSE; untarget = FALSE;
} }
GST_PLAY_SINK_UNLOCK (playsink); GST_PLAY_SINK_UNLOCK (playsink);
if (*res) { if (*res) {
@ -4694,6 +4720,23 @@ gst_play_sink_release_pad (GstPlaySink * playsink, GstPad * pad)
gst_element_remove_pad (GST_ELEMENT_CAST (playsink), *res); gst_element_remove_pad (GST_ELEMENT_CAST (playsink), *res);
*res = NULL; *res = NULL;
} }
GST_PLAY_SINK_LOCK (playsink);
/* 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 ready after release -- 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);
} }
static void static void