1
0
mirror of https://github.com/mpv-player/mpv synced 2025-01-09 00:19:32 +00:00

cache: fix unnecessary seek blocking from f4d62dc4a0

Commit 374600cec0 ("cache: propagate seek failures") changed
stream-level seeks to be done in the calling thread so possible errors
could be reported. This commit included some rationale why doing the
stream-level seeks synchronously was not a big issue. However, the
following fixup commit f4d62dc4a0 changed the seek code to always
synchronize with the cache thread and do seek handling there. This is
a problem because it affects even seeks within already cached data
(which require no stream-level seek). With a network server that sends
data in bursts, the cache thread can be blocked in a read call for a
long time; the added synchronization means that seeking within already
downloaded data can have unnecessary long delays.

Change cache_seek() to check whether the seek is expected to result in
a stream-level seek, and skip synchronization if it is not. This means
that seeks within the cached portion of the file now again happen
immediately without possibly waiting for network.

Signed-off-by: wm4 <wm4@nowhere>
This commit is contained in:
Uoti Urpala 2017-04-24 13:28:37 +03:00 committed by wm4
parent 5aea98551b
commit 3f17b101ee

View File

@ -602,16 +602,25 @@ static int cache_seek(stream_t *cache, int64_t pos)
r = 0;
} else {
cache->pos = s->read_filepos = s->read_min = pos;
s->eof = false; // so that cache_read() will actually wait for new data
s->control = CACHE_CTRL_SEEK;
s->control_res = 0;
double retry = 0;
while (s->control != CACHE_CTRL_NONE) {
if (!cache_wakeup_and_wait(s, &retry))
break;
// Is this seek likely to cause a stream-level seek?
// If it is, wait until that is complete and return its result.
// This check is not quite exact - if the reader thread is blocked in
// a read, the read might advance file position enough that a seek
// forward is no longer needed.
if (pos < s->min_filepos || pos > s->max_filepos + s->seek_limit) {
s->eof = false;
s->control = CACHE_CTRL_SEEK;
s->control_res = 0;
double retry = 0;
while (s->control != CACHE_CTRL_NONE) {
if (!cache_wakeup_and_wait(s, &retry))
break;
}
r = s->control_res;
} else {
pthread_cond_signal(&s->wakeup);
r = 1;
}
r = s->control_res;
pthread_cond_signal(&s->wakeup);
}
pthread_mutex_unlock(&s->mutex);