summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-07-18 15:04:46 +0200
committerwm4 <wm4@nowhere>2014-07-18 15:04:46 +0200
commitdc00b146c487f71ef1f0a23a4f2b9948b2fac18b (patch)
tree0292395823a0bef392c4795acc8d50ca75deedea /player
parent34fdf082d8d7d79a24962ff2d8b43b3bef5905b2 (diff)
downloadmpv-dc00b146c487f71ef1f0a23a4f2b9948b2fac18b.tar.bz2
mpv-dc00b146c487f71ef1f0a23a4f2b9948b2fac18b.tar.xz
player: remove the last instances of polling
Mouse cursor handling, --heartbeat-cmd, and OSD messages basically relied on polling. For this reason, the playloop always used a small timeout (not more than 500ms). Fix these cases, and raise the timeout to 100 seconds. There is no reason behind this number; for this specific purpose it's as close to infinity as any other number. On MS Windows, or if vo_sdl is used, the timeout remains very small. In these cases the GUI code doesn't do proper event handling in the first place, and fixing it requires much more effort. getch2_poll() still does polling, because as far as I'm aware no event- based way to detect this state change exists.
Diffstat (limited to 'player')
-rw-r--r--player/core.h4
-rw-r--r--player/osd.c16
-rw-r--r--player/playloop.c57
3 files changed, 39 insertions, 38 deletions
diff --git a/player/core.h b/player/core.h
index 039f5c26cb..01fefd0889 100644
--- a/player/core.h
+++ b/player/core.h
@@ -291,9 +291,11 @@ typedef struct MPContext {
double audio_delay;
- double last_heartbeat;
+ double next_heartbeat;
double last_idle_tick;
+ double sleeptime; // number of seconds to sleep before next iteration
+
double mouse_timer;
unsigned int mouse_event_ts;
bool mouse_cursor_visible;
diff --git a/player/osd.c b/player/osd.c
index 939d62fd98..41d0b8d160 100644
--- a/player/osd.c
+++ b/player/osd.c
@@ -314,19 +314,21 @@ static mp_osd_msg_t *get_osd_msg(struct MPContext *mpctx)
mp_osd_msg_t *msg = mpctx->osd_msg_stack;
if (msg) {
if (!msg->started || msg->time > diff) {
+ // display it
if (msg->started)
msg->time -= diff;
else
msg->started = 1;
- // display it
- return msg;
+ } else {
+ // kill the message
+ talloc_free(msg);
+ msg = NULL;
+ mpctx->osd_msg_stack = NULL;
}
- // kill the message
- talloc_free(msg);
- mpctx->osd_msg_stack = NULL;
}
- // Nothing found
- return NULL;
+ if (msg)
+ mpctx->sleeptime = MPMIN(mpctx->sleeptime, msg->time);
+ return msg;
}
// type: mp_osd_font_codepoints, ASCII, or OSD_BAR_*
diff --git a/player/playloop.c b/player/playloop.c
index 9ce4c39ed3..2392fd32a4 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -52,8 +52,6 @@
#include "screenshot.h"
#include "command.h"
-#define WAKEUP_PERIOD 0.5
-
static const char av_desync_help_text[] =
"\n\n"
" *************************************************\n"
@@ -644,10 +642,11 @@ static void handle_heartbeat_cmd(struct MPContext *mpctx)
struct MPOpts *opts = mpctx->opts;
if (opts->heartbeat_cmd && !mpctx->paused) {
double now = mp_time_sec();
- if (now - mpctx->last_heartbeat > opts->heartbeat_interval) {
- mpctx->last_heartbeat = now;
+ if (mpctx->next_heartbeat <= now) {
+ mpctx->next_heartbeat = now + opts->heartbeat_interval;
system(opts->heartbeat_cmd);
}
+ mpctx->sleeptime = MPMIN(mpctx->sleeptime, mpctx->next_heartbeat - now);
}
}
@@ -660,17 +659,20 @@ static void handle_cursor_autohide(struct MPContext *mpctx)
return;
bool mouse_cursor_visible = mpctx->mouse_cursor_visible;
+ double now = mp_time_sec();
unsigned mouse_event_ts = mp_input_get_mouse_event_counter(mpctx->input);
if (mpctx->mouse_event_ts != mouse_event_ts) {
mpctx->mouse_event_ts = mouse_event_ts;
- mpctx->mouse_timer =
- mp_time_sec() + opts->cursor_autohide_delay / 1000.0;
+ mpctx->mouse_timer = now + opts->cursor_autohide_delay / 1000.0;
mouse_cursor_visible = true;
}
- if (mp_time_sec() >= mpctx->mouse_timer)
+ if (mpctx->mouse_timer > now) {
+ mpctx->sleeptime = MPMIN(mpctx->sleeptime, mpctx->mouse_timer - now);
+ } else {
mouse_cursor_visible = false;
+ }
if (opts->cursor_autohide_delay == -1)
mouse_cursor_visible = true;
@@ -879,13 +881,7 @@ static double timing_sleep(struct MPContext *mpctx, double time_frame)
static double get_wakeup_period(struct MPContext *mpctx)
{
- /* Even if we can immediately wake up in response to most input events,
- * there are some timers which are not registered to the event loop
- * and need to be checked periodically (like automatic mouse cursor hiding).
- * OSD content updates behave similarly. Also some uncommon input devices
- * may not have proper FD event support.
- */
- double sleeptime = WAKEUP_PERIOD;
+ double sleeptime = 100.0; // infinite for all practical purposes
#if !HAVE_POSIX_SELECT
// No proper file descriptor event handling; keep waking up to poll input
@@ -906,7 +902,6 @@ void run_playloop(struct MPContext *mpctx)
bool audio_left = false, video_left = false;
double endpts = get_play_end_pts(mpctx);
bool end_is_chapter = false;
- double sleeptime = get_wakeup_period(mpctx);
bool was_restart = mpctx->restart_playback;
bool new_frame_shown = false;
@@ -1010,7 +1005,7 @@ void run_playloop(struct MPContext *mpctx)
}
if (r != 2 && !mpctx->playing_last_frame) {
- sleeptime = 0;
+ mpctx->sleeptime = 0;
break;
}
@@ -1052,10 +1047,10 @@ void run_playloop(struct MPContext *mpctx)
double vsleep = mpctx->time_frame - vo->flip_queue_offset;
if (vsleep > 0.050) {
- sleeptime = MPMIN(sleeptime, vsleep - 0.040);
+ mpctx->sleeptime = MPMIN(mpctx->sleeptime, vsleep - 0.040);
break;
}
- sleeptime = 0;
+ mpctx->sleeptime = 0;
mpctx->playing_last_frame = false;
// last frame case (don't set video_left - consider format changes)
@@ -1245,19 +1240,21 @@ void run_playloop(struct MPContext *mpctx)
}
- if (!mpctx->stop_play) {
- if (mpctx->restart_playback)
- sleeptime = 0;
- if (sleeptime > 0) {
- if (handle_osd_redraw(mpctx))
- sleeptime = 0;
- }
- if (sleeptime > 0) {
- MP_STATS(mpctx, "start sleep");
- mp_input_get_cmd(mpctx->input, sleeptime * 1000, true);
- MP_STATS(mpctx, "end sleep");
- }
+ if (mpctx->stop_play)
+ mpctx->sleeptime = 0;
+
+ if (mpctx->restart_playback)
+ mpctx->sleeptime = 0;
+
+ if (mpctx->sleeptime > 0 && handle_osd_redraw(mpctx))
+ mpctx->sleeptime = 0;
+
+ if (mpctx->sleeptime > 0) {
+ MP_STATS(mpctx, "start sleep");
+ mp_input_get_cmd(mpctx->input, mpctx->sleeptime * 1000, true);
+ MP_STATS(mpctx, "end sleep");
}
+ mpctx->sleeptime = get_wakeup_period(mpctx);
handle_pause_on_low_cache(mpctx);