Index: mplayer.c =================================================================== RCS file: /cvsroot/mplayer/main/mplayer.c,v retrieving revision 1.756 diff -u -r1.756 mplayer.c --- mplayer.c 10 Jun 2004 11:16:44 -0000 1.756 +++ mplayer.c 24 Jun 2004 09:26:25 -0000 @@ -1117,7 +1117,8 @@ #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 @@ -2215,9 +2216,9 @@ } 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)! Index: osdep/timer-darwin.c =================================================================== RCS file: /cvsroot/mplayer/main/osdep/timer-darwin.c,v retrieving revision 1.3 diff -u -r1.3 timer-darwin.c --- osdep/timer-darwin.c 28 Jan 2004 10:40:29 -0000 1.3 +++ osdep/timer-darwin.c 24 Jun 2004 09:26:25 -0000 @@ -1,170 +1,114 @@ /* - * 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 #include -#include - +#include +#include +#include #include -#include -#include #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 */ -int usec_sleep(int usec_delay) +/* the core sleep function, uses floats and is used in MPlayer G2 */ +float sleep_accurate(float time_frame) { -#if 0 - mach_timespec_t start_time, end_time; - - clock_get_time(clock_port, &start_time); + uint64_t deadline = time_frame / timebase_ratio + mach_absolute_time(); - end_time = start_time; - time_uadd(usec_delay, end_time); + mach_wait_until(deadline); - clock_sleep(clock_port, TIME_ABSOLUTE, end_time, NULL); - - clock_get_time(clock_port, &end_time); + return (mach_absolute_time() - deadline) * timebase_ratio; +} - return usec_delay - udiff_time(start_time, end_time); -#else - usleep(usec_delay); -#endif +/* wrapper for MPlayer G1 */ +int usec_sleep(int usec_delay) +{ + 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 + +int main() { + int i,j, r; + const int delay = 0.1 * 1e6; + 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 < 20; i++) { + j = GetTimer(); +#if 1 + r = usec_sleep(delay); +#else + r = sleep_accurate(delay / 1e6) * 1e6; +#endif + j = (GetTimer() - j) - delay; + printf("sleep time:\t%i (%i)\n", + j, j - r); } - 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 Index: osdep/timer-lx.c =================================================================== RCS file: /cvsroot/mplayer/main/osdep/timer-lx.c,v retrieving revision 1.7 diff -u -r1.7 timer-lx.c --- osdep/timer-lx.c 24 Mar 2002 00:58:27 -0000 1.7 +++ osdep/timer-lx.c 24 Jun 2004 09:26:25 -0000 @@ -6,6 +6,13 @@ #include #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 @@ #endif } - // Returns current time in microseconds unsigned int GetTimer(){ struct timeval tv; Index: osdep/timer-win2.c =================================================================== RCS file: /cvsroot/mplayer/main/osdep/timer-win2.c,v retrieving revision 1.2 diff -u -r1.2 timer-win2.c --- osdep/timer-win2.c 16 Nov 2003 15:11:52 -0000 1.2 +++ osdep/timer-win2.c 24 Jun 2004 09:26:25 -0000 @@ -4,6 +4,8 @@ #include #include "timer.h" +const char *timer_name = "Windows native"; + // Returns current time in microseconds unsigned int GetTimer(){ return timeGetTime() * 1000; Index: osdep/timer.h =================================================================== RCS file: /cvsroot/mplayer/main/osdep/timer.h,v retrieving revision 1.5 diff -u -r1.5 timer.h --- osdep/timer.h 25 Feb 2002 14:24:11 -0000 1.5 +++ osdep/timer.h 24 Jun 2004 09:26:25 -0000 @@ -1,6 +1,8 @@ #ifndef __TIMER_H #define __TIMER_H +extern const char *timer_name; + void InitTimer(); unsigned int GetTimer(); unsigned int GetTimerMS();