[FFmpeg-devel] [PATCH 12/12] asfdec: read the index while reading the header, not on first seek

Anton Khirnov anton
Wed Feb 9 21:56:02 CET 2011


it makes more sense and gets rid of a variable from ASFContext.

asf_build_simple_index() is changed to use ASFContext.data_ofsset
instead of AVFormatContext.data_offset, since the latter isn't set yet.
---
 libavformat/asfdec.c |  136 ++++++++++++++++++++++++--------------------------
 1 files changed, 66 insertions(+), 70 deletions(-)

diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index 648dbd5..677d35a 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -44,7 +44,6 @@ typedef struct {
     uint64_t data_offset;                ///< beginning of the first data packet
     uint64_t data_object_offset;         ///< data object offset (excl. GUID & size)
     uint64_t data_object_size;           ///< size of the data object
-    int index_read;
 
     ASFMainHeader hdr;
 
@@ -563,6 +562,69 @@ static int asf_read_marker(AVFormatContext *s, int64_t size)
     return 0;
 }
 
+static void asf_build_simple_index(AVFormatContext *s)
+{
+    ff_asf_guid g;
+    ASFContext *asf = s->priv_data;
+    int64_t current_pos= url_ftell(s->pb);
+    int i, stream_index = 0;
+    AVStream *st;
+
+    url_fseek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET);
+    ff_get_guid(s->pb, &g);
+
+    /* the data object can be followed by other top-level objects,
+       skip them until the simple index object is reached */
+    while (ff_guidcmp(&g, &ff_asf_guid_simple_index)) {
+        int64_t gsize= get_le64(s->pb);
+        if (gsize < 24 || url_feof(s->pb)) {
+            url_fseek(s->pb, current_pos, SEEK_SET);
+            return;
+        }
+        url_fseek(s->pb, gsize-24, SEEK_CUR);
+        ff_get_guid(s->pb, &g);
+    }
+
+    while (!ff_guidcmp(&g, &ff_asf_guid_simple_index)) {
+        int64_t itime, last_pos=-1;
+        int pct, ict;
+        int64_t av_unused gsize= get_le64(s->pb);
+        ff_get_guid(s->pb, &g);
+        itime=get_le64(s->pb);
+        pct=get_le32(s->pb);
+        ict=get_le32(s->pb);
+        av_log(s, AV_LOG_DEBUG, "itime:0x%"PRIx64", pct:%d, ict:%d\n",itime,pct,ict);
+
+        /* find next video stream */
+        for (i = stream_index; i < s->nb_streams; i++) {
+            st = s->streams[i];
+            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+                stream_index = i;
+                break;
+            }
+        }
+        if (i == s->nb_streams) {
+            av_log(s, AV_LOG_ERROR, "Found an index not corresponding to any stream.\n");
+            return;
+        }
+
+        for (i=0;i<ict;i++){
+            int pktnum=get_le32(s->pb);
+            int pktct =get_le16(s->pb);
+            int64_t pos      = asf->data_offset + s->packet_size*(int64_t)pktnum;
+            int64_t index_pts= av_rescale(itime, i, 10000);
+
+            if(pos != last_pos){
+            av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d\n", pktnum, pktct);
+            av_add_index_entry(st, pos, index_pts, s->packet_size, 0, AVINDEX_KEYFRAME);
+            last_pos=pos;
+            }
+        }
+        ff_get_guid(s->pb, &g);
+    }
+    url_fseek(s->pb, current_pos, SEEK_SET);
+}
+
 static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
 {
     ASFContext *asf = s->priv_data;
@@ -650,6 +712,8 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
     asf->data_offset = url_ftell(pb);
     asf->packet_size_left = 0;
 
+    if (!(url_is_streamed(s->pb) || s->flags & AVFMT_FLAG_IGNIDX))
+        asf_build_simple_index(s);
 
     for(i=0; i<128; i++){
         int stream_num= asf->asfid2avid[i];
@@ -1145,73 +1209,8 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos,
     return pts;
 }
 
-static void asf_build_simple_index(AVFormatContext *s)
-{
-    ff_asf_guid g;
-    ASFContext *asf = s->priv_data;
-    int64_t current_pos= url_ftell(s->pb);
-    int i, stream_index = 0;
-    AVStream *st;
-
-    url_fseek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET);
-    ff_get_guid(s->pb, &g);
-
-    /* the data object can be followed by other top-level objects,
-       skip them until the simple index object is reached */
-    while (ff_guidcmp(&g, &ff_asf_guid_simple_index)) {
-        int64_t gsize= get_le64(s->pb);
-        if (gsize < 24 || url_feof(s->pb)) {
-            url_fseek(s->pb, current_pos, SEEK_SET);
-            return;
-        }
-        url_fseek(s->pb, gsize-24, SEEK_CUR);
-        ff_get_guid(s->pb, &g);
-    }
-
-    while (!ff_guidcmp(&g, &ff_asf_guid_simple_index)) {
-        int64_t itime, last_pos=-1;
-        int pct, ict;
-        int64_t av_unused gsize= get_le64(s->pb);
-        ff_get_guid(s->pb, &g);
-        itime=get_le64(s->pb);
-        pct=get_le32(s->pb);
-        ict=get_le32(s->pb);
-        av_log(s, AV_LOG_DEBUG, "itime:0x%"PRIx64", pct:%d, ict:%d\n",itime,pct,ict);
-
-        /* find next video stream */
-        for (i = stream_index; i < s->nb_streams; i++) {
-            st = s->streams[i];
-            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
-                stream_index = i;
-                break;
-            }
-        }
-        if (i == s->nb_streams) {
-            av_log(s, AV_LOG_ERROR, "Found an index not corresponding to any stream.\n");
-            return;
-        }
-
-        for (i=0;i<ict;i++){
-            int pktnum=get_le32(s->pb);
-            int pktct =get_le16(s->pb);
-            int64_t pos      = s->data_offset + s->packet_size*(int64_t)pktnum;
-            int64_t index_pts= av_rescale(itime, i, 10000);
-
-            if(pos != last_pos){
-            av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d\n", pktnum, pktct);
-            av_add_index_entry(st, pos, index_pts, s->packet_size, 0, AVINDEX_KEYFRAME);
-            last_pos=pos;
-            }
-        }
-        asf->index_read= 1;
-        ff_get_guid(s->pb, &g);
-    }
-    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;
@@ -1228,10 +1227,7 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int
             return ret;
     }
 
-    if (!asf->index_read)
-        asf_build_simple_index(s);
-
-    if(!(asf->index_read && st->index_entries)){
+    if(!st->index_entries){
         if(av_seek_frame_binary(s, stream_index, pts, flags)<0)
             return -1;
     }else{
-- 
1.7.2.3




More information about the ffmpeg-devel mailing list