[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