[Ffmpeg-devel] [PATCH] fix ogg seeking

Reimar Döffinger Reimar.Doeffinger
Sun Jul 16 18:00:33 CEST 2006


Hello,
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.

The attached patch fixes both problems for me, and I also changed the
return value of the seek function. It does not seem to make any
difference, but returning the 64 bit pts via an int doesn't make much
sense to me.
A sample file that shows the problem quite well is here:
http://ktown.kde.org/akademy/Scott_And_Christian_GStreamer_video.ogg

Greetings,
Reimar D?ffinger
-------------- next part --------------
Index: utils.c
===================================================================
--- utils.c	(revision 5761)
+++ 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: ogg2.c
===================================================================
--- ogg2.c	(revision 5761)
+++ 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,11 +581,13 @@
     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);
 
+    if ((uint64_t)target_ts < tmin || target_ts < 0)
+        target_ts = tmin;
     while (min <= max){
         uint64_t p = min + (max - min) * (target_ts - tmin) / (tmax - tmin);
         int i = -1;
@@ -615,7 +626,8 @@
         pts = AV_NOPTS_VALUE;
     }
 
-    return pts;
+    av_update_cur_dts(s, st, pts);
+    return 0;
 
 #if 0
     //later...



More information about the ffmpeg-devel mailing list