diff utils.c @ 346:e154eb1b7149 libavformat

caching of timestamps for mpeg-ps so seeking is faster move (av_)find_stream_index() to utils.c as its usefull outside mpeg.c assert checking enabled, to find bugs quicker, should obviously be disabled later (av_)add_index_entry() inserts new entries so that the list stays ordered and updates entries if already in it (av_)index_search_timestamp() cleanup (kill ugly goto) and shorter
author michael
date Tue, 13 Jan 2004 22:02:49 +0000
parents 7f089db11f9a
children 6770ca07abe2
line wrap: on
line diff
--- a/utils.c	Mon Jan 12 22:14:45 2004 +0000
+++ b/utils.c	Tue Jan 13 22:02:49 2004 +0000
@@ -18,6 +18,9 @@
  */
 #include "avformat.h"
 
+#undef NDEBUG
+#include <assert.h>
+
 AVInputFormat *first_iformat;
 AVOutputFormat *first_oformat;
 AVImageFormat *first_image_format;
@@ -811,6 +814,22 @@
 /*******************************************************/
 /* seek support */
 
+int av_find_default_stream_index(AVFormatContext *s)
+{
+    int i;
+    AVStream *st;
+
+    if (s->nb_streams <= 0)
+        return -1;
+    for(i = 0; i < s->nb_streams; i++) {
+        st = s->streams[i];
+        if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
+            return i;
+        }
+    }
+    return 0;
+}
+
 /* flush the frame reader */
 static void av_read_frame_flush(AVFormatContext *s)
 {
@@ -841,22 +860,42 @@
     }
 }
 
-static void add_index_entry(AVStream *st,
+/* add a index entry into a sorted list updateing if it is already there */
+void av_add_index_entry(AVStream *st,
                             int64_t pos, int64_t timestamp, int flags)
 {
     AVIndexEntry *entries, *ie;
+    int index;
     
     entries = av_fast_realloc(st->index_entries,
                               &st->index_entries_allocated_size,
                               (st->nb_index_entries + 1) * 
                               sizeof(AVIndexEntry));
-    if (entries) {
-        st->index_entries = entries;
-        ie = &entries[st->nb_index_entries++];
-        ie->pos = pos;
-        ie->timestamp = timestamp;
-        ie->flags = flags;
-    }
+    st->index_entries= entries;
+
+    if(st->nb_index_entries){
+        index= av_index_search_timestamp(st, timestamp);
+        ie= &entries[index];
+
+        if(ie->timestamp != timestamp){
+            if(ie->timestamp < timestamp){
+                index++; //index points to next instead of previous entry, maybe nonexistant
+                ie= &st->index_entries[index];
+            }else
+                assert(index==0);
+                
+            if(index != st->nb_index_entries){
+                assert(index < st->nb_index_entries);
+                memmove(entries + index + 1, entries + index, sizeof(AVIndexEntry)*(st->nb_index_entries - index));
+            }
+            st->nb_index_entries++;
+        }
+    }else
+        ie= &entries[st->nb_index_entries++];
+    
+    ie->pos = pos;
+    ie->timestamp = timestamp;
+    ie->flags = flags;
 }
 
 /* build an index for raw streams using a parser */
@@ -876,7 +915,7 @@
             break;
         if (pkt->stream_index == 0 && st->parser &&
             (pkt->flags & PKT_FLAG_KEY)) {
-            add_index_entry(st, st->parser->frame_offset, pkt->dts, 
+            av_add_index_entry(st, st->parser->frame_offset, pkt->dts, 
                             AVINDEX_KEYFRAME);
         }
         av_free_packet(pkt);
@@ -899,9 +938,10 @@
 
 /* return the largest index entry whose timestamp is <=
    wanted_timestamp */
-static int index_search_timestamp(AVIndexEntry *entries, 
-                                  int nb_entries, int wanted_timestamp)
+int av_index_search_timestamp(AVStream *st, int wanted_timestamp)
 {
+    AVIndexEntry *entries= st->index_entries;
+    int nb_entries= st->nb_index_entries;
     int a, b, m;
     int64_t timestamp;
 
@@ -910,22 +950,17 @@
     
     a = 0;
     b = nb_entries - 1;
-    while (a <= b) {
-        m = (a + b) >> 1;
+
+    while (a < b) {
+        m = (a + b + 1) >> 1;
         timestamp = entries[m].timestamp;
-        if (timestamp == wanted_timestamp)
-            goto found;
-        else if (timestamp > wanted_timestamp) {
+        if (timestamp > wanted_timestamp) {
             b = m - 1;
         } else {
-            a = m + 1;
+            a = m;
         }
     }
-    m = a;
-    if (m > 0)
-        m--;
- found:
-    return m;
+    return a;
 }
 
 static int av_seek_frame_generic(AVFormatContext *s, 
@@ -947,8 +982,7 @@
     if (stream_index < 0)
         stream_index = 0;
     st = s->streams[stream_index];
-    index = index_search_timestamp(st->index_entries, st->nb_index_entries,
-                                   timestamp);
+    index = av_index_search_timestamp(st, timestamp);
     if (index < 0)
         return -1;