[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