Index: configure.ac
===================================================================
RCS file: /cvs/gstreamer/gstreamer/configure.ac,v
retrieving revision 1.487
diff -u -r1.487 configure.ac
--- configure.ac	5 Oct 2006 15:31:15 -0000	1.487
+++ configure.ac	13 Oct 2006 13:50:25 -0000
@@ -315,6 +315,102 @@
 AC_FUNC_MMAP
 AM_CONDITIONAL(HAVE_MMAP, test "x$ac_cv_func_mmap_fixed_mapped" = "xyes")
 
+dnl Check for POSIX timers
+AC_CHECK_FUNCS(clock_gettime, [], [
+  AC_CHECK_LIB(rt, clock_gettime, [
+    AC_DEFINE(HAVE_CLOCK_GETTIME, 1)
+    LIBS="$LIBS -lrt"
+  ])
+])
+
+AC_CACHE_CHECK(for posix timers, gst_cv_posix_timers,AC_TRY_RUN([
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+      int main() {
+#if defined(_POSIX_TIMERS) && _POSIX_TIMERS >= 0 && defined(CLOCK_REALTIME)
+        return 0;
+#else
+        return 1;
+#endif
+      }],gst_cv_posix_timers=yes,gst_cv_posix_timers=no))
+
+if test "$gst_cv_posix_timers" = "yes"; then
+  AC_DEFINE(HAVE_POSIX_TIMERS,1,[Have posix timers])
+  GST_HAVE_POSIX_TIMERS_DEFINE="#define GST_HAVE_POSIX_TIMERS 1"
+else
+  GST_HAVE_POSIX_TIMERS_DEFINE="#define GST_HAVE_POSIX_TIMERS 0"
+fi
+AC_SUBST(GST_HAVE_POSIX_TIMERS_DEFINE)
+AM_CONDITIONAL(GST_HAVE_POSIX_TIMERS, test "$gst_cv_posix_timers" = "yes")
+
+AC_CACHE_CHECK(for monotonic clock, gst_cv_monotonic_clock,AC_TRY_RUN([
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+      int main() {
+#if defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 && defined(CLOCK_MONOTONIC)
+        return 0;
+#else
+        return 1;
+#endif
+      }],gst_cv_monotonic_clock=yes,gst_cv_monotonic_clock=no))
+
+if test "$gst_cv_monotonic_clock" = "yes"; then
+  AC_DEFINE(HAVE_MONOTONIC_CLOCK,1,[Have a monotonic clock])
+  GST_HAVE_MONOTONIC_CLOCK_DEFINE="#define GST_HAVE_MONOTONIC_CLOCK 1"
+else
+  GST_HAVE_MONOTONIC_CLOCK_DEFINE="#define GST_HAVE_MONOTONIC_CLOCK 0"
+fi
+AC_SUBST(GST_HAVE_MONOTONIC_CLOCK_DEFINE)
+AM_CONDITIONAL(GST_HAVE_MONOTONIC_CLOCK, test "$gst_cv_monotonic_clock" = "yes")
+
+AC_CACHE_CHECK(for cputime clock, gst_cv_cputime,AC_TRY_RUN([
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+      int main() {
+#if defined(_POSIX_CPUTIME) && _POSIX_CPUTIME >= 0 && defined(CLOCK_PROCESS_CPUTIME_ID)
+        return 0;
+#else
+        return 1;
+#endif
+      }],gst_cv_cputime=yes,gst_cv_cputime=no))
+
+if test "$gst_cv_cputime" = "yes"; then
+  AC_DEFINE(HAVE_CPUTIME,1,[Have a cputime clock])
+  GST_HAVE_CPUTIME_DEFINE="#define GST_HAVE_CPUTIME 1"
+else
+  GST_HAVE_CPUTIME_DEFINE="#define GST_HAVE_CPUTIME 0"
+fi
+AC_SUBST(GST_HAVE_CPUTIME_DEFINE)
+AM_CONDITIONAL(GST_HAVE_CPUTIME, test "$gst_cv_cputime" = "yes")
+
+AC_CACHE_CHECK(for thread cputime clock, gst_cv_thread_cputime,AC_TRY_RUN([
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+      int main() {
+#if defined(_POSIX_THREAD_CPUTIME) && _POSIX_THREAD_CPUTIME >= 0 && defined(CLOCK_THREAD_CPUTIME_ID)
+        return 0;
+#else
+        return 1;
+#endif
+      }],gst_cv_thread_cputime=yes,gst_cv_thread_cputime=no))
+
+if test "$gst_cv_thread_cputime" = "yes"; then
+  AC_DEFINE(HAVE_THREAD_CPUTIME,1,[Have a thread cputime clock])
+  GST_HAVE_THREAD_CPUTIME_DEFINE="#define GST_HAVE_THREAD_CPUTIME 1"
+else
+  GST_HAVE_THREAD_CPUTIME_DEFINE="#define GST_HAVE_THREAD_CPUTIME 0"
+fi
+AC_SUBST(GST_HAVE_THREAD_CPUTIME_DEFINE)
+AM_CONDITIONAL(GST_HAVE_THREAD_CPUTIME, test "$gst_cv_thread_cputime" = "yes")
+
 dnl Check for a way to display the function name in debug output
 GST_CHECK_FUNCTION
 
