mirror of
https://github.com/mpv-player/mpv
synced 2025-03-21 10:51:51 +00:00
Native darwin timer update.
Patch by Dan Christiansen <danchr@daimi.au.dk> git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@12955 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
37e68033df
commit
e68d7f6858
@ -1127,7 +1127,8 @@ if(!codecs_file || !parse_codec_cfg(codecs_file)){
|
||||
#endif
|
||||
if(rtc_fd<0)
|
||||
#endif
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, "Using %s timing\n",softsleep?"software":"usleep()");
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, "Using %s timing\n",
|
||||
softsleep?"software":timer_name);
|
||||
|
||||
#ifdef USE_TERMCAP
|
||||
if ( !use_gui ) load_termcap(NULL); // load key-codes
|
||||
@ -2232,9 +2233,9 @@ if(time_frame>0.001 && !(vo_flags&256)){
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// -------- USLEEP + SOFTSLEEP -----------
|
||||
// -------- TIMER + SOFTSLEEP -----------
|
||||
float min=softsleep?0.021:0.005;
|
||||
current_module="sleep_usleep";
|
||||
current_module="sleep_timer";
|
||||
while(time_frame>min){
|
||||
if(time_frame<=0.020)
|
||||
usec_sleep(0); // sleeps 1 clock tick (10ms)!
|
||||
|
@ -1,170 +1,116 @@
|
||||
/*
|
||||
* Precise timer routines using Mach kernel-space timing.
|
||||
* Precise timer routines using Mach timing
|
||||
*
|
||||
* It reports to be accurate by ~20us, unless the task is preempted.
|
||||
* Copyright (c) 2003-2004, Dan Villiom Podlaski Christiansen
|
||||
*
|
||||
* (C) 2003 Dan Christiansen
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* Released into the public domain.
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <sys/time.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/clock.h>
|
||||
|
||||
#include "../config.h"
|
||||
#include "../mp_msg.h"
|
||||
#include "timer.h"
|
||||
|
||||
/* Utility macros for mach_timespec_t - it uses nsec rather than usec */
|
||||
|
||||
/* returns time from t1 to t2, in seconds (as float) */
|
||||
#define diff_time(t1, t2) \
|
||||
(((t2).tv_sec - (t1).tv_sec) + \
|
||||
((t2).tv_nsec - (t1).tv_nsec) / 1e9)
|
||||
|
||||
/* returns time from t1 to t2, in microseconds (as integer) */
|
||||
#define udiff_time(t1, t2) \
|
||||
(((t2).tv_sec - (t1).tv_sec) * 1000000 + \
|
||||
((t2).tv_nsec - (t1).tv_nsec) / 1000)
|
||||
|
||||
/* returns float value of t, in seconds */
|
||||
#define time_to_float(t) \
|
||||
((t).tv_sec + (t).tv_nsec / 1e9)
|
||||
|
||||
/* returns integer value of t, in microseconds */
|
||||
#define time_to_usec(t) \
|
||||
((t).tv_sec * 1000000 + (t).tv_nsec / 1000)
|
||||
|
||||
/* sets ts to the value of f, in seconds */
|
||||
#define float_to_time(f, ts) \
|
||||
do { \
|
||||
(ts).tv_sec = (unsigned int)(f); \
|
||||
(ts).tv_nsec = (int)(((f) - (ts).sec) / 1000000000.0); \
|
||||
} while (0)
|
||||
|
||||
/* sets ts to the value of i, in microseconds */
|
||||
#define usec_to_time(i, ts) \
|
||||
do { \
|
||||
(ts).tv_sec = (i) / 1000000; \
|
||||
(ts).tv_nsec = (i) % 1000000 * 1000; \
|
||||
} while (0)
|
||||
|
||||
#define time_uadd(i, ts) \
|
||||
do { \
|
||||
(ts).tv_sec += (i) / 1000000; \
|
||||
(ts).tv_nsec += (i) % 1000000 * 1000; \
|
||||
while ((ts).tv_nsec > 1000000000) { \
|
||||
(ts).tv_sec++; \
|
||||
(ts).tv_nsec -= 1000000000; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* global variables */
|
||||
static double relative_time, startup_time;
|
||||
static double timebase_ratio;
|
||||
static mach_port_t clock_port;
|
||||
|
||||
const char *timer_name = "Darwin accurate";
|
||||
|
||||
/* sleep usec_delay microseconds */
|
||||
/* the core sleep function, uses floats and is used in MPlayer G2 */
|
||||
float sleep_accurate(float time_frame)
|
||||
{
|
||||
uint64_t deadline = time_frame / timebase_ratio + mach_absolute_time();
|
||||
|
||||
mach_wait_until(deadline);
|
||||
|
||||
return (mach_absolute_time() - deadline) * timebase_ratio;
|
||||
}
|
||||
|
||||
/* wrapper for MPlayer G1 */
|
||||
int usec_sleep(int usec_delay)
|
||||
{
|
||||
#if 0
|
||||
mach_timespec_t start_time, end_time;
|
||||
|
||||
clock_get_time(clock_port, &start_time);
|
||||
|
||||
end_time = start_time;
|
||||
time_uadd(usec_delay, end_time);
|
||||
|
||||
clock_sleep(clock_port, TIME_ABSOLUTE, end_time, NULL);
|
||||
|
||||
clock_get_time(clock_port, &end_time);
|
||||
|
||||
return usec_delay - udiff_time(start_time, end_time);
|
||||
#else
|
||||
usleep(usec_delay);
|
||||
#endif
|
||||
return sleep_accurate(usec_delay / 1e6) * 1e6;
|
||||
}
|
||||
|
||||
|
||||
/* Returns current time in microseconds */
|
||||
/* current time in microseconds */
|
||||
unsigned int GetTimer()
|
||||
{
|
||||
return (unsigned int)((mach_absolute_time() * timebase_ratio - startup_time)
|
||||
* 1e6);
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns current time in milliseconds */
|
||||
/* current time in milliseconds */
|
||||
unsigned int GetTimerMS()
|
||||
{
|
||||
return (unsigned int)(GetTimer() / 1000);
|
||||
}
|
||||
|
||||
/* Returns time spent between now and last call in seconds */
|
||||
/* time spent between now and last call in seconds */
|
||||
float GetRelativeTime()
|
||||
{
|
||||
double last_time;
|
||||
|
||||
last_time = relative_time;
|
||||
double last_time = relative_time;
|
||||
|
||||
if (!relative_time)
|
||||
InitTimer();
|
||||
|
||||
relative_time = mach_absolute_time() * timebase_ratio;
|
||||
|
||||
return (float)(relative_time-last_time);
|
||||
}
|
||||
|
||||
/* Initialize timer, must be called at least once at start */
|
||||
/* initialize timer, must be called at least once at start */
|
||||
void InitTimer()
|
||||
{
|
||||
struct mach_timebase_info timebase;
|
||||
|
||||
/* get base for mach_absolute_time() */
|
||||
mach_timebase_info(&timebase);
|
||||
timebase_ratio = (double)timebase.numer / (double)timebase.denom
|
||||
* (double)1e-9;
|
||||
|
||||
/* get mach port for the clock */
|
||||
host_get_clock_service(mach_host_self(), REALTIME_CLOCK, &clock_port);
|
||||
|
||||
/* prepare for GetRelativeTime() */
|
||||
|
||||
relative_time = startup_time =
|
||||
(double)(mach_absolute_time() * timebase_ratio);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
int main()
|
||||
{
|
||||
const long delay = 0.001*1e6;
|
||||
const unsigned short attempts = 100;
|
||||
int i,j[attempts],t[attempts],r[attempts];
|
||||
double sqtotal;
|
||||
double total;
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
int i,j, r, c = 200;
|
||||
long long t = 0;
|
||||
|
||||
InitTimer();
|
||||
|
||||
for (i = 0; i < attempts; i++) {
|
||||
t[i] = j[i] = GetTimer();
|
||||
r[i] = usec_sleep(delay);
|
||||
j[i] = delay-(GetTimer() - j[i]);
|
||||
fflush(stdout);
|
||||
for (i = 0; i < c; i++) {
|
||||
const int delay = rand() / (RAND_MAX / 1e5);
|
||||
j = GetTimer();
|
||||
#if 1
|
||||
r = usec_sleep(delay);
|
||||
#else
|
||||
r = sleep_accurate(delay / 1e6) * 1e6;
|
||||
#endif
|
||||
j = (GetTimer() - j) - delay;
|
||||
printf("sleep time:%8i %5i (%i)\n", delay, j, j - r);
|
||||
t += j - r;
|
||||
}
|
||||
fprintf(stderr, "average error:\t%lli\n", t / c);
|
||||
|
||||
for (i = 0; i < attempts; i++) {
|
||||
sqtotal += j[i]*j[i];
|
||||
total += j[i];
|
||||
printf("%2i=%0.06g \tr: %9i\tj: %9i\tr - j:%9i\n",
|
||||
i, t[i] / 1e6, r[i], j[i], r[i] - j[i]);
|
||||
}
|
||||
|
||||
printf("attempts: %i\ttotal=%g\trms=%g\tavg=%g\n", attempts, total,
|
||||
sqrt(sqtotal/attempts),total/attempts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -6,6 +6,13 @@
|
||||
#include <sys/time.h>
|
||||
#include "../config.h"
|
||||
|
||||
const char *timer_name() =
|
||||
#ifdef HAVE_NANOSLEEP
|
||||
"nanosleep()";
|
||||
#else
|
||||
"usleep()";
|
||||
#endif
|
||||
|
||||
int usec_sleep(int usec_delay)
|
||||
{
|
||||
#ifdef HAVE_NANOSLEEP
|
||||
@ -18,7 +25,6 @@ int usec_sleep(int usec_delay)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Returns current time in microseconds
|
||||
unsigned int GetTimer(){
|
||||
struct timeval tv;
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <mmsystem.h>
|
||||
#include "timer.h"
|
||||
|
||||
const char *timer_name = "Windows native";
|
||||
|
||||
// Returns current time in microseconds
|
||||
unsigned int GetTimer(){
|
||||
return timeGetTime() * 1000;
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef __TIMER_H
|
||||
#define __TIMER_H
|
||||
|
||||
extern const char *timer_name;
|
||||
|
||||
void InitTimer();
|
||||
unsigned int GetTimer();
|
||||
unsigned int GetTimerMS();
|
||||
|
Loading…
Reference in New Issue
Block a user