From a77a171b7ff436cb63b13321427a259a2a8c8fc7 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 30 Oct 2014 22:46:25 +0100 Subject: demux_lavf: mark as seekable if protocol supports seeking by time Basically, this will mark the demuxer as seekable with rtmp* and mmsh protocols. These protocols have network-level time seeking, and whether you can seek on the byte level does not matter. Until now, seeking was typically only enabled because of the cache, and a (nonsensical) warning was shown accordingly. It still could happen that the server doesn't actually support thse requests (or simply rejects them), so this is somewhat imperfect. --- demux/demux_lavf.c | 2 ++ stream/cache.c | 4 ++++ stream/stream.h | 1 + stream/stream_lavf.c | 4 ++++ 4 files changed, 11 insertions(+) diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index 553e43aea0..d1158619b7 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -729,6 +729,8 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check) priv->pb->read_seek = mp_read_seek; priv->pb->seekable = demuxer->seekable ? AVIO_SEEKABLE_NORMAL : 0; avfc->pb = priv->pb; + if (stream_control(demuxer->stream, STREAM_CTRL_HAS_AVSEEK, NULL) > 0) + demuxer->seekable = true; } if (matches_avinputformat_name(priv, "rtsp")) { diff --git a/stream/cache.c b/stream/cache.c index bc4d9e2610..7bbbcd62c5 100644 --- a/stream/cache.c +++ b/stream/cache.c @@ -112,6 +112,7 @@ struct priv { int64_t stream_size; struct mp_tags *stream_metadata; double start_pts; + bool has_avseek; }; enum { @@ -361,6 +362,7 @@ static void update_cached_controls(struct priv *s) s->stream_size = -1; if (stream_control(s->stream, STREAM_CTRL_GET_SIZE, &i64) == STREAM_OK) s->stream_size = i64; + s->has_avseek = stream_control(s->stream, STREAM_CTRL_HAS_AVSEEK, NULL) > 0; } // the core might call these every frame, so cache them... @@ -391,6 +393,8 @@ static int cache_get_cached_control(stream_t *cache, int cmd, void *arg) *(double *)arg = s->start_pts; return STREAM_OK; } + case STREAM_CTRL_HAS_AVSEEK: + return s->has_avseek ? STREAM_OK : STREAM_UNSUPPORTED; case STREAM_CTRL_GET_METADATA: { if (s->stream_metadata) { ta_set_parent(s->stream_metadata, NULL); diff --git a/stream/stream.h b/stream/stream.h index e7a0bb5dca..5cf3487462 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -105,6 +105,7 @@ enum stream_ctrl { STREAM_CTRL_DVB_SET_CHANNEL, STREAM_CTRL_DVB_STEP_CHANNEL, STREAM_CTRL_AVSEEK, + STREAM_CTRL_HAS_AVSEEK, }; struct stream_lang_req { diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c index 02f23284b3..76f2c8ee4e 100644 --- a/stream/stream_lavf.c +++ b/stream/stream_lavf.c @@ -117,6 +117,10 @@ static int control(stream_t *s, int cmd, void *arg) return 1; break; } + case STREAM_CTRL_HAS_AVSEEK: + if (avio->read_seek) + return 1; + break; case STREAM_CTRL_GET_METADATA: { *(struct mp_tags **)arg = read_icy(s); if (!*(struct mp_tags **)arg) -- cgit v1.2.3