changeset 977:8bb9cea3c2d3 libavformat

ODML index parsing support
author michael
date Wed, 01 Mar 2006 01:32:32 +0000
parents c4a67d8fa68f
children c168be36dbba
files avidec.c
diffstat 1 files changed, 68 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/avidec.c	Wed Mar 01 01:29:12 2006 +0000
+++ b/avidec.c	Wed Mar 01 01:32:32 2006 +0000
@@ -37,7 +37,7 @@
     int sample_size; /* audio only data */
     int start;
 
-    int cum_len; /* temporary storage (used during seek) */
+    int64_t cum_len; /* temporary storage (used during seek) */
 
     int prefix;                       ///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b'
     int prefix_count;
@@ -85,6 +85,65 @@
     return 0;
 }
 
+static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
+    ByteIOContext *pb = &s->pb;
+    int longs_pre_entry= get_le16(pb);
+    int index_sub_type = get_byte(pb);
+    int index_type     = get_byte(pb);
+    int entries_in_use = get_le32(pb);
+    int chunk_id       = get_le32(pb);
+    int64_t base       = get_le64(pb);
+    int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0');
+    AVStream *st;
+    AVIStream *ast;
+    int i;
+
+//    av_log(s, AV_LOG_ERROR, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%Ld\n",
+//        longs_pre_entry,index_type, entries_in_use, chunk_id, base);
+
+    if(stream_id > s->nb_streams || stream_id < 0)
+        return -1;
+    st= s->streams[stream_id];
+    ast = st->priv_data;
+
+    if(index_sub_type)
+        return -1;
+
+    get_le32(pb);
+
+    if(index_type && longs_pre_entry != 2)
+        return -1;
+    if(index_type>1)
+        return -1;
+
+    for(i=0; i<entries_in_use; i++){
+        if(index_type){
+            int64_t pos= get_le32(pb) + base;
+            int len    = get_le32(pb);
+
+            av_add_index_entry(st, pos, ast->cum_len, 0, (len<0) ? 0 : AVINDEX_KEYFRAME);
+            len &= 0x7FFFFFFF;
+
+            if(ast->sample_size)
+                ast->cum_len += len / ast->sample_size;
+            else
+                ast->cum_len ++;
+        }else{
+            int64_t offset= get_le64(pb);
+            int size      = get_le32(pb);
+            int duration  = get_le32(pb);
+            int64_t pos= url_ftell(pb);
+
+            url_fseek(pb, offset+8, SEEK_SET);
+            read_braindead_odml_indx(s, frame_num);
+            frame_num += duration;
+
+            url_fseek(pb, pos, SEEK_SET);
+        }
+    }
+    return 0;
+}
+
 static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
 {
     AVIContext *avi = s->priv_data;
@@ -326,6 +385,12 @@
                 }
             }
             break;
+        case MKTAG('i', 'n', 'd', 'x'):
+            i= url_ftell(pb);
+            read_braindead_odml_indx(s, 0);
+            avi->index_loaded=1;
+            url_fseek(pb, i+size, SEEK_SET);
+            break;
         default:
             /* skip tag */
             size += (size & 1);
@@ -344,8 +409,8 @@
         return -1;
     }
 
-    assert(!avi->index_loaded);
-    avi_load_index(s);
+    if(!avi->index_loaded)
+        avi_load_index(s);
     avi->index_loaded = 1;
 
     return 0;