rtspsrc: When seeking, consider the current element state or pending state instead...
authorSebastian Dröge <sebastian@centricular.com>
Tue, 28 Jun 2016 07:57:27 +0000 (10:57 +0300)
committerSebastian Dröge <sebastian@centricular.com>
Tue, 28 Jun 2016 08:01:24 +0000 (11:01 +0300)
If we consider the RTSP state, what can happen is that it is PLAYING but the
element already asynchronously tried to PAUSE and it just did not happen yet.

We would then override this setting to PAUSED (while the element actually is
in PAUSED) and set the RTSP state to PLAYING again. This would then cause us
to produce packets while the sinks are all PAUSED, piling up thousands of
packets in the rtpjitterbuffer and other elements and finally failing.

gst/rtsp/gstrtspsrc.c

index 3addf7a..662e0f1 100644 (file)
@@ -2170,9 +2170,8 @@ gst_rtspsrc_perform_seek (GstRTSPSrc * src, GstEvent * event)
   if ((stop = seeksegment.stop) == -1)
     stop = seeksegment.duration;
 
-  playing = (src->state == GST_RTSP_STATE_PLAYING);
-
   /* if we were playing, pause first */
+  playing = (src->state == GST_RTSP_STATE_PLAYING);
   if (playing) {
     /* obtain current position in case seek fails */
     gst_rtspsrc_get_position (src);
@@ -2185,7 +2184,12 @@ gst_rtspsrc_perform_seek (GstRTSPSrc * src, GstEvent * event)
   /* PLAY will add the range header now. */
   src->need_range = TRUE;
 
-  /* and continue playing */
+  /* and continue playing if needed */
+  GST_OBJECT_LOCK (src);
+  playing = (GST_STATE_PENDING (src) == GST_STATE_VOID_PENDING
+      && GST_STATE (src) == GST_STATE_PLAYING)
+      || (GST_STATE_PENDING (src) == GST_STATE_PLAYING);
+  GST_OBJECT_UNLOCK (src);
   if (playing)
     gst_rtspsrc_play (src, &seeksegment, FALSE);