summaryrefslogtreecommitdiff
path: root/gst/gstsystemclock.c
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2009-08-28 17:02:30 +0200
committerWim Taymans <wim.taymans@collabora.co.uk>2009-08-28 17:02:30 +0200
commite54e5eb9bb70b4e1fe2fbf93dcefd8eabcbe7efa (patch)
treeeaea29291940ea916306e84662a0a941e71ca00c /gst/gstsystemclock.c
parent7c054f5f53f67288c441bf366aae031b113c0d2a (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.c84
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
}