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
| ... | ... |
@@ -449,6 +449,39 @@ leave: |
| 449 | 449 |
return ret; |
| 450 | 450 |
} |
| 451 | 451 |
|
| 452 |
+static int flv_read_seek(AVFormatContext *s, int stream_index, |
|
| 453 |
+ int64_t ts, int flags) |
|
| 454 |
+{
|
|
| 455 |
+ return av_url_read_fseek(s->pb, stream_index, ts, flags); |
|
| 456 |
+} |
|
| 457 |
+ |
|
| 458 |
+#if 0 /* don't know enough to implement this */ |
|
| 459 |
+static int flv_read_seek2(AVFormatContext *s, int stream_index, |
|
| 460 |
+ int64_t min_ts, int64_t ts, int64_t max_ts, int flags) |
|
| 461 |
+{
|
|
| 462 |
+ int ret = AVERROR(ENOSYS); |
|
| 463 |
+ |
|
| 464 |
+ if (ts - min_ts > (uint64_t)(max_ts - ts)) flags |= AVSEEK_FLAG_BACKWARD; |
|
| 465 |
+ |
|
| 466 |
+ if (url_is_streamed(s->pb)) {
|
|
| 467 |
+ if (stream_index < 0) {
|
|
| 468 |
+ stream_index = av_find_default_stream_index(s); |
|
| 469 |
+ if (stream_index < 0) |
|
| 470 |
+ return -1; |
|
| 471 |
+ |
|
| 472 |
+ /* timestamp for default must be expressed in AV_TIME_BASE units */ |
|
| 473 |
+ ts = av_rescale_rnd(ts, 1000, AV_TIME_BASE, |
|
| 474 |
+ flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); |
|
| 475 |
+ } |
|
| 476 |
+ ret = av_url_read_fseek(s->pb, stream_index, ts, flags); |
|
| 477 |
+ } |
|
| 478 |
+ |
|
| 479 |
+ if (ret == AVERROR(ENOSYS)) |
|
| 480 |
+ ret = av_seek_frame(s, stream_index, ts, flags); |
|
| 481 |
+ return ret; |
|
| 482 |
+} |
|
| 483 |
+#endif |
|
| 484 |
+ |
|
| 452 | 485 |
AVInputFormat flv_demuxer = {
|
| 453 | 486 |
"flv", |
| 454 | 487 |
NULL_IF_CONFIG_SMALL("FLV format"),
|
| ... | ... |
@@ -456,6 +489,10 @@ AVInputFormat flv_demuxer = {
|
| 456 | 456 |
flv_probe, |
| 457 | 457 |
flv_read_header, |
| 458 | 458 |
flv_read_packet, |
| 459 |
+ .read_seek = flv_read_seek, |
|
| 460 |
+#if 0 |
|
| 461 |
+ .read_seek2 = flv_read_seek2, |
|
| 462 |
+#endif |
|
| 459 | 463 |
.extensions = "flv", |
| 460 | 464 |
.value = CODEC_ID_FLV1, |
| 461 | 465 |
}; |
| ... | ... |
@@ -144,7 +144,10 @@ static int64_t rtmp_read_seek(URLContext *s, int stream_index, |
| 144 | 144 |
return AVERROR(ENOSYS); |
| 145 | 145 |
|
| 146 | 146 |
/* seeks are in milliseconds */ |
| 147 |
- timestamp = av_rescale(timestamp, AV_TIME_BASE, 1000); |
|
| 147 |
+ if (stream_index < 0) |
|
| 148 |
+ timestamp = av_rescale_rnd(timestamp, 1000, AV_TIME_BASE, |
|
| 149 |
+ flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); |
|
| 150 |
+ |
|
| 148 | 151 |
if (!RTMP_SendSeek(r, timestamp)) |
| 149 | 152 |
return -1; |
| 150 | 153 |
return timestamp; |