diff options
author | wm4 <wm4@nowhere> | 2016-09-16 14:25:50 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-09-16 14:49:23 +0200 |
commit | 8716c2e88f9694cf8368132e50a0e778dc055dd1 (patch) | |
tree | fde808300704d664eef1c19a8115de9bcc00cec3 /player/playloop.c | |
parent | 15baf2789cd5c5e0413616df22f235478f40e65e (diff) | |
download | mpv-8716c2e88f9694cf8368132e50a0e778dc055dd1.tar.bz2 mpv-8716c2e88f9694cf8368132e50a0e778dc055dd1.tar.xz |
player: use better way to wait for input and dispatching commands
Instead of using input_ctx for waiting, use the dispatch queue directly.
One big change is that the dispatch queue will just process commands
that come in (e.g. from client API) without returning. This should
reduce unnecessary playloop excutions (which is good since the playloop
got a bit fat from rechecking a lot of conditions every iteration).
Since this doesn't force a new playloop iteration on every access, this
has to be enforced manually in some cases.
Normal input (via terminal or VO window) still wakes up the playloop
every time, though that's not too important. It makes testing this
harder, though. If there are missing wakeup calls, it will be noticed
only when using the client API in some form.
At this point we could probably use a normal lock instead of the
dispatch queue stuff.
Diffstat (limited to 'player/playloop.c')
-rw-r--r-- | player/playloop.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/player/playloop.c b/player/playloop.c index a8d2d1a695..c2795e0d40 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -51,10 +51,24 @@ #include "command.h" // Wait until mp_wakeup_core() is called, since the last time -// mp_wait_events() was called. (But see mp_process_input().) -void mp_wait_events(struct MPContext *mpctx, double sleeptime) +// mp_wait_events() was called. +void mp_wait_events(struct MPContext *mpctx) { - mp_input_wait(mpctx->input, sleeptime); + if (mpctx->sleeptime > 0) + MP_STATS(mpctx, "start sleep"); + + mpctx->in_dispatch = true; + + mp_dispatch_queue_process(mpctx->dispatch, mpctx->sleeptime); + + while (mpctx->suspend_count) + mp_dispatch_queue_process(mpctx->dispatch, 100); + + mpctx->in_dispatch = false; + mpctx->sleeptime = INFINITY; + + if (mpctx->sleeptime > 0) + MP_STATS(mpctx, "end sleep"); } // Set the timeout used when the playloop goes to sleep. This means the @@ -63,6 +77,10 @@ void mp_wait_events(struct MPContext *mpctx, double sleeptime) void mp_set_timeout(struct MPContext *mpctx, double sleeptime) { mpctx->sleeptime = MPMIN(mpctx->sleeptime, sleeptime); + + // Can't adjust timeout if called from mp_dispatch_queue_process(). + if (mpctx->in_dispatch && isfinite(sleeptime)) + mp_wakeup_core(mpctx); } // Cause the playloop to run. This can be called from any thread. If called @@ -70,7 +88,7 @@ void mp_set_timeout(struct MPContext *mpctx, double sleeptime) // of going to sleep in the next mp_wait_events(). void mp_wakeup_core(struct MPContext *mpctx) { - mp_input_wakeup(mpctx->input); + mp_dispatch_interrupt(mpctx->dispatch); } // Opaque callback variant of mp_wakeup_core(). @@ -84,17 +102,14 @@ void mp_wakeup_core_cb(void *ctx) // API threads. This also resets the "wakeup" flag used with mp_wait_events(). void mp_process_input(struct MPContext *mpctx) { - mp_dispatch_queue_process(mpctx->dispatch, 0); for (;;) { mp_cmd_t *cmd = mp_input_read_cmd(mpctx->input); if (!cmd) break; run_command(mpctx, cmd, NULL); mp_cmd_free(cmd); - mp_dispatch_queue_process(mpctx->dispatch, 0); } - while (mpctx->suspend_count) - mp_dispatch_queue_process(mpctx->dispatch, 100); + mp_set_timeout(mpctx, mp_input_get_delay(mpctx->input)); } double get_relative_time(struct MPContext *mpctx) @@ -1045,7 +1060,7 @@ void run_playloop(struct MPContext *mpctx) if (mpctx->lavfi) { if (lavfi_process(mpctx->lavfi)) - mpctx->sleeptime = 0; + mp_wakeup_core(mpctx); if (lavfi_has_failed(mpctx->lavfi)) mpctx->stop_play = AT_END_OF_FILE; } @@ -1079,8 +1094,7 @@ void run_playloop(struct MPContext *mpctx) handle_osd_redraw(mpctx); - mp_wait_events(mpctx, mpctx->sleeptime); - mpctx->sleeptime = 1e9; // infinite for all practical purposes + mp_wait_events(mpctx); handle_pause_on_low_cache(mpctx); @@ -1096,8 +1110,7 @@ void run_playloop(struct MPContext *mpctx) void mp_idle(struct MPContext *mpctx) { handle_dummy_ticks(mpctx); - mp_wait_events(mpctx, mpctx->sleeptime); - mpctx->sleeptime = 100.0; + mp_wait_events(mpctx); mp_process_input(mpctx); handle_command_updates(mpctx); handle_cursor_autohide(mpctx); |