diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2006-08-23 17:07:01 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2006-08-23 17:07:01 +0000 |
commit | 56c96a229b383827808a993b90661130e4a2b537 (patch) | |
tree | 28b7d87883472ab282d660260ff1ee9e52e3d59c /libavformat/asf.c | |
parent | 052aa2ad3c1131754ed1cf56b3284f732977bcec (diff) | |
download | ffmpeg-56c96a229b383827808a993b90661130e4a2b537.tar.gz |
read and use index (based on a patch by John Donaghy on the 23-03-2006 '[Ffmpeg-devel] dvr-ms seek help request')
Originally committed as revision 6054 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/asf.c')
-rw-r--r-- | libavformat/asf.c | 81 |
1 files changed, 78 insertions, 3 deletions
diff --git a/libavformat/asf.c b/libavformat/asf.c index cf0742e315..587c139410 100644 --- a/libavformat/asf.c +++ b/libavformat/asf.c @@ -837,16 +837,91 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, return pts; } +static void asf_build_simple_index(AVFormatContext *s, int stream_index) +{ + GUID g; + ASFContext *asf = s->priv_data; + int64_t gsize, itime; + int64_t pos, current_pos, index_pts; + int i; + int pct,ict; + + current_pos = url_ftell(&s->pb); + + url_fseek(&s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET); + get_guid(&s->pb, &g); + if (!memcmp(&g, &index_guid, sizeof(GUID))) { + gsize = get_le64(&s->pb); + get_guid(&s->pb, &g); + itime=get_le64(&s->pb); + pct=get_le32(&s->pb); + ict=get_le32(&s->pb); + av_log(NULL, AV_LOG_DEBUG, "itime:0x%Lx, pct:%d, ict:%d\n",itime,pct,ict); + + for (i=0;i<ict;i++){ + int pktnum=get_le32(&s->pb); + int pktct =get_le16(&s->pb); + av_log(NULL, AV_LOG_DEBUG, "pktnum:%d, pktct:%d\n", pktnum, pktct); + + pos=s->data_offset + asf->packet_size*(int64_t)pktnum; + index_pts=av_rescale(itime, i, 10000); + + av_add_index_entry(s->streams[stream_index], pos, index_pts, asf->packet_size, 0, AVINDEX_KEYFRAME); + } + } + url_fseek(&s->pb, current_pos, SEEK_SET); +} + static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags) { ASFContext *asf = s->priv_data; + AVStream *st = s->streams[stream_index]; + int64_t pos; + int index; if (asf->packet_size <= 0) return -1; - if(av_seek_frame_binary(s, stream_index, pts, flags)<0) - return -1; - + if (!st->index_entries) + asf_build_simple_index(s, stream_index); + + if(!st->index_entries){ + if(av_seek_frame_binary(s, stream_index, pts, flags)<0) + return -1; + }else{ + index= av_index_search_timestamp(st, pts, flags); + if(index<0) + return -1; + + /* find the position */ + pos = st->index_entries[index].pos; + pts = st->index_entries[index].timestamp; + + // various attempts to find key frame have failed so far + // asf_reset_header(s); + // url_fseek(&s->pb, pos, SEEK_SET); + // key_pos = pos; + // for(i=0;i<16;i++){ + // pos = url_ftell(&s->pb); + // if (av_read_frame(s, &pkt) < 0){ + // av_log(s, AV_LOG_INFO, "seek failed\n"); + // return -1; + // } + // asf_st = s->streams[stream_index]->priv_data; + // pos += st->parser->frame_offset; + // + // if (pkt.size > b) { + // b = pkt.size; + // key_pos = pos; + // } + // + // av_free_packet(&pkt); + // } + + /* do the seek */ + av_log(NULL, AV_LOG_DEBUG, "SEEKTO: %Ld\n", pos); + url_fseek(&s->pb, pos, SEEK_SET); + } asf_reset_header(s); return 0; } |