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:
parent
db79db8444
commit
c8f49be919
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user