diff options
author | Howard Chu <hyc@highlandsun.com> | 2010-04-18 19:09:25 +0000 |
---|---|---|
committer | Stefano Sabatini <stefano.sabatini-lala@poste.it> | 2010-04-18 19:09:25 +0000 |
commit | fc8fa007fb6099643a1f742a162e5e5eda760fd6 (patch) | |
tree | ec3196c5a1703310ec1038a793ea51bdca0bf77f | |
parent | d79fc8403b829cab5199a662390873706aed7986 (diff) | |
download | ffmpeg-fc8fa007fb6099643a1f742a162e5e5eda760fd6.tar.gz |
Implement librtmp seek support.
Implement flv_read_seek(), add a missing check on stream_index
and fix timestamp rounding in rtmp_read_seek().
Also add the flv_read_seek2() function, which is not enabled but is
useful as reference.
To actually implement flv_read_seek2() correctly, there would need to
be some corresponding av_url_read_fseek2() function to propagate the
timestamps down to the ByteIOContext and URLContext.
Patch by Howard Chu <hyc <at> highlandsun.com>.
See the thread:
Subject: [FFmpeg-devel] RTMP seek support
Date: 2010-03-28 23:35:02 GMT
Originally committed as revision 22904 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavformat/flvdec.c | 37 | ||||
-rw-r--r-- | libavformat/librtmp.c | 5 |
2 files changed, 41 insertions, 1 deletions
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 24a414e17d..b5a8eefe0f 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -449,6 +449,39 @@ leave: return ret; } +static int flv_read_seek(AVFormatContext *s, int stream_index, + int64_t ts, int flags) +{ + return av_url_read_fseek(s->pb, stream_index, ts, flags); +} + +#if 0 /* don't know enough to implement this */ +static int flv_read_seek2(AVFormatContext *s, int stream_index, + int64_t min_ts, int64_t ts, int64_t max_ts, int flags) +{ + int ret = AVERROR(ENOSYS); + + if (ts - min_ts > (uint64_t)(max_ts - ts)) flags |= AVSEEK_FLAG_BACKWARD; + + if (url_is_streamed(s->pb)) { + if (stream_index < 0) { + stream_index = av_find_default_stream_index(s); + if (stream_index < 0) + return -1; + + /* timestamp for default must be expressed in AV_TIME_BASE units */ + ts = av_rescale_rnd(ts, 1000, AV_TIME_BASE, + flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); + } + ret = av_url_read_fseek(s->pb, stream_index, ts, flags); + } + + if (ret == AVERROR(ENOSYS)) + ret = av_seek_frame(s, stream_index, ts, flags); + return ret; +} +#endif + AVInputFormat flv_demuxer = { "flv", NULL_IF_CONFIG_SMALL("FLV format"), @@ -456,6 +489,10 @@ AVInputFormat flv_demuxer = { flv_probe, flv_read_header, flv_read_packet, + .read_seek = flv_read_seek, +#if 0 + .read_seek2 = flv_read_seek2, +#endif .extensions = "flv", .value = CODEC_ID_FLV1, }; diff --git a/libavformat/librtmp.c b/libavformat/librtmp.c index 69a69f1211..b9efa51477 100644 --- a/libavformat/librtmp.c +++ b/libavformat/librtmp.c @@ -144,7 +144,10 @@ static int64_t rtmp_read_seek(URLContext *s, int stream_index, return AVERROR(ENOSYS); /* seeks are in milliseconds */ - timestamp = av_rescale(timestamp, AV_TIME_BASE, 1000); + if (stream_index < 0) + timestamp = av_rescale_rnd(timestamp, 1000, AV_TIME_BASE, + flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); + if (!RTMP_SendSeek(r, timestamp)) return -1; return timestamp; |