[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