From c57e5b8154f5fe1457f4c64e04885a2cdfb37f51 Mon Sep 17 00:00:00 2001 From: Joakim Plate 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 Signed-off-by: Thomas Petazzoni --- 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;inb_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