rtspsrc: improve recovery from failed seek
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Wed, 9 Mar 2011 16:07:47 +0000 (17:07 +0100)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Wed, 9 Mar 2011 16:18:09 +0000 (17:18 +0100)
In case server-side fails to perform seek, i.e. PLAY at non-zero requested
position, recovery so far would arrange for streaming to continue, albeit
having lost position tracking in the process.  So, query position prior
to seek and use upon failed seek.

gst/rtsp/gstrtspsrc.c
gst/rtsp/gstrtspsrc.h

index 980fd026f99ef3eebd86fe9f72f7c8f3c3a802f7..e1c8f9b4040cbf30e37f53f31389c6388dbb583b 100644 (file)
@@ -1716,6 +1716,33 @@ gst_rtspsrc_connection_receive (GstRTSPSrc * src, GstRTSPConnection * conn,
   return ret;
 }
 
+static void
+gst_rtspsrc_get_position (GstRTSPSrc * src)
+{
+  GstQuery *query;
+  GList *walk;
+
+  query = gst_query_new_position (GST_FORMAT_TIME);
+  /*  should be known somewhere down the stream (e.g. jitterbuffer) */
+  for (walk = src->streams; walk; walk = g_list_next (walk)) {
+    GstRTSPStream *stream = (GstRTSPStream *) walk->data;
+    GstFormat fmt;
+    gint64 pos;
+
+    if (stream->srcpad) {
+      if (gst_pad_query (stream->srcpad, query)) {
+        gst_query_parse_position (query, &fmt, &pos);
+        GST_DEBUG_OBJECT (src, "retaining position %" GST_TIME_FORMAT,
+            GST_TIME_ARGS (pos));
+        src->last_pos = pos;
+        return;
+      }
+    }
+  }
+
+  src->last_pos = 0;
+}
+
 static gboolean
 gst_rtspsrc_do_seek (GstRTSPSrc * src, GstSegment * segment)
 {
@@ -1808,8 +1835,11 @@ gst_rtspsrc_perform_seek (GstRTSPSrc * src, GstEvent * event)
   playing = (src->state == GST_RTSP_STATE_PLAYING);
 
   /* if we were playing, pause first */
-  if (playing)
+  if (playing) {
+    /* obtain current position in case seek fails */
+    gst_rtspsrc_get_position (src);
     gst_rtspsrc_pause (src, FALSE);
+  }
 
   gst_rtspsrc_do_seek (src, &seeksegment);
 
@@ -5885,7 +5915,7 @@ gst_rtspsrc_play (GstRTSPSrc * src, GstSegment * segment)
       /* NOTE the above also disables npt based eos detection */
       /* and below forces position to 0,
        * which is visible feedback we lost the plot */
-      segment->start = segment->last_stop = 0;
+      segment->start = segment->last_stop = src->last_pos;
     }
 
     gst_rtsp_message_unset (&request);
index 00861b6da948ca314a6fd1d2095f32daa4cf6714..460f29a0f578277aeb63107fdf61162d3cf6e2a1 100644 (file)
@@ -233,7 +233,9 @@ struct _GstRTSPSrc {
 
   /* supported methods */
   gint               methods;
+
   gboolean           seekable;
+  GstClockTime       last_pos;
 
   /* session management */
   GstElement      *manager;