From 27389178522e04512bb6aa086aa8465fe64599fc Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Wed, 9 Mar 2011 17:07:47 +0100 Subject: [PATCH] rtspsrc: improve recovery from failed seek 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 | 34 ++++++++++++++++++++++++++++++++-- gst/rtsp/gstrtspsrc.h | 2 ++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c index 980fd02..e1c8f9b 100644 --- a/gst/rtsp/gstrtspsrc.c +++ b/gst/rtsp/gstrtspsrc.c @@ -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); diff --git a/gst/rtsp/gstrtspsrc.h b/gst/rtsp/gstrtspsrc.h index 00861b6..460f29a 100644 --- a/gst/rtsp/gstrtspsrc.h +++ b/gst/rtsp/gstrtspsrc.h @@ -233,7 +233,9 @@ struct _GstRTSPSrc { /* supported methods */ gint methods; + gboolean seekable; + GstClockTime last_pos; /* session management */ GstElement *manager; -- 2.7.4