changeset 1496:7e288adde245 libavformat

split av_seek_frame_binary() so the code becomes idependant of AVInputFormat and AVIndex
author michael
date Tue, 14 Nov 2006 01:34:36 +0000
parents 04909cf98da7
children a561635afa61
files avformat.h utils.c
diffstat 2 files changed, 37 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/avformat.h	Tue Nov 14 01:05:31 2006 +0000
+++ b/avformat.h	Tue Nov 14 01:34:36 2006 +0000
@@ -445,6 +445,7 @@
                        int64_t pos, int64_t timestamp, int size, int distance, int flags);
 int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags);
 void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp);
+int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ));
 
 /* media file output */
 int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);
--- a/utils.c	Tue Nov 14 01:05:31 2006 +0000
+++ b/utils.c	Tue Nov 14 01:34:36 2006 +0000
@@ -1163,8 +1163,7 @@
     AVInputFormat *avif= s->iformat;
     int64_t pos_min, pos_max, pos, pos_limit;
     int64_t ts_min, ts_max, ts;
-    int64_t start_pos, filesize;
-    int index, no_change;
+    int index;
     AVStream *st;
 
     if (stream_index < 0)
@@ -1212,9 +1211,36 @@
         }
     }
 
+    pos= av_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, ts_min, ts_max, flags, &ts, avif->read_timestamp);
+    if(pos<0)
+        return -1;
+
+    /* do the seek */
+    url_fseek(&s->pb, pos, SEEK_SET);
+
+    av_update_cur_dts(s, st, ts);
+
+    return 0;
+}
+
+/**
+ * Does a binary search using read_timestamp().
+ * this isnt supposed to be called directly by a user application, but by demuxers
+ * @param target_ts target timestamp in the time base of the given stream
+ * @param stream_index stream number
+ */
+int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )){
+    int64_t pos, ts;
+    int64_t start_pos, filesize;
+    int no_change;
+
+#ifdef DEBUG_SEEK
+    av_log(s, AV_LOG_DEBUG, "gen_seek: %d %"PRId64"\n", stream_index, target_ts);
+#endif
+
     if(ts_min == AV_NOPTS_VALUE){
         pos_min = s->data_offset;
-        ts_min = avif->read_timestamp(s, stream_index, &pos_min, INT64_MAX);
+        ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
         if (ts_min == AV_NOPTS_VALUE)
             return -1;
     }
@@ -1225,7 +1251,7 @@
         pos_max = filesize - 1;
         do{
             pos_max -= step;
-            ts_max = avif->read_timestamp(s, stream_index, &pos_max, pos_max + step);
+            ts_max = read_timestamp(s, stream_index, &pos_max, pos_max + step);
             step += step;
         }while(ts_max == AV_NOPTS_VALUE && pos_max >= step);
         if (ts_max == AV_NOPTS_VALUE)
@@ -1233,7 +1259,7 @@
 
         for(;;){
             int64_t tmp_pos= pos_max + 1;
-            int64_t tmp_ts= avif->read_timestamp(s, stream_index, &tmp_pos, INT64_MAX);
+            int64_t tmp_ts= read_timestamp(s, stream_index, &tmp_pos, INT64_MAX);
             if(tmp_ts == AV_NOPTS_VALUE)
                 break;
             ts_max= tmp_ts;
@@ -1277,7 +1303,7 @@
             pos= pos_limit;
         start_pos= pos;
 
-        ts = avif->read_timestamp(s, stream_index, &pos, INT64_MAX); //may pass pos_limit instead of -1
+        ts = read_timestamp(s, stream_index, &pos, INT64_MAX); //may pass pos_limit instead of -1
         if(pos == pos_max)
             no_change++;
         else
@@ -1301,18 +1327,14 @@
     ts  = (flags & AVSEEK_FLAG_BACKWARD) ?  ts_min :  ts_max;
 #ifdef DEBUG_SEEK
     pos_min = pos;
-    ts_min = avif->read_timestamp(s, stream_index, &pos_min, INT64_MAX);
+    ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
     pos_min++;
-    ts_max = avif->read_timestamp(s, stream_index, &pos_min, INT64_MAX);
+    ts_max = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
     av_log(s, AV_LOG_DEBUG, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n",
            pos, ts_min, target_ts, ts_max);
 #endif
-    /* do the seek */
-    url_fseek(&s->pb, pos, SEEK_SET);
-
-    av_update_cur_dts(s, st, ts);
-
-    return 0;
+    *ts_ret= ts;
+    return pos;
 }
 
 static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){