0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 12:02:23 +02:00

demux_lavf: workaround for broken libavformat subtitle seeking

The really funny thing about this commit is that this code is added on
top of another work around. Basically, subtitle seeking in libavformat
is completely broken. To make it useful, we have to add yet another
workaround.

The basic problem is that libavformat's subtitle seeking code always
uses the stream time base, instead of AV_TIME_BASE if stream index -1 is
passed to the avformat_seek_file() function.

Fixes github issue #216. Hopefully this will be fixed in ffmpeg too at
some point.
This commit is contained in:
wm4 2013-09-07 02:46:19 +02:00
parent db79db8444
commit c8f49be919

View File

@ -862,12 +862,31 @@ static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, int flags)
// API by default, because there are some major issues.
// Set max_ts==ts, so that demuxing starts from an earlier position in
// the worst case.
int r = avformat_seek_file(priv->avfc, -1, INT64_MIN,
priv->last_pts, priv->last_pts, avsflags);
// To make this horrible situation even worse, some lavf demuxers have
// broken timebase handling (everything that uses
// ff_subtitles_queue_seek()), and always uses the stream timebase. So
// we use the timebase and stream index of the first enabled stream
// (i.e. a stream which can participate in seeking).
int stream_index = -1;
AVRational time_base = {1, AV_TIME_BASE};
for (int n = 0; n < priv->num_streams; n++) {
struct sh_stream *stream = priv->streams[n];
AVStream *st = priv->avfc->streams[n];
if (stream && st->discard != AVDISCARD_ALL) {
stream_index = n;
time_base = st->time_base;
break;
}
}
int64_t pts = priv->last_pts;
if (pts != AV_NOPTS_VALUE)
pts = pts / (double)AV_TIME_BASE * av_q2d(av_inv_q(time_base));
int r = avformat_seek_file(priv->avfc, stream_index, INT64_MIN,
pts, pts, avsflags);
// Similar issue as in the normal seeking codepath.
if (r < 0) {
avformat_seek_file(priv->avfc, -1, INT64_MIN,
priv->last_pts, INT64_MAX, avsflags);
avformat_seek_file(priv->avfc, stream_index, INT64_MIN,
pts, INT64_MAX, avsflags);
}
}
}