avidec: infer absolute vs relative index from first packet
authorAlex Converse <alex.converse@gmail.com>
Thu, 2 Jun 2011 00:33:38 +0000 (17:33 -0700)
committerAlex Converse <alex.converse@gmail.com>
Fri, 1 Jul 2011 23:08:21 +0000 (16:08 -0700)
libavformat/avidec.c

index 7e509ce..871da0b 100644 (file)
@@ -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;
 {
     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){
             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;
             }
                 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')*/) {
 
                          (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++;
 //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;
     }
 
         return size;
     }
 
-    if ((err = avi_sync(s)) < 0)
+    if ((err = avi_sync(s, 0)) < 0)
         return err;
     goto resync;
 }
         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;
     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;
     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;
 
 
     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);
     /* 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);
         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';
 
         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;
 
         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)
         av_dlog(s, "%d cum_len=%"PRId64"\n", len, ast->cum_len);
 
         if(pb->eof_reached)