summaryrefslogtreecommitdiffstats
path: root/demux/demux_lavf.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-02-19 01:43:26 +0100
committerwm4 <wm4@nowhere>2013-02-19 01:49:01 +0100
commita090c0745354791874167349498bb635c3cba3ba (patch)
treef0d1de5a7be22337b1a7204442ab5bfbb41ca14f /demux/demux_lavf.c
parent41763b6d5626a66b063e016200c68fed2adb5e63 (diff)
downloadmpv-a090c0745354791874167349498bb635c3cba3ba.tar.bz2
mpv-a090c0745354791874167349498bb635c3cba3ba.tar.xz
demux_lavf: add workaround for broken libavformat seek behavior
Seeking before the start of a .flac file (such as seeking backwards when the file just started) generates a bunch of decoding errors and audible artifacts. Also, the audio output doesn't match the reported playback position. The errors printed to the terminal are: [flac @ 0x8aca1c0]invalid sync code [flac @ 0x8aca1c0]invalid frame header [flac @ 0x8aca1c0]decode_frame() failed This is most likely a problem with the libavformat API. When seeking with av_seek_frame() fails, the demuxer can be left in an inconsistent state. ffplay has the same issue [1]. Older versions of mpv somehow handled this fine. Bisection shows that commit b3fb7c2 caused this regression by removing code that retried failed seeks with an inverted AVSEEK_FLAG_BACKWARD flag. This code was removed because it made it harder to stop playback of a file by seeking past the end of the file (expecting this is rather natural when skipping through multiple files by seeking, and the internal mplayer demuxers also did this). As a workaround, re-add the original code, but only for the backwards seeking case. Also note that the original intention of the code removed in b3fb7c2 was not dealing with this case, but something else. It also had to do with working around weird libavformat situations, though. It's not perfectly clear what exactly. See commit 1ad332f. [1] https://ffmpeg.org/trac/ffmpeg/ticket/2282
Diffstat (limited to 'demux/demux_lavf.c')
-rw-r--r--demux/demux_lavf.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index ca81a45f84..eaa0cfadf8 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -724,7 +724,14 @@ static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs,
if (!priv->avfc->iformat->read_seek2) {
// Normal seeking.
- av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags);
+ int r = av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags);
+ if (r < 0 && (avsflags & AVSEEK_FLAG_BACKWARD)) {
+ // When seeking before the beginning of the file, and seeking fails,
+ // try again without the backwards flag to make it seek to the
+ // beginning.
+ avsflags &= ~AVSEEK_FLAG_BACKWARD;
+ av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags);
+ }
} else {
// av_seek_frame() won't work. Use "new" seeking API. We don't use this
// API by default, because there are some major issues.