diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2004-01-13 22:02:49 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2004-01-13 22:02:49 +0000 |
commit | b754978a3b0aa17e7794f64c69bf4491762797fd (patch) | |
tree | 6ce15dcec2032989161883a4b08aab74777b7e92 /libavformat/mpeg.c | |
parent | 6245598582f74240360113f1d58945c6093b7060 (diff) | |
download | ffmpeg-b754978a3b0aa17e7794f64c69bf4491762797fd.tar.gz |
caching of timestamps for mpeg-ps so seeking is faster
move (av_)find_stream_index() to utils.c as its usefull outside mpeg.c
assert checking enabled, to find bugs quicker, should obviously be disabled later
(av_)add_index_entry() inserts new entries so that the list stays ordered and updates entries if already in it
(av_)index_search_timestamp() cleanup (kill ugly goto) and shorter
Originally committed as revision 2697 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/mpeg.c')
-rw-r--r-- | libavformat/mpeg.c | 89 |
1 files changed, 62 insertions, 27 deletions
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index 5fcc7f6084..5bd7215d6c 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -21,6 +21,9 @@ #define MAX_PAYLOAD_SIZE 4096 //#define DEBUG_SEEK +#undef NDEBUG +#include <assert.h> + typedef struct { uint8_t buffer[MAX_PAYLOAD_SIZE]; int buffer_ptr; @@ -902,6 +905,15 @@ static int mpegps_read_pes_header(AVFormatContext *s, len -= 3; } } + if(dts != AV_NOPTS_VALUE && ppos){ + int i; + for(i=0; i<s->nb_streams; i++){ + if(startcode == s->streams[i]->id) { + av_add_index_entry(s->streams[i], *ppos, dts, 0 /* FIXME keyframe? */); + } + } + } + *pstart_code = startcode; *ppts = pts; *pdts = dts; @@ -913,10 +925,10 @@ static int mpegps_read_packet(AVFormatContext *s, { AVStream *st; int len, startcode, i, type, codec_id; - int64_t pts, dts; + int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work redo: - len = mpegps_read_pes_header(s, NULL, &startcode, &pts, &dts, 1); + len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts, 1); if (len < 0) return len; @@ -1022,27 +1034,13 @@ static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, return dts; } -static int find_stream_index(AVFormatContext *s) -{ - int i; - AVStream *st; - - if (s->nb_streams <= 0) - return -1; - for(i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - if (st->codec.codec_type == CODEC_TYPE_VIDEO) { - return i; - } - } - return 0; -} - static int mpegps_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp) { int64_t pos_min, pos_max, pos; int64_t dts_min, dts_max, dts; + int index; + AVStream *st; timestamp = (timestamp * 90000) / AV_TIME_BASE; @@ -1052,19 +1050,56 @@ static int mpegps_read_seek(AVFormatContext *s, /* XXX: find stream_index by looking at the first PES packet found */ if (stream_index < 0) { - stream_index = find_stream_index(s); + stream_index = av_find_default_stream_index(s); if (stream_index < 0) return -1; } - pos_min = 0; - dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1); - if (dts_min == AV_NOPTS_VALUE) { - /* we can reach this case only if no PTS are present in - the whole stream */ - return -1; + + dts_max= + dts_min= AV_NOPTS_VALUE; + + st= s->streams[stream_index]; + if(st->index_entries){ + AVIndexEntry *e; + + index= av_index_search_timestamp(st, timestamp); + e= &st->index_entries[index]; + if(e->timestamp <= timestamp){ + pos_min= e->pos; + dts_min= e->timestamp; +#ifdef DEBUG_SEEK + printf("unsing cached pos_min=0x%llx dts_min=%0.3f\n", + pos_min,dts_min / 90000.0); +#endif + }else{ + assert(index==0); + } + index++; + if(index < st->nb_index_entries){ + e= &st->index_entries[index]; + assert(e->timestamp >= timestamp); + pos_max= e->pos; + dts_max= e->timestamp; +#ifdef DEBUG_SEEK + printf("unsing cached pos_max=0x%llx dts_max=%0.3f\n", + pos_max,dts_max / 90000.0); +#endif + } + } + + if(dts_min == AV_NOPTS_VALUE){ + pos_min = 0; + dts_min = mpegps_read_dts(s, stream_index, &pos_min, 1); + if (dts_min == AV_NOPTS_VALUE) { + /* we can reach this case only if no PTS are present in + the whole stream */ + return -1; + } + } + if(dts_max == AV_NOPTS_VALUE){ + pos_max = url_filesize(url_fileno(&s->pb)) - 1; + dts_max = mpegps_read_dts(s, stream_index, &pos_max, 0); } - pos_max = url_filesize(url_fileno(&s->pb)) - 1; - dts_max = mpegps_read_dts(s, stream_index, &pos_max, 0); while (pos_min <= pos_max) { #ifdef DEBUG_SEEK |