[Ffmpeg-devel] [PATCH] fix ogg seeking

Reimar Döffinger Reimar.Doeffinger
Sun Jul 23 11:05:36 CEST 2006


Hello,
On Sun, Jul 23, 2006 at 10:11:45AM +0200, Reimar D?ffinger wrote:
> On Sun, Jul 16, 2006 at 06:00:33PM +0200, Reimar D?ffinger wrote:
> > currently ogg seeking has at least two issues:
> > 1) the timestamp is reset to 0 until a frame (might be related to the
> > fact that seeking doesn't jump to a keyframe, but I can't fix that).
> > 2) if timestamps do not start at 0, it will quite often hang.
> 
> It's been almost one week, so I intend to apply soon. As a notice to
> everyone who doesn't care about ogg: the patch will also make
> av_update_cur_dts in utils.c non-static.

A little update since the last patch could still hang forever in some
cases.
This patch should guarantee that we always make progress.

Greetings,
Reimar D?ffinger
-------------- next part --------------
Index: libavformat/utils.c
===================================================================
--- libavformat/utils.c	(revision 5813)
+++ libavformat/utils.c	(working copy)
@@ -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++) {
Index: libavformat/ogg2.c
===================================================================
--- libavformat/ogg2.c	(revision 5813)
+++ libavformat/ogg2.c	(working copy)
@@ -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,15 @@
             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) / 2;
             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;
             min = p;
             tmin = pts;
         }
@@ -615,7 +632,8 @@
         pts = AV_NOPTS_VALUE;
     }
 
-    return pts;
+    av_update_cur_dts(s, st, pts);
+    return 0;
 
 #if 0
     //later...
Index: libavformat/avformat.h
===================================================================
--- libavformat/avformat.h	(revision 5813)
+++ libavformat/avformat.h	(working copy)
@@ -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);



More information about the ffmpeg-devel mailing list