From ab37286300baac65e6ccfca2101007a00a49a292 Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Wed, 12 Jun 2019 22:19:27 +0200 Subject: [PATCH] rtsp-media: make sure streams are blocked when sending seek The recent ONVIF work exposed a race condition when dealing with multiple streams: one of the sinks may preroll before other streams have started flushing. This led to the pipeline posting async-done prematurely, when some streams were actually still in the middle of performing a flushing seek. The newly-added code looks up a sticky segment event on the first stream in order to respond to the PLAY request with accurate Scale and Speed headers. In the failure condition, the first stream was flushing, and thus had no sticky segment event, leading to the PLAY request failing, and in turn the test. --- gst/rtsp-server/rtsp-media.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index 4c672ddfc2..bd3fcaab91 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -2797,6 +2797,7 @@ gst_rtsp_media_seek_trickmode (GstRTSPMedia * media, res = TRUE; } else { GstEvent *seek_event; + gboolean unblock = FALSE; gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARING); @@ -2815,8 +2816,21 @@ gst_rtsp_media_seek_trickmode (GstRTSPMedia * media, gst_event_set_seek_trickmode_interval (seek_event, trickmode_interval); + if (!media->priv->blocked) { + /* Prevent a race condition with multiple streams, + * where one stream may have time to preroll before others + * have even started flushing, causing async-done to be + * posted too early. + */ + media_streams_set_blocked (media, TRUE); + unblock = TRUE; + } + res = gst_element_send_event (priv->pipeline, seek_event); + if (unblock) + media_streams_set_blocked (media, FALSE); + /* and block for the seek to complete */ GST_INFO ("done seeking %d", res); if (!res)