summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-09-29 17:52:11 +0200
committerwm4 <wm4@nowhere>2014-09-29 18:06:44 +0200
commitb0cb2977edfa0f2f06912bab1c1603c4fbecb71a (patch)
treec87908dd60a3e57c8740bf01ad3dd86f6c94c830 /demux
parent39451732e905e5884a04e040a9d47d8f4a47025c (diff)
downloadmpv-b0cb2977edfa0f2f06912bab1c1603c4fbecb71a.tar.bz2
mpv-b0cb2977edfa0f2f06912bab1c1603c4fbecb71a.tar.xz
demux_lavf: bluray: don't skip stream data when flushing
This code meant to flush demuxer internal buffers by doing a byte seek to the current position. In theory this shouldn't drop any stream data. However, if the stream positions mismatch, then avio_seek() (called by av_seek_frame()) stops being a no-op, and might for example read some data to skip to the seek target. (This can happen if the distance is less than SHORT_SEEK_THRESHOLD.) The positions get out of sync because we drop data at one point (which is what we _want_ to do). Strictly speaking, the AVIOContext flushing is done incorrectly, becuase pb->pos points to the start of the buffer, not the current position. So we have to increment pb->pos by the buffered amount. Since there are other weird reasons why the positions might go out of sync (such as stream_dvd.c dropping buffers itself), and they don't necessarily need to be in sync in the first place unless AVIOContext has nothing buffered internally, just use the sledgehammer approach and correct the position manually. Also run av_seek_frame() after this. Currently, it shouldn't read anything, but who knows how that might change with future libavformat development. This whole change didn't have any observable effect for me, but I'm hoping it fixes a reported problem.
Diffstat (limited to 'demux')
-rw-r--r--demux/demux_lavf.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 8dd248aec1..bfcda2b2c4 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -1010,12 +1010,13 @@ redo:
* call the new API instead of relying on av_seek_frame() to do this
* for us.
*/
- av_seek_frame(priv->avfc, 0, stream_tell(demuxer->stream),
- AVSEEK_FLAG_BYTE);
// avio_flush() is designed for write-only streams, and does the wrong
// thing when reading. Flush it manually instead.
- priv->avfc->pb->buf_ptr = priv->avfc->pb->buf_end = priv->avfc->pb->buffer;
stream_drop_buffers(demuxer->stream);
+ priv->avfc->pb->buf_ptr = priv->avfc->pb->buf_end = priv->avfc->pb->buffer;
+ priv->avfc->pb->pos = stream_tell(demuxer->stream);
+ av_seek_frame(priv->avfc, 0, stream_tell(demuxer->stream),
+ AVSEEK_FLAG_BYTE);
return DEMUXER_CTRL_OK;
default:
return DEMUXER_CTRL_NOTIMPL;