From 5e727c314e98aa77c255734f4aab5b0d1ad0fd3e Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 5 May 2013 21:41:58 +0200 Subject: stream: fix bad cache behavior introduced by recent commit Commit 4d14a42, a seemingly harmless change, introduced very bad cache behavior when the cache isn't forked, such as on Windows, where it uses threads. Apparently the cache code was designed for forking, and an unknown obscure condition causes severe performance degradation if a STREAM_CTRL is sent to the cache on every frame. Since the cache code is literally insane (uses shared memory + fork(), and has hacks to make it work with threads, is messed into the stream code in extra-hacky ways), we just fix it by caching the STREAM_CTRL in question. This is also done for some other STREAM_CTRLs that are called on each frame, such as playback duration. This indicates that the cache code has some inherent problem with answering such requests in a timely matter, and that there's no easy way around this. (Even if the cache is eventually rewritten, these things will probably have to be cached, otherwise you'd have to forcibly block until the stream implementation is done with a blocking read. The real question is why it worked fine with the forked cache, though.) --- stream/cache2.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/stream/cache2.c b/stream/cache2.c index 705ba15014..0c1c70a577 100644 --- a/stream/cache2.c +++ b/stream/cache2.c @@ -93,6 +93,7 @@ typedef struct { volatile int control_res; volatile double stream_time_length; volatile double stream_time_pos; + volatile double stream_start_time; volatile int idle; } cache_vars_t; @@ -284,6 +285,10 @@ static int cache_execute_control(cache_vars_t *s) { s->stream_time_pos = pos; else s->stream_time_pos = MP_NOPTS_VALUE; + if (s->stream->control(s->stream, STREAM_CTRL_GET_START_TIME, &pos) == STREAM_OK) + s->stream_start_time = pos; + else + s->stream_start_time = MP_NOPTS_VALUE; #if FORKED_CACHE // if parent PID changed, main process was killed -> exit if (s->ppid != getppid()) { @@ -653,6 +658,9 @@ int cache_do_control(stream_t *stream, int cmd, void *arg) { case STREAM_CTRL_GET_CURRENT_TIME: *(double *)arg = s->stream_time_pos; return s->stream_time_pos != MP_NOPTS_VALUE ? STREAM_OK : STREAM_UNSUPPORTED; + case STREAM_CTRL_GET_START_TIME: + *(double *)arg = s->stream_start_time; + return s->stream_start_time != MP_NOPTS_VALUE ? STREAM_OK : STREAM_UNSUPPORTED; case STREAM_CTRL_GET_LANG: s->control_lang_arg = *(struct stream_lang_req *)arg; case STREAM_CTRL_GET_NUM_TITLES: @@ -664,7 +672,6 @@ int cache_do_control(stream_t *stream, int cmd, void *arg) { case STREAM_CTRL_GET_ANGLE: case STREAM_CTRL_GET_SIZE: case STREAM_CTRL_MANAGES_TIMELINE: - case STREAM_CTRL_GET_START_TIME: case -2: s->control = cmd; break; -- cgit v1.2.3