diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2009-08-28 17:02:30 +0200 |
---|---|---|
committer | Wim Taymans <wim.taymans@collabora.co.uk> | 2009-08-28 17:02:30 +0200 |
commit | e54e5eb9bb70b4e1fe2fbf93dcefd8eabcbe7efa (patch) | |
tree | eaea29291940ea916306e84662a0a941e71ca00c /gst/gstsystemclock.c | |
parent | 7c054f5f53f67288c441bf366aae031b113c0d2a (diff) |
systemclock: use preformance counters on windows
Based on clock implementation by HÃ¥vard Graff <havard.graff@tandberg.com>
Try to get the time on windows using the performance counters. These have a much
higher resolution and accuracy than the regular getcurrenttime(). Be careful to
fall back to regular getcurrenttime() or posix clocks when performance counters
are not available.
Diffstat (limited to 'gst/gstsystemclock.c')
-rw-r--r-- | gst/gstsystemclock.c | 84 |
1 files changed, 64 insertions, 20 deletions
diff --git a/gst/gstsystemclock.c b/gst/gstsystemclock.c index 2a74fed49..2b2ef0b8d 100644 --- a/gst/gstsystemclock.c +++ b/gst/gstsystemclock.c @@ -46,6 +46,12 @@ #include <errno.h> +#ifdef G_OS_WIN32 +# define WIN32_LEAN_AND_MEAN /* prevents from including too many things */ +# include <windows.h> /* QueryPerformance* stuff */ +# undef WIN32_LEAN_AND_MEAN +#endif /* G_OS_WIN32 */ + /* Define this to get some extra debug about jitter from each clock_wait */ #undef WAIT_DEBUGGING @@ -55,6 +61,11 @@ struct _GstSystemClockPrivate GstPoll *timer; gint wakeup_count; /* the number of entries with a pending wakeup */ gboolean async_wakeup; /* if the wakeup was because of a async list change */ + +#ifdef G_OS_WIN32 + LARGE_INTEGER start; + LARGE_INTEGER frequency; +#endif /* G_OS_WIN32 */ }; #define GST_SYSTEM_CLOCK_GET_PRIVATE(obj) \ @@ -155,6 +166,14 @@ gst_system_clock_init (GstSystemClock * clock) clock->priv->clock_type = DEFAULT_CLOCK_TYPE; clock->priv->timer = gst_poll_new_timer (); +#ifdef G_OS_WIN32 + QueryPerformanceFrequency (&clock->priv->frequency); + /* can be 0 if the hardware does not have hardware support */ + if (clock->priv->frequency.QuadPart != 0) + /* we take a base time so that time starts from 0 to ease debugging */ + QueryPerformanceCounter (&clock->priv->start); +#endif /* G_OS_WIN32 */ + #if 0 /* Uncomment this to start the async clock thread straight away */ GST_OBJECT_LOCK (clock); @@ -459,42 +478,67 @@ clock_type_to_posix_id (GstClockType clock_type) static GstClockTime gst_system_clock_get_internal_time (GstClock * clock) { -#ifdef HAVE_POSIX_TIMERS - GstSystemClock *sysclock = GST_SYSTEM_CLOCK_CAST (clock); - clockid_t ptype; - struct timespec ts; - - ptype = clock_type_to_posix_id (sysclock->priv->clock_type); +#ifdef G_OS_WIN32 + if (clock->priv->frequency.QuadPart != 0) { + GstSystemClock *sysclock = GST_SYSTEM_CLOCK_CAST (clock); + LARGE_INTEGER now; + + /* we prefer the highly accurate performance counters on windows */ + QueryPerformanceCounter (&now); + + return gst_util_uint64_scale (now.QuadPart - sysclock->priv->start.QuadPart, + GST_SECOND, sysclock->priv->frequency.QuadPart); + } else +#endif /* G_OS_WIN32 */ +#if !defined HAVE_POSIX_TIMERS + { + GTimeVal timeval; - if (G_UNLIKELY (clock_gettime (ptype, &ts))) - return GST_CLOCK_TIME_NONE; + g_get_current_time (&timeval); - return GST_TIMESPEC_TO_TIME (ts); + return GST_TIMEVAL_TO_TIME (timeval); + } #else - GTimeVal timeval; + { + GstSystemClock *sysclock = GST_SYSTEM_CLOCK_CAST (clock); + clockid_t ptype; + struct timespec ts; + + ptype = clock_type_to_posix_id (sysclock->priv->clock_type); - g_get_current_time (&timeval); + if (G_UNLIKELY (clock_gettime (ptype, &ts))) + return GST_CLOCK_TIME_NONE; - return GST_TIMEVAL_TO_TIME (timeval); + return GST_TIMESPEC_TO_TIME (ts); + } #endif } static guint64 gst_system_clock_get_resolution (GstClock * clock) { +#ifdef G_OS_WIN32 + if (clock->priv->frequency.QuadPart != 0) { + return GST_SECOND / sysclock->priv->frequency.QuadPart; + } else +#endif /* G_OS_WIN32 */ #ifdef HAVE_POSIX_TIMERS - GstSystemClock *sysclock = GST_SYSTEM_CLOCK_CAST (clock); - clockid_t ptype; - struct timespec ts; + { + GstSystemClock *sysclock = GST_SYSTEM_CLOCK_CAST (clock); + clockid_t ptype; + struct timespec ts; - ptype = clock_type_to_posix_id (sysclock->priv->clock_type); + ptype = clock_type_to_posix_id (sysclock->priv->clock_type); - if (G_UNLIKELY (clock_getres (ptype, &ts))) - return GST_CLOCK_TIME_NONE; + if (G_UNLIKELY (clock_getres (ptype, &ts))) + return GST_CLOCK_TIME_NONE; - return GST_TIMESPEC_TO_TIME (ts); + return GST_TIMESPEC_TO_TIME (ts); + } #else - return 1 * GST_USECOND; + { + return 1 * GST_USECOND; + } #endif } |