cache: propagate seek failures

Eagerly execute seeks to the underlying stream in the cache seek
entrypoint itself. While asynchronous execution is a goal of the cache,
it doesn't matter too much for seeks. They always were executed within
the lock, so the reader was blocked anyway. It's not necessary to ensure
async. execution here either, because seeks are relatively rare, and the
demuxer can just stay blocked for a while.

Fixes: mpv http://samples.mplayerhq.hu/V-codecs/DIV5/ayaneshk-test.avi
This commit is contained in:
wm4 2016-07-11 20:52:30 +02:00
parent 5a6ba2a4fd
commit 374600cec0
1 changed files with 17 additions and 7 deletions

View File

@ -200,12 +200,9 @@ static size_t read_buffer(struct priv *s, unsigned char *dst,
return read;
}
// Runs in the cache thread.
static void cache_fill(struct priv *s)
static bool cache_update_stream_position(struct priv *s)
{
int64_t read = s->read_filepos;
bool read_attempted = false;
int len = 0;
// drop cache contents only if seeking backward or too much fwd.
// This is also done for on-disk files, since it loses the backseek cache.
@ -221,11 +218,23 @@ static void cache_fill(struct priv *s)
if (stream_tell(s->stream) != s->max_filepos && s->seekable) {
MP_VERBOSE(s, "Seeking underlying stream: %"PRId64" -> %"PRId64"\n",
stream_tell(s->stream), s->max_filepos);
stream_seek(s->stream, s->max_filepos);
if (stream_tell(s->stream) != s->max_filepos)
goto done;
if (!stream_seek(s->stream, s->max_filepos))
return false;
}
return stream_tell(s->stream) == s->max_filepos;
}
// Runs in the cache thread.
static void cache_fill(struct priv *s)
{
int64_t read = s->read_filepos;
bool read_attempted = false;
int len = 0;
if (!cache_update_stream_position(s))
goto done;
if (!s->enable_readahead && s->read_min <= s->max_filepos)
goto done;
@ -570,6 +579,7 @@ static int cache_seek(stream_t *cache, int64_t pos)
} else {
cache->pos = s->read_filepos = s->read_min = pos;
s->eof = false; // so that cache_read() will actually wait for new data
r = cache_update_stream_position(s);
pthread_cond_signal(&s->wakeup);
}