changeset 1265:613fdf995af0 libavformat

read and use index (based on a patch by John Donaghy on the 23-03-2006 '[Ffmpeg-devel] dvr-ms seek help request')
author michael
date Wed, 23 Aug 2006 17:07:01 +0000
parents 3d00cb7b7426
children 5b9729f5145c
files asf.c
diffstat 1 files changed, 77 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/asf.c	Wed Aug 23 16:26:59 2006 +0000
+++ b/asf.c	Wed Aug 23 17:07:01 2006 +0000
@@ -837,16 +837,91 @@
     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;
 }