summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Kelly <paul@stjohnspoint.co.uk>2008-01-13 13:33:37 +0000
committerMichael Niedermayer <michaelni@gmx.at>2008-01-13 13:33:37 +0000
commit3dea63bd7e611b625d135fe9bc8b3cef891bc757 (patch)
treeac9bb100ccb98d185503c44954626f481486ead8
parent3ed546fe525eace861e708ab970cf91f69bfdd09 (diff)
user specifyable maximum amount of memory to use for the index.
patch by Paul Kelly paul stjohnspoint co uk with some changes by me Originally committed as revision 11521 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavformat/avformat.h25
-rw-r--r--libavformat/mpeg.c1
-rw-r--r--libavformat/utils.c15
3 files changed, 39 insertions, 2 deletions
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index e303d48728..de622312a9 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -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 @@ typedef struct AVFormatContext {
* 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_find_default_stream_index(AVFormatContext *s);
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 --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index d044d07f41..aca9db2bb9 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -386,6 +386,7 @@ static int mpegps_read_pes_header(AVFormatContext *s,
int i;
for(i=0; i<s->nb_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 --git a/libavformat/utils.c b/libavformat/utils.c
index ea47bcf014..d116e845dd 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -324,6 +324,7 @@ static const AVOption options[]={
{"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 @@ static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
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 av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp){
}
}
+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*i<st->nb_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)
{