[FFmpeg-cvslog] avidec: infer absolute vs relative index from first packet

Alex Converse git at videolan.org
Sun Jul 3 03:20:23 CEST 2011


ffmpeg | branch: master | Alex Converse <alex.converse at gmail.com> | Wed Jun  1 17:33:38 2011 -0700| [d3f610c186b6e8430e4cf97667750e720f6983c8] | committer: Alex Converse

avidec: infer absolute vs relative index from first packet

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d3f610c186b6e8430e4cf97667750e720f6983c8
---

 libavformat/avidec.c |   30 +++++++++++++++++++++++-------
 1 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index 7e509ce..871da0b 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -836,7 +836,7 @@ static int get_stream_idx(int *d){
     }
 }
 
-static int avi_sync(AVFormatContext *s)
+static int avi_sync(AVFormatContext *s, int exit_early)
 {
     AVIContext *avi = s->priv_data;
     AVIOContext *pb = s->pb;
@@ -916,7 +916,9 @@ start_sync:
             if(   (st->discard >= AVDISCARD_DEFAULT && size==0)
                /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering
                || st->discard >= AVDISCARD_ALL){
-                ast->frame_offset += get_duration(ast, size);
+                if (!exit_early) {
+                    ast->frame_offset += get_duration(ast, size);
+                }
                 avio_skip(pb, size);
                 goto start_sync;
             }
@@ -936,6 +938,8 @@ start_sync:
                          (d[2] == 'd' && d[3] == 'c') ||
                          (d[2] == 'w' && d[3] == 'b')*/) {
 
+                if (exit_early)
+                    return 0;
 //av_log(s, AV_LOG_DEBUG, "OK\n");
                 if(d[2]*256+d[3] == ast->prefix)
                     ast->prefix_count++;
@@ -1117,7 +1121,7 @@ resync:
         return size;
     }
 
-    if ((err = avi_sync(s)) < 0)
+    if ((err = avi_sync(s, 0)) < 0)
         return err;
     goto resync;
 }
@@ -1131,13 +1135,22 @@ static int avi_read_idx1(AVFormatContext *s, int size)
     int nb_index_entries, i;
     AVStream *st;
     AVIStream *ast;
-    unsigned int index, tag, flags, pos, len;
+    unsigned int index, tag, flags, pos, len, first_packet = 1;
     unsigned last_pos= -1;
+    int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
 
     nb_index_entries = size / 16;
     if (nb_index_entries <= 0)
         return -1;
 
+    idx1_pos = avio_tell(pb);
+    avio_seek(pb, avi->movi_list+4, SEEK_SET);
+    if (avi_sync(s, 1) == 0) {
+        first_packet_pos = avio_tell(pb) - 8;
+    }
+    avi->stream_index = -1;
+    avio_seek(pb, idx1_pos, SEEK_SET);
+
     /* Read the entries and sort them in each stream component. */
     for(i = 0; i < nb_index_entries; i++) {
         tag = avio_rl32(pb);
@@ -1146,9 +1159,6 @@ static int avi_read_idx1(AVFormatContext *s, int size)
         len = avio_rl32(pb);
         av_dlog(s, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
                 i, tag, flags, pos, len);
-        if(i==0 && pos > avi->movi_list)
-            avi->movi_list= 0; //FIXME better check
-        pos += avi->movi_list;
 
         index = ((tag & 0xff) - '0') * 10;
         index += ((tag >> 8) & 0xff) - '0';
@@ -1157,6 +1167,12 @@ static int avi_read_idx1(AVFormatContext *s, int size)
         st = s->streams[index];
         ast = st->priv_data;
 
+        if(first_packet && first_packet_pos && len) {
+            data_offset = first_packet_pos - pos;
+            first_packet = 0;
+        }
+        pos += data_offset;
+
         av_dlog(s, "%d cum_len=%"PRId64"\n", len, ast->cum_len);
 
         if(pb->eof_reached)



More information about the ffmpeg-cvslog mailing list