+2006-08-11 Wim Taymans <wim@fluendo.com>
+
+ * docs/gst/gstreamer-sections.txt:
+ Add GstClockClass vmethod docs.
+
+ * gst/gstcaps.h:
+ Mark #endif with comment for associated #if
+
+ * gst/gstclock.c: (gst_clock_id_wait):
+ * gst/gstclock.h:
+ Add vmethod wait_jitter to avoid an unneeded _get_time() for
+ most clock implementations.
+ Document vmethods.
+ Flesh out docs about resolution methods.
+ API: GstClockClass::wait_jitter
+
+ * gst/gstsystemclock.c: (gst_system_clock_class_init),
+ (gst_system_clock_async_thread),
+ (gst_system_clock_id_wait_jitter_unlocked),
+ (gst_system_clock_id_wait_jitter):
+ Use base class wait_jitter variant for improved performance
+ due to less clock polling.
+
2006-08-11 Edward Hervey <edward@fluendo.com>
* gst/gst.c: (gst_init_check), (init_post):
<FILE>gstclock</FILE>
<TITLE>GstClock</TITLE>
GstClock
+GstClockClass
GstClockTime
GstClockTimeDiff
GstClockID
GST_TYPE_CLOCK_TIME
<SUBSECTION Standard>
-GstClockClass
GST_CLOCK
GST_IS_CLOCK
GST_TYPE_CLOCK
*/
#define GST_DEBUG_CAPS(string, caps) \
GST_DEBUG ( string "%s: " GST_PTR_FORMAT, caps)
-#endif
+
+#endif /* GST_DISABLE_DEPRECATED */
/**
* GST_STATIC_CAPS:
return GST_CLOCK_ENTRY_TIME ((GstClockEntry *) id);
}
-
/**
* gst_clock_id_wait
* @id: The #GstClockID to wait on
cclass = GST_CLOCK_GET_CLASS (clock);
- if (G_UNLIKELY (cclass->wait == NULL))
- goto not_supported;
-
GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);
- if (jitter) {
- GstClockTime now = gst_clock_get_time (clock);
-
- /* jitter is the diff against the clock when this entry is scheduled. Negative
- * values mean that the entry was in time, a positive value means that the
- * entry was too late. */
- *jitter = GST_CLOCK_DIFF (requested, now);
+ /* if we have a wait_jitter function, use that */
+ if (G_LIKELY (cclass->wait_jitter)) {
+ res = cclass->wait_jitter (clock, entry, jitter);
+ } else {
+ /* check if we have a simple _wait function otherwise. The function without
+ * the jitter arg is less optimal as we need to do an additional _get_time()
+ * which is not atomic with the _wait() and a typical _wait() function does
+ * yet another _get_time() anyway. */
+ if (G_UNLIKELY (cclass->wait == NULL))
+ goto not_supported;
+
+ if (jitter) {
+ GstClockTime now = gst_clock_get_time (clock);
+
+ /* jitter is the diff against the clock when this entry is scheduled. Negative
+ * values mean that the entry was in time, a positive value means that the
+ * entry was too late. */
+ *jitter = GST_CLOCK_DIFF (requested, now);
+ }
+ res = cclass->wait (clock, entry);
}
- res = cclass->wait (clock, entry);
GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
"done waiting entry %p, res: %d", id, res);
* @clock: a #GstClock
* @resolution: The resolution to set
*
- * Set the accuracy of the clock.
+ * Set the accuracy of the clock. Some clocks have the possibility to operate
+ * with different accuracy at the expense of more resource usage. There is
+ * normally no need to change the default resolution of a clock. The resolution
+ * of a clock can only be changed if the clock has the
+ * #GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set.
*
* Returns: the new resolution of the clock.
*/
* gst_clock_get_resolution
* @clock: a #GstClock
*
- * Get the accuracy of the clock.
+ * Get the accuracy of the clock. The accuracy of the clock is the granularity
+ * of the values returned by gst_clock_get_time().
*
* Returns: the resolution of the clock in units of #GstClockTime.
*
GstClockTime _gst_reserved[GST_PADDING];
};
+/**
+ * GstClockClass:
+ * @parent_class: the parent class structure
+ * @change_resolution: change the resolution of the clock. Not all values might
+ * be acceptable. The new resolution should be returned.
+ * @get_resolution: get the resolution of the clock.
+ * @get_internal_time: get the internal unadjusted time of the clock.
+ * @wait: perform a blocking wait for the given GstClockEntry. Deprecated,
+ * implement @wait_jitter instead.
+ * @wait_async: perform an asynchronous wait for the given GstClockEntry.
+ * @unschedule: unblock a blocking or async wait operation.
+ * @wait_jitter: perform a blocking wait on the given GstClockEntry and return
+ * the jitter.
+ *
+ * GStreamer clock class. Override the vmethods to implement the clock
+ * functionality.
+ */
struct _GstClockClass {
GstObjectClass parent_class;
- /*< protected >*/
+ /*< public >*/
/* vtable */
GstClockTime (*change_resolution) (GstClock *clock,
GstClockTime old_resolution,
GstClockReturn (*wait_async) (GstClock *clock, GstClockEntry *entry);
void (*unschedule) (GstClock *clock, GstClockEntry *entry);
+ /* ABI added to replace the deprecated wait */
+ GstClockReturn (*wait_jitter) (GstClock *clock, GstClockEntry *entry,
+ GstClockTimeDiff *jitter);
/*< private >*/
- gpointer _gst_reserved[GST_PADDING];
+ gpointer _gst_reserved[GST_PADDING - 1];
};
GType gst_clock_get_type (void);
static GstClockTime gst_system_clock_get_internal_time (GstClock * clock);
static guint64 gst_system_clock_get_resolution (GstClock * clock);
-static GstClockReturn gst_system_clock_id_wait (GstClock * clock,
- GstClockEntry * entry);
-static GstClockReturn gst_system_clock_id_wait_unlocked
- (GstClock * clock, GstClockEntry * entry);
+static GstClockReturn gst_system_clock_id_wait_jitter (GstClock * clock,
+ GstClockEntry * entry, GstClockTimeDiff * jitter);
+static GstClockReturn gst_system_clock_id_wait_jitter_unlocked
+ (GstClock * clock, GstClockEntry * entry, GstClockTimeDiff * jitter);
static GstClockReturn gst_system_clock_id_wait_async (GstClock * clock,
GstClockEntry * entry);
static void gst_system_clock_id_unschedule (GstClock * clock,
gstclock_class->get_internal_time = gst_system_clock_get_internal_time;
gstclock_class->get_resolution = gst_system_clock_get_resolution;
- gstclock_class->wait = gst_system_clock_id_wait;
+ gstclock_class->wait_jitter = gst_system_clock_id_wait_jitter;
gstclock_class->wait_async = gst_system_clock_id_wait_async;
gstclock_class->unschedule = gst_system_clock_id_unschedule;
}
}
/* now wait for the entry, we already hold the lock */
- res = gst_system_clock_id_wait_unlocked (clock, (GstClockID) entry);
+ res =
+ gst_system_clock_id_wait_jitter_unlocked (clock, (GstClockID) entry,
+ NULL);
switch (res) {
case GST_CLOCK_UNSCHEDULED:
* MT safe.
*/
static GstClockReturn
-gst_system_clock_id_wait_unlocked (GstClock * clock, GstClockEntry * entry)
+gst_system_clock_id_wait_jitter_unlocked (GstClock * clock,
+ GstClockEntry * entry, GstClockTimeDiff * jitter)
{
GstClockTime entryt, real, now, target;
GstClockTimeDiff diff;
entryt = GST_CLOCK_ENTRY_TIME (entry);
now = gst_clock_adjust_unlocked (clock, real);
+ if (jitter) {
+ *jitter = GST_CLOCK_DIFF (entryt, now);
+ }
diff = entryt - now;
target = gst_system_clock_get_internal_time (clock) + diff;
(final - target),
((double) (GstClockTimeDiff) (final - target)) / GST_SECOND);
#endif
-
break;
} else {
/* the waiting is interrupted because the GCond was signaled. This can
* be because this or some other entry was unscheduled. */
GST_CAT_DEBUG (GST_CAT_CLOCK, "entry %p unlocked with signal", entry);
- /* if the entry is unscheduled, we can stop waiting for it */
+ /* if the entry is unscheduled, we can stop waiting for it, else we
+ * continue our while loop. */
if (entry->status == GST_CLOCK_UNSCHEDULED)
break;
}
}
static GstClockReturn
-gst_system_clock_id_wait (GstClock * clock, GstClockEntry * entry)
+gst_system_clock_id_wait_jitter (GstClock * clock, GstClockEntry * entry,
+ GstClockTimeDiff * jitter)
{
GstClockReturn ret;
GST_OBJECT_LOCK (clock);
- ret = gst_system_clock_id_wait_unlocked (clock, entry);
+ ret = gst_system_clock_id_wait_jitter_unlocked (clock, entry, jitter);
GST_OBJECT_UNLOCK (clock);
return ret;