keyframe & non keyframe index fixes
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 13 Mar 2005 00:13:01 +0000 (00:13 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 13 Mar 2005 00:13:01 +0000 (00:13 +0000)
Originally committed as revision 4034 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/avformat.h
libavformat/mpeg.c
libavformat/utils.c

index d4daa03..137b8cf 100644 (file)
@@ -5,7 +5,7 @@
 extern "C" {
 #endif
 
-#define LIBAVFORMAT_BUILD       4621
+#define LIBAVFORMAT_BUILD       4622
 
 #define LIBAVFORMAT_VERSION_INT FFMPEG_VERSION_INT
 #define LIBAVFORMAT_VERSION     FFMPEG_VERSION
@@ -584,6 +584,7 @@ void av_set_pts_info(AVStream *s, int pts_wrap_bits,
 
 #define AVSEEK_FLAG_BACKWARD 1 ///< seek backward
 #define AVSEEK_FLAG_BYTE     2 ///< seeking based on position in bytes
+#define AVSEEK_FLAG_ANY      4 ///< seek to any frame, even non keyframes
 
 int av_find_default_stream_index(AVFormatContext *s);
 int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags);
index acb33dd..e9b5e9b 100644 (file)
@@ -1482,7 +1482,7 @@ static int mpegps_read_pes_header(AVFormatContext *s,
         int i;
         for(i=0; i<s->nb_streams; i++){
             if(startcode == s->streams[i]->id) {
-                av_add_index_entry(s->streams[i], *ppos, dts, 0, 0 /* FIXME keyframe? */);
+                av_add_index_entry(s->streams[i], *ppos, dts, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */);
             }
         }
     }
index fc49a6d..d2b6c94 100644 (file)
@@ -1024,7 +1024,7 @@ int av_add_index_entry(AVStream *st,
 
     st->index_entries= entries;
 
-    index= av_index_search_timestamp(st, timestamp, 0);
+    index= av_index_search_timestamp(st, timestamp, AVSEEK_FLAG_ANY);
 
     if(index<0){
         index= st->nb_index_entries++;
@@ -1090,13 +1090,14 @@ static int is_raw_stream(AVFormatContext *s)
 
 /**
  * gets the index for a specific timestamp.
- * @param backward if non zero then the returned index will correspond to 
+ * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond to 
  *                 the timestamp which is <= the requested one, if backward is 0 
  *                 then it will be >=
+ *              if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise
  * @return < 0 if no such timestamp could be found
  */
 int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp,
-                              int backward)
+                              int flags)
 {
     AVIndexEntry *entries= st->index_entries;
     int nb_entries= st->nb_index_entries;
@@ -1114,7 +1115,13 @@ int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp,
         if(timestamp <= wanted_timestamp)
             a = m;
     }
-    m= backward ? a : b;
+    m= (flags & AVSEEK_FLAG_BACKWARD) ? a : b;
+    
+    if(!(flags & AVSEEK_FLAG_ANY)){
+        while(m>=0 && m<nb_entries && !(entries[m].flags & AVINDEX_KEYFRAME)){
+            m += (flags & AVSEEK_FLAG_BACKWARD) ? -1 : 1;
+        }
+    }
 
     if(m == nb_entries) 
         return -1;
@@ -1152,7 +1159,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
     if(st->index_entries){
         AVIndexEntry *e;
 
-        index= av_index_search_timestamp(st, target_ts, 1);
+        index= av_index_search_timestamp(st, target_ts, flags | AVSEEK_FLAG_BACKWARD); //FIXME whole func must be checked for non keyframe entries in index case, especially read_timestamp()
         index= FFMAX(index, 0);
         e= &st->index_entries[index];
 
@@ -1166,8 +1173,10 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
         }else{
             assert(index==0);
         }
-        index++;
-        if(index < st->nb_index_entries){
+        
+        index= av_index_search_timestamp(st, target_ts, flags & ~AVSEEK_FLAG_BACKWARD); 
+        assert(index < st->nb_index_entries);
+        if(index >= 0){
             e= &st->index_entries[index];
             assert(e->timestamp >= target_ts);
             pos_max= e->pos;
@@ -1316,7 +1325,7 @@ static int av_seek_frame_generic(AVFormatContext *s,
     }
 
     st = s->streams[stream_index];
-    index = av_index_search_timestamp(st, timestamp, flags & AVSEEK_FLAG_BACKWARD);
+    index = av_index_search_timestamp(st, timestamp, flags);
     if (index < 0)
         return -1;