From b0cb2977edfa0f2f06912bab1c1603c4fbecb71a Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 29 Sep 2014 17:52:11 +0200 Subject: 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. --- demux/demux_lavf.c | 7 ++++--- 1 file 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; -- cgit v1.2.3