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
Unified · Split
| @@ -449,6 +449,39 @@ leave: · 448 unmodified lines | |||
| 449 | return ret; | 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 | AVInputFormat flv_demuxer = { | 485 | AVInputFormat flv_demuxer = { |
| 453 | "flv", | 486 | "flv", |
| 454 | NULL_IF_CONFIG_SMALL("FLV format"), | 487 | NULL_IF_CONFIG_SMALL("FLV format"), |
| @@ -456,6 +489,10 @@ AVInputFormat flv_demuxer = { · 1 unmodified line | |||
| 456 | flv_probe, | 489 | flv_probe, |
| 457 | flv_read_header, | 490 | flv_read_header, |
| 458 | flv_read_packet, | 491 | flv_read_packet, |
| 492 | .read_seek = flv_read_seek, | ||
| 493 | #if 0 | ||
| 494 | .read_seek2 = flv_read_seek2, | ||
| 495 | #endif | ||
| 459 | .extensions = "flv", | 496 | .extensions = "flv", |
| 460 | .value = CODEC_ID_FLV1, | 497 | .value = CODEC_ID_FLV1, |
| 461 | }; | 498 | }; |
| @@ -144,7 +144,10 @@ static int64_t rtmp_read_seek(URLContext *s, int stream_index, · 143 unmodified lines | |||
| 144 | return AVERROR(ENOSYS); | 144 | return AVERROR(ENOSYS); |
| 145 | 145 | ||
| 146 | /* seeks are in milliseconds */ | 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 | if (!RTMP_SendSeek(r, timestamp)) | 151 | if (!RTMP_SendSeek(r, timestamp)) |
| 149 | return -1; | 152 | return -1; |
| 150 | return timestamp; | 153 | return timestamp; |