summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-05-25 18:31:06 +0200
committerwm4 <wm4@nowhere>2013-05-26 16:44:20 +0200
commite56d8a200d900066c3da571d92733f66ce6a13ab (patch)
treef43862ec12beee05380da82ebef23bcce83401e7 /core
parent51254a678c386cf48f2caa51e06ad34065c8693a (diff)
downloadmpv-e56d8a200d900066c3da571d92733f66ce6a13ab.tar.bz2
mpv-e56d8a200d900066c3da571d92733f66ce6a13ab.tar.xz
Replace all calls to GetTimer()/GetTimerMS()
GetTimer() is generally replaced with mp_time_us(). Both calls return microseconds, but the latter uses int64_t, us defined to never wrap, and never returns 0 or negative values. GetTimerMS() has no direct replacement. Instead the other functions are used. For some code, switch to mp_time_sec(), which returns the time as double float value in seconds. The returned time is offset to program start time, so there is enough precision left to deliver microsecond resolution for at least 100 years. Unless it's casted to a float (or the CPU reduces precision), which is why we still use mp_time_us() out of paranoia in places where precision is clearly needed. Always switch to the correct time. The whole point of the new timer calls is that they don't wrap, and storing microseconds in unsigned int variables would negate this. In some cases, remove wrap-around handling for time values.
Diffstat (limited to 'core')
-rw-r--r--core/encode_lavc.c9
-rw-r--r--core/encode_lavc.h2
-rw-r--r--core/input/input.c18
-rw-r--r--core/input/input.h2
-rw-r--r--core/mp_core.h23
-rw-r--r--core/mp_fifo.c6
-rw-r--r--core/mplayer.c81
7 files changed, 66 insertions, 75 deletions
diff --git a/core/encode_lavc.c b/core/encode_lavc.c
index 457f6ab987..1677baf838 100644
--- a/core/encode_lavc.c
+++ b/core/encode_lavc.c
@@ -269,7 +269,7 @@ int encode_lavc_start(struct encode_lavc_context *ctx)
}
}
- ctx->t0 = GetTimerMS();
+ ctx->t0 = mp_time_sec();
mp_msg(MSGT_ENCODE, MSGL_INFO, "Opening muxer: %s [%s]\n",
ctx->avc->oformat->long_name, ctx->avc->oformat->name);
@@ -997,6 +997,7 @@ int encode_lavc_getstatus(struct encode_lavc_context *ctx,
char *buf, int bufsize,
float relative_position, float playback_time)
{
+ double now = mp_time_sec();
float minutes, megabytes, fps, x;
float f = FFMAX(0.0001, relative_position);
if (!ctx)
@@ -1004,10 +1005,10 @@ int encode_lavc_getstatus(struct encode_lavc_context *ctx,
CHECK_FAIL(ctx, -1);
- minutes = (GetTimerMS() - ctx->t0) / 60000.0 * (1 - f) / f;
+ minutes = (now - ctx->t0) / 60.0 * (1 - f) / f;
megabytes = ctx->avc->pb ? (avio_size(ctx->avc->pb) / 1048576.0 / f) : 0;
- fps = ctx->frames / ((GetTimerMS() - ctx->t0) / 1000.0);
- x = playback_time / ((GetTimerMS() - ctx->t0) / 1000.0);
+ fps = ctx->frames / ((now - ctx->t0));
+ x = playback_time / ((now - ctx->t0));
if (ctx->frames)
snprintf(buf, bufsize, "{%.1f%% %.1fmin %.1ffps %.1fMB}",
relative_position * 100.0, minutes, fps, megabytes);
diff --git a/core/encode_lavc.h b/core/encode_lavc.h
index a0245c991a..7e53ae6a1d 100644
--- a/core/encode_lavc.h
+++ b/core/encode_lavc.h
@@ -61,7 +61,7 @@ struct encode_lavc_context {
long long vbytes;
struct stream *twopass_bytebuffer_a;
struct stream *twopass_bytebuffer_v;
- unsigned int t0;
+ double t0;
unsigned int frames;
bool expect_video;
diff --git a/core/input/input.c b/core/input/input.c
index c756efcbdc..3d8ba711b7 100644
--- a/core/input/input.c
+++ b/core/input/input.c
@@ -464,7 +464,7 @@ struct input_ctx {
// Autorepeat stuff
short ar_state;
mp_cmd_t *ar_cmd;
- unsigned int last_ar;
+ int64_t last_ar;
// Autorepeat config
unsigned int ar_delay;
unsigned int ar_rate;
@@ -475,7 +475,7 @@ struct input_ctx {
// these are the keys currently down
int key_down[MP_MAX_KEY_DOWN];
unsigned int num_key_down;
- unsigned int last_key_down;
+ int64_t last_key_down;
bool test;
@@ -491,7 +491,7 @@ struct input_ctx {
// events sources. If yes, the sources may have more queued.
bool got_new_events;
- unsigned int last_mouse_event;
+ unsigned int mouse_event_counter;
struct input_fd key_fds[MP_MAX_KEY_FD];
unsigned int num_key_fd;
@@ -1230,7 +1230,7 @@ static mp_cmd_t *interpret_key(struct input_ctx *ictx, int code)
return NULL;
ictx->key_down[ictx->num_key_down] = code;
ictx->num_key_down++;
- ictx->last_key_down = GetTimer();
+ ictx->last_key_down = mp_time_us();
ictx->ar_state = 0;
ret = NULL;
if (!(code & MP_NO_REPEAT_KEY))
@@ -1287,7 +1287,7 @@ static mp_cmd_t *check_autorepeat(struct input_ctx *ictx)
// No input : autorepeat ?
if (ictx->ar_rate > 0 && ictx->ar_state >= 0 && ictx->num_key_down > 0
&& !(ictx->key_down[ictx->num_key_down - 1] & MP_NO_REPEAT_KEY)) {
- unsigned int t = GetTimer();
+ int64_t t = mp_time_us();
if (ictx->last_ar + 2000000 < t)
ictx->last_ar = t;
// First time : wait delay
@@ -1319,7 +1319,7 @@ void mp_input_feed_key(struct input_ctx *ictx, int code)
ictx->got_new_events = true;
int unmod = code & ~(MP_KEY_MODIFIER_MASK | MP_KEY_STATE_DOWN);
if (unmod >= MP_MOUSE_BASE && unmod <= MP_MOUSE_BTN_END)
- ictx->last_mouse_event = GetTimerMS();
+ ictx->mouse_event_counter++;
if (code == MP_INPUT_RELEASE_ALL) {
mp_msg(MSGT_INPUT, MSGL_V, "input: release all\n");
memset(ictx->key_down, 0, sizeof(ictx->key_down));
@@ -1483,7 +1483,7 @@ int mp_input_queue_cmd(struct input_ctx *ictx, mp_cmd_t *cmd)
if (!cmd)
return 0;
if (cmd->id == MP_CMD_SET_MOUSE_POS)
- ictx->last_mouse_event = GetTimerMS();
+ ictx->mouse_event_counter++;
queue_add(&ictx->control_cmd_queue, cmd, false);
return 1;
}
@@ -1914,7 +1914,7 @@ int mp_input_check_interrupt(struct input_ctx *ictx, int time)
}
}
-unsigned int mp_input_get_last_mouse_event_time(struct input_ctx *ictx)
+unsigned int mp_input_get_mouse_event_counter(struct input_ctx *ictx)
{
- return ictx->last_mouse_event;
+ return ictx->mouse_event_counter;
}
diff --git a/core/input/input.h b/core/input/input.h
index 1f079e7451..6c33e47fdc 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -209,7 +209,7 @@ void mp_input_set_section(struct input_ctx *ictx, char *name, int flags);
char *mp_input_get_section(struct input_ctx *ictx);
// Used to detect mouse movement.
-unsigned int mp_input_get_last_mouse_event_time(struct input_ctx *ictx);
+unsigned int mp_input_get_mouse_event_counter(struct input_ctx *ictx);
// Initialize the input system
struct input_conf;
diff --git a/core/mp_core.h b/core/mp_core.h
index 6f784b4b7c..3b693d1658 100644
--- a/core/mp_core.h
+++ b/core/mp_core.h
@@ -132,9 +132,10 @@ typedef struct MPContext {
subtitle subs; // subtitle list used when reading subtitles from demuxer
int add_osd_seek_info; // bitfield of enum mp_osd_seek_info
- unsigned int osd_visible; // for the osd bar only
+ double osd_visible; // for the osd bar only
int osd_function;
- unsigned int osd_function_visible;
+ double osd_function_visible;
+ double osd_last_update;
struct playlist *playlist;
char *filename; // currently playing file
@@ -196,11 +197,11 @@ typedef struct MPContext {
// by the audio CPU usage meter.
double delay;
// AV sync: time until next frame should be shown
- float time_frame;
+ double time_frame;
// How long the last vo flip() call took. Used to adjust timing with
// the goal of making flip() calls finish (rather than start) at the
// specified time.
- float last_vo_flip_duration;
+ double last_vo_flip_duration;
// How much video timing has been changed to make it match the audio
// timeline. Used for status line information only.
double total_avsync_change;
@@ -232,23 +233,21 @@ typedef struct MPContext {
uint64_t backstep_start_seek_ts;
bool backstep_active;
- float audio_delay;
+ double audio_delay;
- unsigned int last_heartbeat;
+ double last_heartbeat;
- unsigned int mouse_timer;
- unsigned int mouse_last_time;
+ double mouse_timer;
+ unsigned int mouse_event_ts;
int mouse_waiting_hide;
- unsigned int next_wakup_time;
-
// used to prevent hanging in some error cases
- unsigned int start_timestamp;
+ double start_timestamp;
// Timestamp from the last time some timing functions read the
// current time, in (occasionally wrapping) microseconds. Used
// to turn a new time value to a delta from last time.
- unsigned int last_time;
+ int64_t last_time;
// Used to communicate the parameters of a seek between parts
struct seek_params {
diff --git a/core/mp_fifo.c b/core/mp_fifo.c
index 386eda5e80..32036749d1 100644
--- a/core/mp_fifo.c
+++ b/core/mp_fifo.c
@@ -31,7 +31,7 @@ struct mp_fifo {
struct MPOpts *opts;
struct input_ctx *input;
int last_key_down;
- unsigned last_down_time;
+ double last_down_time;
};
struct mp_fifo *mp_fifo_create(struct input_ctx *input, struct MPOpts *opts)
@@ -50,7 +50,7 @@ static void put_double(struct mp_fifo *fifo, int code)
void mplayer_put_key(struct mp_fifo *fifo, int code)
{
- unsigned now = GetTimerMS();
+ double now = mp_time_sec();
int doubleclick_time = fifo->opts->doubleclick_time;
// ignore system-doubleclick if we generate these events ourselves
if (doubleclick_time
@@ -61,7 +61,7 @@ void mplayer_put_key(struct mp_fifo *fifo, int code)
if (code & MP_KEY_STATE_DOWN) {
code &= ~MP_KEY_STATE_DOWN;
if (fifo->last_key_down == code
- && now - fifo->last_down_time < doubleclick_time)
+ && now - fifo->last_down_time < doubleclick_time / 1000.0)
put_double(fifo, code);
fifo->last_key_down = code;
fifo->last_down_time = now;
diff --git a/core/mplayer.c b/core/mplayer.c
index 0b1bee4179..8e077e248d 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -207,10 +207,10 @@ static struct track *open_external_file(struct MPContext *mpctx, char *filename,
char *demuxer_name, int stream_cache,
enum stream_type filter);
-static float get_relative_time(struct MPContext *mpctx)
+static double get_relative_time(struct MPContext *mpctx)
{
- unsigned int new_time = GetTimer();
- unsigned int delta = new_time - mpctx->last_time;
+ int64_t new_time = mp_time_us();
+ int64_t delta = new_time - mpctx->last_time;
mpctx->last_time = new_time;
return delta * 0.000001;
}
@@ -1329,13 +1329,14 @@ struct mp_osd_msg {
/// Message text.
char *msg;
int id, level, started;
- /// Display duration in ms.
- unsigned time;
+ /// Display duration in seconds.
+ double time;
// Show full OSD for duration of message instead of msg
// (osd_show_progression command)
bool show_position;
};
+// time is in ms
static mp_osd_msg_t *add_osd_msg(struct MPContext *mpctx, int id, int level,
int time)
{
@@ -1345,7 +1346,7 @@ static mp_osd_msg_t *add_osd_msg(struct MPContext *mpctx, int id, int level,
.msg = "",
.id = id,
.level = level,
- .time = time,
+ .time = time / 1000.0,
});
mpctx->osd_msg_stack = msg;
return msg;
@@ -1415,32 +1416,25 @@ static mp_osd_msg_t *get_osd_msg(struct MPContext *mpctx)
{
struct MPOpts *opts = &mpctx->opts;
mp_osd_msg_t *msg, *prev, *last = NULL;
- static unsigned last_update = 0;
- unsigned now = GetTimerMS();
- unsigned diff;
+ double now = mp_time_sec();
+ double diff;
char hidden_dec_done = 0;
- if (mpctx->osd_visible) {
- // 36000000 means max timed visibility is 1 hour into the future, if
- // the difference is greater assume it's wrapped around from below 0
- if (mpctx->osd_visible - now > 36000000) {
- mpctx->osd_visible = 0;
- mpctx->osd->progbar_type = -1; // disable
- vo_osd_changed(OSDTYPE_PROGBAR);
- }
+ if (mpctx->osd_visible && now >= mpctx->osd_visible) {
+ mpctx->osd_visible = 0;
+ mpctx->osd->progbar_type = -1; // disable
+ vo_osd_changed(OSDTYPE_PROGBAR);
}
- if (mpctx->osd_function_visible) {
- if (mpctx->osd_function_visible - now > 36000000) {
- mpctx->osd_function_visible = 0;
- mpctx->osd_function = 0;
- }
+ if (mpctx->osd_function_visible && now >= mpctx->osd_function_visible) {
+ mpctx->osd_function_visible = 0;
+ mpctx->osd_function = 0;
}
- if (!last_update)
- last_update = now;
- diff = now >= last_update ? now - last_update : 0;
+ if (!mpctx->osd_last_update)
+ mpctx->osd_last_update = now;
+ diff = now >= mpctx->osd_last_update ? now - mpctx->osd_last_update : 0;
- last_update = now;
+ mpctx->osd_last_update = now;
// Look for the first message in the stack with high enough level.
for (msg = mpctx->osd_msg_stack; msg; last = msg, msg = prev) {
@@ -1484,7 +1478,7 @@ void set_osd_bar(struct MPContext *mpctx, int type, const char *name,
return;
if (mpctx->sh_video && opts->term_osd != 1) {
- mpctx->osd_visible = (GetTimerMS() + opts->osd_duration) | 1;
+ mpctx->osd_visible = mp_time_sec() + opts->osd_duration / 1000.0;
mpctx->osd->progbar_type = type;
mpctx->osd->progbar_value = (val - min) / (max - min);
mpctx->osd->progbar_num_stops = 0;
@@ -1535,7 +1529,7 @@ void set_osd_function(struct MPContext *mpctx, int osd_function)
struct MPOpts *opts = &mpctx->opts;
mpctx->osd_function = osd_function;
- mpctx->osd_function_visible = (GetTimerMS() + opts->osd_duration) | 1;
+ mpctx->osd_function_visible = mp_time_sec() + opts->osd_duration / 1000.0;
}
/**
@@ -2028,12 +2022,12 @@ static int check_framedrop(struct MPContext *mpctx, double frame_time)
return 0;
}
-static float timing_sleep(struct MPContext *mpctx, float time_frame)
+static double timing_sleep(struct MPContext *mpctx, double time_frame)
{
// assume kernel HZ=100 for softsleep, works with larger HZ but with
// unnecessarily high CPU usage
struct MPOpts *opts = &mpctx->opts;
- float margin = opts->softsleep ? 0.011 : 0;
+ double margin = opts->softsleep ? 0.011 : 0;
while (time_frame > margin) {
usec_sleep(1000000 * (time_frame - margin));
time_frame -= get_relative_time(mpctx);
@@ -3129,7 +3123,7 @@ static int seek(MPContext *mpctx, struct seek_params seek,
: mpctx->timeline[mpctx->timeline_part].start;
}
- mpctx->start_timestamp = GetTimerMS();
+ mpctx->start_timestamp = mp_time_sec();
return 0;
}
@@ -3507,32 +3501,29 @@ static void run_playloop(struct MPContext *mpctx)
// ================================================================
vo_check_events(vo);
- unsigned int mouse_last_time =
- mp_input_get_last_mouse_event_time(mpctx->input);
- if (mpctx->mouse_last_time != mouse_last_time) {
- mpctx->mouse_last_time = mouse_last_time;
+ double 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;
if (opts->vo.cursor_autohide_delay > -1) {
vo_control(vo, VOCTRL_SET_CURSOR_VISIBILITY, &(bool){true});
if (opts->vo.cursor_autohide_delay >= 0) {
mpctx->mouse_waiting_hide = 1;
mpctx->mouse_timer =
- GetTimerMS() + opts->vo.cursor_autohide_delay;
+ mp_time_sec() + opts->vo.cursor_autohide_delay / 1000.0;
}
}
}
if (mpctx->mouse_waiting_hide == 1 &&
- GetTimerMS() >= mpctx->mouse_timer)
+ mp_time_sec() >= mpctx->mouse_timer)
{
vo_control(vo, VOCTRL_SET_CURSOR_VISIBILITY, &(bool){false});
mpctx->mouse_waiting_hide = 2;
}
if (opts->heartbeat_cmd) {
- unsigned now = GetTimerMS();
- if (now - mpctx->last_heartbeat >
- (unsigned)(opts->heartbeat_interval * 1000))
- {
+ double now = mp_time_sec();
+ if (now - mpctx->last_heartbeat > opts->heartbeat_interval) {
mpctx->last_heartbeat = now;
system(opts->heartbeat_cmd);
}
@@ -3602,12 +3593,12 @@ static void run_playloop(struct MPContext *mpctx)
mpctx->time_frame = timing_sleep(mpctx, mpctx->time_frame);
mpctx->time_frame += vo->flip_queue_offset;
- unsigned int t2 = GetTimer();
+ int64_t t2 = mp_time_us();
/* Playing with playback speed it's possible to get pathological
* cases with mpctx->time_frame negative enough to cause an
* overflow in pts_us calculation, thus the FFMAX. */
double time_frame = FFMAX(mpctx->time_frame, -1);
- unsigned int pts_us = mpctx->last_time + time_frame * 1e6;
+ int64_t pts_us = mpctx->last_time + time_frame * 1e6;
int duration = -1;
double pts2 = vo->next_pts2;
if (pts2 != MP_NOPTS_VALUE && opts->correct_pts &&
@@ -3625,7 +3616,7 @@ static void run_playloop(struct MPContext *mpctx)
}
vo_flip_page(vo, pts_us | 1, duration);
- mpctx->last_vo_flip_duration = (GetTimer() - t2) * 0.000001;
+ mpctx->last_vo_flip_duration = (mp_time_us() - t2) * 0.000001;
if (vo->driver->flip_page_timed) {
// No need to adjust sync based on flip speed
mpctx->last_vo_flip_duration = 0;
@@ -3788,7 +3779,7 @@ static void run_playloop(struct MPContext *mpctx)
* another seek (which could lead to unchanging display). */
if ((mpctx->seek.type && cmd->id != MP_CMD_SEEK) ||
(mpctx->restart_playback && cmd->id == MP_CMD_SEEK &&
- GetTimerMS() - mpctx->start_timestamp < 300))
+ mp_time_sec() - mpctx->start_timestamp < 0.3))
break;
cmd = mp_input_get_cmd(mpctx->input, 0, 0);
run_command(mpctx, cmd);