Index: gst/gstconfig.h.in
===================================================================
RCS file: /cvs/gstreamer/gstreamer/gst/gstconfig.h.in,v
retrieving revision 1.22
diff -u -r1.22 gstconfig.h.in
--- gst/gstconfig.h.in	5 Oct 2006 12:31:07 -0000	1.22
+++ gst/gstconfig.h.in	13 Oct 2006 13:50:25 -0000
@@ -167,6 +167,18 @@
    refcounting */
 @GST_HAVE_GLIB_2_8_DEFINE@
 
+/* whether or not POSIX realtime clock is supported */
+@GST_HAVE_POSIX_TIMERS_DEFINE@
+
+/* whether or not POSIX monotonic clock is supported */
+@GST_HAVE_MONOTONIC_CLOCK_DEFINE@
+
+/* whether or not POSIX per-process clock is supported */
+@GST_HAVE_CPUTIME_DEFINE@
+
+/* whether or not POSIX thread specific clock is supported */
+@GST_HAVE_THREAD_CPUTIME_DEFINE@
+
 /***** Deal with XML stuff, we have to handle both loadsave and registry *****/
 
 #if (! (defined(GST_DISABLE_LOADSAVE) && defined(GST_DISABLE_REGISTRY)) )
Index: gst/gstsystemclock.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/gst/gstsystemclock.c,v
retrieving revision 1.44
diff -u -r1.44 gstsystemclock.c
--- gst/gstsystemclock.c	11 Oct 2006 16:30:14 -0000	1.44
+++ gst/gstsystemclock.c	13 Oct 2006 13:50:25 -0000
@@ -40,18 +40,50 @@
 
 #include "gst_private.h"
 #include "gstinfo.h"
+#include "gstconfig.h"
 
 #include "gstsystemclock.h"
 
 /* Define this to get some extra debug about jitter from each clock_wait */
 #undef WAIT_DEBUGGING
 
+enum
+{
+  PROP_0,
+  PROP_CLOCK_TYPE
+      /* FILL ME */
+};
+
+#define GST_TYPE_CLOCK_TYPE (gst_clock_type_get_type())
+static GType
+gst_clock_type_get_type (void)
+{
+  static GType clock_type_type = 0;
+  static const GEnumValue clock_types[] = {
+    {GST_CLOCK_TYPE_REALTIME, "Realtime", "realtime"},
+    {GST_CLOCK_TYPE_MONOTONIC, "Monotonic", "monotonic"},
+    {GST_CLOCK_TYPE_CPUTIME, "CPU-Time", "cputime"},
+    {GST_CLOCK_TYPE_THREAD_CPUTIME, "Thread CPU-Time", "thread-cputime"},
+    {0, NULL, NULL},
+  };
+
+  if (!clock_type_type) {
+    clock_type_type =
+        g_enum_register_static ("GstClockType", clock_types);
+  }
+  return clock_type_type;
+}
+
 /* the one instance of the systemclock */
 static GstClock *_the_system_clock = NULL;
 
 static void gst_system_clock_class_init (GstSystemClockClass * klass);
 static void gst_system_clock_init (GstSystemClock * clock);
 static void gst_system_clock_dispose (GObject * object);
+static void gst_system_clock_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_system_clock_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
 
 static GstClockTime gst_system_clock_get_internal_time (GstClock * clock);
 static guint64 gst_system_clock_get_resolution (GstClock * clock);
@@ -110,6 +142,13 @@
   parent_class = g_type_class_peek_parent (klass);
 
   gobject_class->dispose = gst_system_clock_dispose;
+  gobject_class->set_property = gst_system_clock_set_property;
+  gobject_class->get_property = gst_system_clock_get_property;
+
+  g_object_class_install_property (gobject_class, PROP_CLOCK_TYPE,
+      g_param_spec_enum ("clock-type", "Clock type",
+          "The type of underlying clock implementation used",
+          GST_TYPE_CLOCK_TYPE, GST_CLOCK_TYPE_REALTIME, G_PARAM_READWRITE));
 
   gstclock_class->get_internal_time = gst_system_clock_get_internal_time;
   gstclock_class->get_resolution = gst_system_clock_get_resolution;
