| From c57e5b8154f5fe1457f4c64e04885a2cdfb37f51 Mon Sep 17 00:00:00 2001 |
| From: Joakim Plate <elupus@ecce.se> |
| Date: Sat, 22 Oct 2011 19:01:38 +0200 |
| Subject: [PATCH 08/13] Get stream durations using read_timestamp |
| |
| Patch part of the XBMC patch set for ffmpeg, downloaded from |
| https://github.com/xbmc/FFmpeg/. |
| |
| Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de> |
| Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> |
| --- |
| libavformat/utils.c | 39 +++++++++++++++++++++++++++++++++++++++ |
| 1 file changed, 39 insertions(+) |
| |
| diff --git a/libavformat/utils.c b/libavformat/utils.c |
| index 3e8af50..f4fb172 100644 |
| --- a/libavformat/utils.c |
| +++ b/libavformat/utils.c |
| @@ -2356,6 +2356,41 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic) |
| #define DURATION_MAX_READ_SIZE 250000LL |
| #define DURATION_MAX_RETRY 4 |
| |
| +static void av_estimate_timings_from_pts2(AVFormatContext *ic, int64_t old_offset) |
| +{ |
| + AVStream *st; |
| + int i, step= 1024; |
| + int64_t ts, pos; |
| + |
| + for(i=0;i<ic->nb_streams;i++) { |
| + st = ic->streams[i]; |
| + |
| + pos = 0; |
| + ts = ic->iformat->read_timestamp(ic, i, &pos, DURATION_MAX_READ_SIZE); |
| + if (ts == AV_NOPTS_VALUE) |
| + continue; |
| + if (st->start_time > ts || st->start_time == AV_NOPTS_VALUE) |
| + st->start_time = ts; |
| + |
| + pos = avio_size(ic->pb) - 1; |
| + do { |
| + pos -= step; |
| + ts = ic->iformat->read_timestamp(ic, i, &pos, pos + step); |
| + step += step; |
| + } while (ts == AV_NOPTS_VALUE && pos >= step && step < DURATION_MAX_READ_SIZE); |
| + |
| + if (ts == AV_NOPTS_VALUE) |
| + continue; |
| + |
| + if (st->duration < ts - st->start_time || st->duration == AV_NOPTS_VALUE) |
| + st->duration = ts - st->start_time; |
| + } |
| + |
| + fill_all_stream_timings(ic); |
| + |
| + avio_seek(ic->pb, old_offset, SEEK_SET); |
| +} |
| + |
| /* only usable for MPEG-PS streams */ |
| static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) |
| { |
| @@ -2506,6 +2541,10 @@ static void estimate_timings(AVFormatContext *ic, int64_t old_offset) |
| * the components */ |
| fill_all_stream_timings(ic); |
| ic->duration_estimation_method = AVFMT_DURATION_FROM_STREAM; |
| + } else if (ic->iformat->read_timestamp && |
| + file_size && ic->pb->seekable) { |
| + /* get accurate estimate from the PTSes */ |
| + av_estimate_timings_from_pts2(ic, old_offset); |
| } else { |
| /* less precise: use bitrate info */ |
| estimate_timings_from_bit_rate(ic); |
| -- |
| 2.1.0 |
| |