[FFmpeg-devel] [Hack/rfc] Fix seeking with timestamps wrapping

Etienne Buira etienne.buira.lists at free.fr
Mon Jul 4 12:58:08 CEST 2011

Hi Michael. Thanks for reviewing.

On Sun, Jul 03, 2011 at 11:45:54PM +0200, Michael Niedermayer wrote:
> On Sun, Jul 03, 2011 at 10:38:36AM +0200, Etienne Buira wrote:
> > Hi all.
> > 
> > Currently, with a file that has timestamps wrapped, it is not possible
> > to seek with lavf.
> > 
> > On the user side, that means that ffmpeg -ss -i wrapfile will error out,
> > and that mplayer -demuxer lavf will exit (eof reported) at every seek
> > request.
> > 
> > This is due to the if (ts_min>ts_max) in
> > libavformat/utils.c:av_gen_search().
> > 
> > The attached patch permits to seek in such files.
> > However, it is breaking seek-lavf_nut in a way I don't understand
> > (tests/data/fate/seek-lavf_nut.err exists but is empty, and
> > seek-lavf_nut is empty). I'd really like if someone could look at that.
> nutdec.c is using av_gen_search()
> not sure why or if   ts_min > ts_max triggers in there

Actually pointed out that nut called with stream_index=-2 and -1 (and
triggered ts_min>ts_max. I added a guard against that.
What I didn't understand is how seek_test can output nothing at all.
Seems to be a bug in redirection when seek_test segfaults.

> > I also don't know how bad it is to ignore AVSEEK_FLAG_BACKWARD.
> > 
> > BTW, it seems reporting ts_max (@ end of av_gen_search) is based on
> > wrong value (pos_MIN).
> maybe you missed pos_min++

Damn, right, sorry about the noise.

> > +        if (s->bit_rate) {
> > +            int64_t offset = target_ts - read_timestamp(s, stream_index, &pos, INT64_MAX);
> > +            pos += av_rescale(offset*s->bit_rate/8,
> > +                              s->streams[stream_index]->time_base.num,
> > +                              s->streams[stream_index]->time_base.den);
> > +            pos_min = pos_max = pos_limit = pos;
> this seems risky to me
> what if bitrate changes, i think its not strictly forbidden for a
> dfemuxer to update it or bitrate is totally wrong ...

Yes it is risky, and will make funny seeks in cases you mention (and
This behaviour might be wished or not for ffmpeg, and IMHO is desired in
mplayer -demuxer lavf, even if some precision is lost instead of
What do you think about adding an AVFMT_ flag for that?

> If you really want to support a single ts wrap it could be done
> exactly. not sure if its worth it though

Well, theoreticaly, an arbitrary number of wraps can happen in one
The only way I see is to cycle through av_read_frame, and summing up
pkt->duration. That seems too heavy to me (especially on seek backward
cases), IMHO if someone wants exact, he needs -ss after -i.
If you have better way, I'd be really happy to hear it.

More information about the ffmpeg-devel mailing list