summaryrefslogtreecommitdiff
path: root/libavformat/utils.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2007-02-05 23:04:48 +0000
committerMichael Niedermayer <michaelni@gmx.at>2007-02-05 23:04:48 +0000
commite9b78eeba22b050810a507e69df1b652e56ab62b (patch)
treec63d266eb46b8f7d8a8c98e7ed39bd426aa48be8 /libavformat/utils.c
parent7ee829922b1053a2496e5f0849265c4cb9060baf (diff)
better generic index building and seeking code
Originally committed as revision 7841 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/utils.c')
-rw-r--r--libavformat/utils.c51
1 files changed, 40 insertions, 11 deletions
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 693a8ecd0f..30a082720e 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -788,6 +788,12 @@ static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
pkt->dts = st->parser->dts;
pkt->destruct = av_destruct_packet_nofree;
compute_pkt_fields(s, st, st->parser, pkt);
+
+ if((s->iformat->flags & AVFMT_GENERIC_INDEX) && pkt->flags & PKT_FLAG_KEY){
+ av_add_index_entry(st, st->parser->frame_offset, pkt->dts,
+ 0, 0, AVINDEX_KEYFRAME);
+ }
+
break;
}
} else {
@@ -836,6 +842,10 @@ static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
}else if(st->need_parsing == 2){
st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
}
+ if(st->parser && (s->iformat->flags & AVFMT_GENERIC_INDEX)){
+ st->parser->last_frame_offset=
+ st->parser->cur_offset= s->cur_pkt.pos;
+ }
}
}
}
@@ -1370,23 +1380,42 @@ static int av_seek_frame_generic(AVFormatContext *s,
AVStream *st;
AVIndexEntry *ie;
- if (!s->index_built) {
- if (is_raw_stream(s)) {
- av_build_index_raw(s);
- } else {
- return -1;
- }
- s->index_built = 1;
- }
-
st = s->streams[stream_index];
+
index = av_index_search_timestamp(st, timestamp, flags);
+
+ if(index < 0){
+ int i;
+ AVPacket pkt;
+
+ if(st->index_entries && st->nb_index_entries){
+ ie= &st->index_entries[st->nb_index_entries-1];
+ url_fseek(&s->pb, ie->pos, SEEK_SET);
+ av_update_cur_dts(s, st, ie->timestamp);
+ }else
+ url_fseek(&s->pb, 0, SEEK_SET);
+
+ for(i=0;; i++) {
+ int ret = av_read_frame(s, &pkt);
+ if(ret<0)
+ break;
+ av_free_packet(&pkt);
+ if(stream_index == pkt.stream_index){
+ if((pkt.flags & PKT_FLAG_KEY) && pkt.dts > timestamp)
+ break;
+ }
+ }
+ index = av_index_search_timestamp(st, timestamp, flags);
+ }
if (index < 0)
return -1;
- /* now we have found the index, we can seek */
- ie = &st->index_entries[index];
av_read_frame_flush(s);
+ if (s->iformat->read_seek){
+ if(s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0)
+ return 0;
+ }
+ ie = &st->index_entries[index];
url_fseek(&s->pb, ie->pos, SEEK_SET);
av_update_cur_dts(s, st, ie->timestamp);