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.
This commit is contained in:
Mark Nauwelaerts 2011-03-09 17:07:47 +01:00
parent 6bc1aa0e59
commit 2738917852
2 changed files with 34 additions and 2 deletions

View 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);

View file

@ -233,7 +233,9 @@ struct _GstRTSPSrc {
/* supported methods */
gint methods;
gboolean seekable;
GstClockTime last_pos;
/* session management */
GstElement *manager;