aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHoward Chu <hyc@highlandsun.com>2010-04-18 19:09:25 +0000
committerStefano Sabatini <stefano.sabatini-lala@poste.it>2010-04-18 19:09:25 +0000
commitfc8fa007fb6099643a1f742a162e5e5eda760fd6 (patch)
treeec3196c5a1703310ec1038a793ea51bdca0bf77f
parentd79fc8403b829cab5199a662390873706aed7986 (diff)
downloadffmpeg-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.c37
-rw-r--r--libavformat/librtmp.c5
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;