summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2010-04-23 23:50:34 +0300
committerUoti Urpala <uau@glyph.nonexistent.invalid>2010-04-23 23:50:34 +0300
commit7be5f14c3ab0cc3e41f398827f4cf6d4f31d7b99 (patch)
tree61c2502f8663afc21a5d7f341e8c7808f3a9eaaf
parent1d4d1bff82f70c7cde37b1beaf1b55c72b3d6618 (diff)
downloadmpv-7be5f14c3ab0cc3e41f398827f4cf6d4f31d7b99.tar.bz2
mpv-7be5f14c3ab0cc3e41f398827f4cf6d4f31d7b99.tar.xz
demux_lavf, stream_ffmpeg: support librtmp seeks
-rw-r--r--libmpdemux/demux_lavf.c25
-rw-r--r--stream/stream_ffmpeg.c11
2 files changed, 31 insertions, 5 deletions
diff --git a/libmpdemux/demux_lavf.c b/libmpdemux/demux_lavf.c
index 1222673d87..70edf16efb 100644
--- a/libmpdemux/demux_lavf.c
+++ b/libmpdemux/demux_lavf.c
@@ -58,7 +58,7 @@ const m_option_t lavfdopts_conf[] = {
#define BIO_BUFFER_SIZE 32768
-typedef struct lavf_priv_t{
+typedef struct lavf_priv {
AVInputFormat *avif;
AVFormatContext *avfc;
ByteIOContext *pb;
@@ -74,7 +74,8 @@ typedef struct lavf_priv_t{
}lavf_priv_t;
static int mp_read(void *opaque, uint8_t *buf, int size) {
- stream_t *stream = opaque;
+ struct demuxer *demuxer = opaque;
+ struct stream *stream = demuxer->stream;
int ret;
if(stream_eof(stream)) //needed?
@@ -86,7 +87,8 @@ static int mp_read(void *opaque, uint8_t *buf, int size) {
}
static int64_t mp_seek(void *opaque, int64_t pos, int whence) {
- stream_t *stream = opaque;
+ struct demuxer *demuxer = opaque;
+ struct stream *stream = demuxer->stream;
int64_t current_pos;
mp_msg(MSGT_HEADER,MSGL_DBG2,"mp_seek(%p, %"PRId64", %d)\n", stream, pos, whence);
if(whence == SEEK_CUR)
@@ -114,6 +116,20 @@ static int64_t mp_seek(void *opaque, int64_t pos, int whence) {
return pos - stream->start_pos;
}
+static int64_t mp_read_seek(void *opaque, int stream_idx, int64_t ts, int flags)
+{
+ struct demuxer *demuxer = opaque;
+ struct stream *stream = demuxer->stream;
+ struct lavf_priv *priv = demuxer->priv;
+
+ AVStream *st = priv->avfc->streams[stream_idx];
+ double pts = (double)ts * st->time_base.num / st->time_base.den;
+ int ret = stream_control(stream, STREAM_CTRL_SEEK_TO_TIME, &pts);
+ if (ret < 0)
+ ret = AVERROR(ENOSYS);
+ return ret;
+}
+
static void list_formats(void) {
AVInputFormat *fmt;
mp_msg(MSGT_DEMUX, MSGL_INFO, "Available lavf input formats:\n");
@@ -482,7 +498,8 @@ static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
av_strlcat(mp_filename, "foobar.dummy", sizeof(mp_filename));
priv->pb = av_alloc_put_byte(priv->buffer, BIO_BUFFER_SIZE, 0,
- demuxer->stream, mp_read, NULL, mp_seek);
+ demuxer, mp_read, NULL, mp_seek);
+ priv->pb->read_seek = mp_read_seek;
priv->pb->is_streamed = !demuxer->stream->end_pos || (demuxer->stream->flags & MP_STREAM_SEEK) != MP_STREAM_SEEK;
if(av_open_input_stream(&avfc, priv->pb, mp_filename, priv->avif, &ap)<0){
diff --git a/stream/stream_ffmpeg.c b/stream/stream_ffmpeg.c
index fe8df9446d..e6705883fc 100644
--- a/stream/stream_ffmpeg.c
+++ b/stream/stream_ffmpeg.c
@@ -50,7 +50,8 @@ static int seek(stream_t *s, off_t newpos)
static int control(stream_t *s, int cmd, void *arg)
{
- int64_t size;
+ int64_t size, ts;
+ double pts;
switch(cmd) {
case STREAM_CTRL_GET_SIZE:
size = url_filesize(s->priv);
@@ -58,6 +59,14 @@ static int control(stream_t *s, int cmd, void *arg)
*(off_t *)arg = size;
return 1;
}
+ break;
+ case STREAM_CTRL_SEEK_TO_TIME:
+ pts = *(double *)arg;
+ ts = pts * AV_TIME_BASE;
+ ts = av_url_read_seek(s->priv, -1, ts, 0);
+ if (ts >= 0)
+ return 1;
+ break;
}
return STREAM_UNSUPPORTED;
}