summaryrefslogtreecommitdiff
path: root/libavformat/async.c
diff options
context:
space:
mode:
authorBryan Huh <bryan@box.com>2015-11-11 02:00:21 -0800
committerMichael Niedermayer <michael@niedermayer.cc>2015-11-13 12:43:22 +0100
commitd07585f04add2448c9a8760ba263f7ac64c910c7 (patch)
tree39c53aef39d9e388d930aa075e7b9d8d5ab51e01 /libavformat/async.c
parent5324109dd7e1bfc0236bf74a492a66f26289d16e (diff)
avformat/async: Fix bug where async could not recover after seek to eof
When async issues its inner seek via ffurl_seek, it treats failures as EOF being reached. This is not consistent with the behavior of other protocols (e.g. http, cache) which continue to tolerate reads after failed seeks, and therefore does not interact correctly with them. A common pattern where this manifests itself is where avio_seek is called with pos to be the end-of-file - the http range-request would fail here, and async would set io_eof_reached to 1. The background thread would then refuse to read more bytes, and subsequent reads would only empty the fifo and end in an error. Presumably the code may have expected subsequent seeks to unset the io_eof_reached but this is not guaranteed to be true - a subsequent seek that lands in the AVIOContext's buffer (the fact that the previously-failed avio_seek leaves the AVIOContext's buffer intact also suggests that follow-up reads are expected to be tolerated) would not be issued to the async_seek function, and when that buffer is drained only async_read calls would follow, leading to the same error just described. Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavformat/async.c')
-rw-r--r--libavformat/async.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/libavformat/async.c b/libavformat/async.c
index f4474b866a..4308c4b587 100644
--- a/libavformat/async.c
+++ b/libavformat/async.c
@@ -195,19 +195,16 @@ static void *async_buffer_task(void *arg)
if (c->seek_request) {
seek_ret = ffurl_seek(c->inner, c->seek_pos, c->seek_whence);
- if (seek_ret < 0) {
- c->io_eof_reached = 1;
- c->io_error = (int)seek_ret;
- } else {
+ if (seek_ret >= 0) {
c->io_eof_reached = 0;
c->io_error = 0;
+ ring_reset(ring);
}
c->seek_completed = 1;
c->seek_ret = seek_ret;
c->seek_request = 0;
- ring_reset(ring);
pthread_cond_signal(&c->cond_wakeup_main);
pthread_mutex_unlock(&c->mutex);