# HG changeset patch # User michael # Date 1200231217 0 # Node ID f5de41d943e2f7f4aab7e01683e9e43a56942127 # Parent 83790e20f993d9adf9487d1c59547f1daeef805b user specifyable maximum amount of memory to use for the index. patch by Paul Kelly paul stjohnspoint co uk with some changes by me diff -r 83790e20f993 -r f5de41d943e2 avformat.h --- a/avformat.h Sat Jan 12 11:25:54 2008 +0000 +++ b/avformat.h Sun Jan 13 13:33:37 2008 +0000 @@ -21,8 +21,8 @@ #ifndef FFMPEG_AVFORMAT_H #define FFMPEG_AVFORMAT_H -#define LIBAVFORMAT_VERSION_INT ((52<<16)+(3<<8)+0) -#define LIBAVFORMAT_VERSION 52.3.0 +#define LIBAVFORMAT_VERSION_INT ((52<<16)+(4<<8)+0) +#define LIBAVFORMAT_VERSION 52.4.0 #define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT #define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION) @@ -477,6 +477,18 @@ * demuxing: set by user */ enum CodecID subtitle_codec_id; + + /** + * Maximum amount of memory in bytes to use per stream for the index. + * If the needed index exceeds this size entries will be discarded as + * needed to maintain a smaller size. This can lead to slower or less + * accurate seeking (depends on demuxer). + * Demuxers for which a full in memory index is mandatory will ignore + * this. + * muxing : unused + * demuxing: set by user + */ + unsigned int max_index_size; } AVFormatContext; typedef struct AVPacketList { @@ -736,6 +748,15 @@ int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags); /** + * Ensures the index uses less memory than the maximum specified in + * AVFormatContext.max_index_size, by discarding entries if it grows + * too large. + * This function is not part of the public API and should only be called + * by demuxers. + */ +void ff_reduce_index(AVFormatContext *s, int stream_index); + +/** * Add a index entry into a sorted list updateing if it is already there. * * @param timestamp timestamp in the timebase of the given stream diff -r 83790e20f993 -r f5de41d943e2 mpeg.c --- a/mpeg.c Sat Jan 12 11:25:54 2008 +0000 +++ b/mpeg.c Sun Jan 13 13:33:37 2008 +0000 @@ -386,6 +386,7 @@ int i; for(i=0; inb_streams; i++){ if(startcode == s->streams[i]->id) { + ff_reduce_index(s, i); av_add_index_entry(s->streams[i], *ppos, dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */); } } diff -r 83790e20f993 -r f5de41d943e2 utils.c --- a/utils.c Sat Jan 12 11:25:54 2008 +0000 +++ b/utils.c Sun Jan 13 13:33:37 2008 +0000 @@ -324,6 +324,7 @@ {"year", "set the year", OFFSET(year), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, E}, {"analyzeduration", "how many microseconds are analyzed to estimate duration", OFFSET(max_analyze_duration), FF_OPT_TYPE_INT, 3*AV_TIME_BASE, 0, INT_MAX, D}, {"cryptokey", "decryption key", OFFSET(key), FF_OPT_TYPE_BINARY, 0, 0, 0, D}, +{"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), FF_OPT_TYPE_INT, INT_MAX, 0, INT_MAX, D}, {NULL}, }; @@ -791,6 +792,7 @@ compute_pkt_fields(s, st, st->parser, pkt); if((s->iformat->flags & AVFMT_GENERIC_INDEX) && pkt->flags & PKT_FLAG_KEY){ + ff_reduce_index(s, st->index); av_add_index_entry(st, st->parser->frame_offset, pkt->dts, 0, 0, AVINDEX_KEYFRAME); } @@ -1008,6 +1010,19 @@ } } +void ff_reduce_index(AVFormatContext *s, int stream_index) +{ + AVStream *st= s->streams[stream_index]; + unsigned int max_entries= s->max_index_size / sizeof(AVIndexEntry); + + if((unsigned)st->nb_index_entries >= max_entries){ + int i; + for(i=0; 2*inb_index_entries; i++) + st->index_entries[i]= st->index_entries[2*i]; + st->nb_index_entries= i; + } +} + int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags) {