[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
ts_min>ts_max).
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
exiting(EOF).
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
stream.
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