summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2006-08-23 17:07:01 +0000
committerMichael Niedermayer <michaelni@gmx.at>2006-08-23 17:07:01 +0000
commit56c96a229b383827808a993b90661130e4a2b537 (patch)
tree28b7d87883472ab282d660260ff1ee9e52e3d59c
parent052aa2ad3c1131754ed1cf56b3284f732977bcec (diff)
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
-rw-r--r--libavformat/asf.c81
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;
}