changeset 1185:13dc486b272b libavformat

Try to find out correct start time to make seeking faster and add some extra checks to make sure the seeking function will not hang forever.
author reimar
date Sun, 23 Jul 2006 18:19:33 +0000
parents 5a743f6f836a
children fbdd53c2a12d
files avformat.h ogg2.c utils.c
diffstat 3 files changed, 34 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/avformat.h	Thu Jul 20 10:22:07 2006 +0000
+++ b/avformat.h	Sun Jul 23 18:19:33 2006 +0000
@@ -472,6 +472,7 @@
 int av_add_index_entry(AVStream *st,
                        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);
 
 /* media file output */
 int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);
--- a/ogg2.c	Thu Jul 20 10:22:07 2006 +0000
+++ b/ogg2.c	Sun Jul 23 18:19:33 2006 +0000
@@ -201,7 +201,6 @@
         return AVERROR_NOMEM;
 
     av_set_pts_info(st, 64, 1, 1000000);
-    st->start_time = 0;
 
     return idx;
 }
@@ -495,6 +494,16 @@
 
     ogg->size = size;
     ogg_restore (s, 0);
+    ogg_save (s);
+    while (ogg_read_page (s, &i)) {
+        if (i == idx && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0)
+            break;
+    }
+    if (i == idx) {
+        s->streams[idx]->start_time = ogg_gptopts (s, idx, ogg->streams[idx].granule);
+        s->streams[idx]->duration -= s->streams[idx]->start_time;
+    }
+    ogg_restore (s, 0);
 
     return 0;
 }
@@ -572,12 +581,14 @@
     ogg_t *ogg = s->priv_data;
     ByteIOContext *bc = &s->pb;
     uint64_t min = 0, max = ogg->size;
-    uint64_t tmin = 0, tmax = st->duration;
+    uint64_t tmin = st->start_time, tmax = st->start_time + st->duration;
     int64_t pts = AV_NOPTS_VALUE;
 
     ogg_save (s);
 
-    while (min <= max){
+    if ((uint64_t)target_ts < tmin || target_ts < 0)
+        target_ts = tmin;
+    while (min <= max && tmin < tmax){
         uint64_t p = min + (max - min) * (target_ts - tmin) / (tmax - tmin);
         int i = -1;
 
@@ -599,9 +610,25 @@
             break;
 
         if (pts > target_ts){
+            if (max == p && tmax == pts) {
+                // probably our tmin is wrong, causing us to always end up too late in the file
+                tmin = (target_ts + tmin + 1) / 2;
+                if (tmin == target_ts) {
+                    url_fseek(bc, min, SEEK_SET);
+                    break;
+                }
+            }
             max = p;
             tmax = pts;
         }else{
+            if (min == p && tmin == pts) {
+                // probably our tmax is wrong, causing us to always end up too early in the file
+                tmax = (target_ts + tmax) / 2;
+                if (tmax == target_ts) {
+                    url_fseek(bc, max, SEEK_SET);
+                    break;
+                }
+            }
             min = p;
             tmin = pts;
         }
@@ -615,7 +642,8 @@
         pts = AV_NOPTS_VALUE;
     }
 
-    return pts;
+    av_update_cur_dts(s, st, pts);
+    return 0;
 
 #if 0
     //later...
--- a/utils.c	Thu Jul 20 10:22:07 2006 +0000
+++ b/utils.c	Sun Jul 23 18:19:33 2006 +0000
@@ -1097,7 +1097,7 @@
  * @param timestamp new dts expressed in time_base of param ref_st
  * @param ref_st reference stream giving time_base of param timestamp
  */
-static void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp){
+void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp){
     int i;
 
     for(i = 0; i < s->nb_streams; i++) {