@@ -123,6 +162,11 @@
 {
   GError *error = NULL;
 
+  clock->clock_type = GST_CLOCK_TYPE_REALTIME;
+#if GST_HAVE_POSIX_TIMERS
+  clock->posix_id = CLOCK_REALTIME;
+#endif
+
   GST_OBJECT_FLAG_SET (clock,
       GST_CLOCK_FLAG_CAN_DO_SINGLE_SYNC |
       GST_CLOCK_FLAG_CAN_DO_SINGLE_ASYNC |
@@ -184,6 +228,59 @@
   }
 }
 
+static void
+gst_system_clock_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstSystemClock *src = GST_SYSTEM_CLOCK (object);
+
+  switch (prop_id) {
+    case PROP_CLOCK_TYPE:
+      src->clock_type = g_value_get_enum (value);
+#if GST_HAVE_POSIX_TIMERS
+#if GST_HAVE_MONOTONIC_CLOCK
+      if (src->clock_type == GST_CLOCK_TYPE_MONOTONIC) {
+        src->posix_id = CLOCK_MONOTONIC;
+      } else
+#endif
+#if GST_HAVE_CPUTIME
+      if (src->clock_type == GST_CLOCK_TYPE_CPUTIME) {
+        src->posix_id = CLOCK_PROCESS_CPUTIME_ID;
+      } else
+#endif
+#if GST_HAVE_THREAD_CPUTIME
+      if (src->clock_type == GST_CLOCK_TYPE_THREAD_CPUTIME) {
+        src->posix_id = CLOCK_THREAD_CPUTIME_ID;
+      } else
+#endif
+      {
+        src->posix_id = CLOCK_REALTIME;
+      }
+#endif
+      GST_CAT_DEBUG (GST_CAT_CLOCK, "clock-type set to %d", src->clock_type);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_system_clock_get_property (GObject * object, guint prop_id, GValue * value,
+    GParamSpec * pspec)
+{
+  GstSystemClock *src = GST_SYSTEM_CLOCK (object);
+
+  switch (prop_id) {
+    case PROP_CLOCK_TYPE:
+      g_value_set_enum (value, src->clock_type);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
 /**
  * gst_system_clock_obtain:
  *
@@ -335,17 +432,37 @@
 static GstClockTime
 gst_system_clock_get_internal_time (GstClock * clock)
 {
+#if GST_HAVE_POSIX_TIMERS
+  struct timespec ts;
+
+  if (G_UNLIKELY (clock_gettime (GST_SYSTEM_CLOCK (clock)->posix_id, &ts))) {
+    return GST_CLOCK_TIME_NONE;
+  }
+
+  return GST_TIMESPEC_TO_TIME (ts);
+#else
   GTimeVal timeval;
 
   g_get_current_time (&timeval);
 
   return GST_TIMEVAL_TO_TIME (timeval);
+#endif
 }
 
 static guint64
 gst_system_clock_get_resolution (GstClock * clock)
 {
+#if GST_HAVE_POSIX_TIMERS
+  struct timespec ts;
+
+  if (G_UNLIKELY (clock_getres (GST_SYSTEM_CLOCK (clock)->posix_id, &ts))) {
+    return GST_CLOCK_TIME_NONE;
+  }
+
+  return GST_TIMESPEC_TO_TIME (ts);
+#else
   return 1 * GST_USECOND;
+#endif
 }
 
 /* synchronously wait on the given GstClockEntry.
@@ -368,7 +485,10 @@
 gst_system_clock_id_wait_jitter_unlocked (GstClock * clock,
     GstClockEntry * entry, GstClockTimeDiff * jitter)
 {
-  GstClockTime entryt, real, now, target;
+  GstClockTime entryt, real, now;
+#ifdef WAIT_DEBUGGING
+  GstClockTime target;
+#endif
   GstClockTimeDiff diff;
 
   /* need to call the overridden method */
@@ -380,8 +500,9 @@
     *jitter = GST_CLOCK_DIFF (entryt, now);
   }
   diff = entryt - now;
-  target = gst_system_clock_get_internal_time (clock) + diff;
 
+#ifdef WAIT_DEBUGGING
+  target = gst_system_clock_get_internal_time (clock) + diff;
   GST_CAT_DEBUG (GST_CAT_CLOCK, "entry %p"
       " target %" GST_TIME_FORMAT
       " entry %" GST_TIME_FORMAT
@@ -391,6 +512,15 @@
       entry,
       GST_TIME_ARGS (target),
       GST_TIME_ARGS (entryt), GST_TIME_ARGS (now), GST_TIME_ARGS (real), diff);
+#else
+  GST_CAT_DEBUG (GST_CAT_CLOCK, "entry %p"
+      " entry %" GST_TIME_FORMAT
+      " now %" GST_TIME_FORMAT
+      " real %" GST_TIME_FORMAT
+      " diff %" G_GINT64_FORMAT,
+      entry,
+      GST_TIME_ARGS (entryt), GST_TIME_ARGS (now), GST_TIME_ARGS (real), diff);
+#endif
 
   if (diff > 0) {
     GTimeVal tv;
@@ -399,7 +529,8 @@
     GstClockTime result, final;
 #endif
 
-    GST_TIME_TO_TIMEVAL (target, tv);
+    g_get_current_time (&tv);
+    g_time_val_add (&tv, diff / G_GINT64_CONSTANT (1000));
 
     while (TRUE) {
       /* now wait on the entry, it either times out or the cond is signaled. */
Index: gst/gstsystemclock.h
===================================================================
RCS file: /cvs/gstreamer/gstreamer/gst/gstsystemclock.h,v
retrieving revision 1.15
diff -u -r1.15 gstsystemclock.h
--- gst/gstsystemclock.h	28 Oct 2005 18:14:24 -0000	1.15
+++ gst/gstsystemclock.h	13 Oct 2006 13:50:25 -0000
@@ -25,6 +25,7 @@
 #ifndef __GST_SYSTEM_CLOCK_H__
 #define __GST_SYSTEM_CLOCK_H__
 
+#include <gst/gstconfig.h>
 #include <gst/gstclock.h>
 
 G_BEGIN_DECLS
@@ -41,6 +42,22 @@
 typedef struct _GstSystemClockClass GstSystemClockClass;
 
 /**
+ * GstClockType:
+ * @GST_CLOCK_TYPE_REALTIME       : time since Epoch
+ * @GST_CLOCK_TYPE_MONOTONIC      : monotonic time since some unspecified
+ *                                  starting point
+ * @GST_CLOCK_TYPE_CPUTIME        : high-resolution per-process timer from the
+ *                                  CPU
+ * @GST_CLOCK_TYPE_THREAD_CPUTIME : thread-specific CPU-time clock
+ */
+typedef enum {
+  GST_CLOCK_TYPE_REALTIME       = 0,
+  GST_CLOCK_TYPE_MONOTONIC      = 1,
+  GST_CLOCK_TYPE_CPUTIME        = 2,
+  GST_CLOCK_TYPE_THREAD_CPUTIME = 3
+} GstClockType;
+
+/**
  * GstSystemClock:
  * @clock: The parent clock
  *
@@ -52,8 +69,15 @@
   /*< private >*/
   GThread	*thread;	/* thread for async notify */
   gboolean 	 stopping;
+  GstClockType   clock_type;
+#if GST_HAVE_POSIX_TIMERS
+  clockid_t      posix_id;
 
-  gpointer _gst_reserved[GST_PADDING];
+  gpointer _gst_reserved[GST_PADDING - 2];
+#else
+
+  gpointer _gst_reserved[GST_PADDING - 1];
+#endif
 };
 
 struct _GstSystemClockClass {
Index: tests/check/gst/gstsystemclock.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/tests/check/gst/gstsystemclock.c,v
retrieving revision 1.8
diff -u -r1.8 gstsystemclock.c
--- tests/check/gst/gstsystemclock.c	1 Jul 2006 20:56:55 -0000	1.8
+++ tests/check/gst/gstsystemclock.c	13 Oct 2006 13:50:26 -0000
@@ -75,6 +75,8 @@
   clock = gst_system_clock_obtain ();
   fail_unless (clock != NULL, "Could not create instance of GstSystemClock");
 
+g_object_set (G_OBJECT (clock), "clock-type", GST_CLOCK_TYPE_MONOTONIC, NULL);
+
   gst_clock_debug (clock);
   base = gst_clock_get_time (clock);
 
@@ -138,6 +140,8 @@
   clock = gst_system_clock_obtain ();
   fail_unless (clock != NULL, "Could not create instance of GstSystemClock");
 
+g_object_set (G_OBJECT (clock), "clock-type", GST_CLOCK_TYPE_MONOTONIC, NULL);
+
   gst_clock_debug (clock);
   base = gst_clock_get_time (clock);
 
