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

Michael Niedermayer michaelni at gmx.at
Sun Jul 3 23:45:54 CEST 2011


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


> 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++


> 
> BTW2, does someone knows how to run a particular fate test? I tried make
> fate-seek-lavf_nut but it does all fate.

fate-... is correct
the seek tests though trigger a full rerun, its poor design



> 
> Regards.

>  libavformat/utils.c     |   10 ++++++++++
>  tests/ref/seek/lavf_asf |   12 ++++++++----
>  2 files changed, 18 insertions(+), 4 deletions(-)
> a9ecb63c096afa9e82c100a9dba75d2cac349e62  av_gen_search_wrap.diff
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index cfc70ec..3a7ac79 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -1578,6 +1578,8 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i
>  
>      av_dlog(s, "gen_seek: %d %"PRId64"\n", stream_index, target_ts);
>  
> +    pos = avio_tell(s->pb);
> +
>      if(ts_min == AV_NOPTS_VALUE){
>          pos_min = s->data_offset;
>          ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
> @@ -1611,7 +1613,15 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i
>      }
>  
>      if(ts_min > ts_max){
> +        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 ...

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

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Dictatorship naturally arises out of democracy, and the most aggravated
form of tyranny and slavery out of the most extreme liberty. -- Plato
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20110703/b9087781/attachment.asc>


More information about the ffmpeg-devel mailing list