#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)
* 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 {
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
{"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},
};
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);
}
}
}
+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)
{