2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
4 * 2004 Wim Taymans <wim@fluendo.com>
6 * gstclock.c: Clock subsystem for maintaining time sync
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
26 * @short_description: Abstract class for global clocks
27 * @see_also: #GstSystemClock, #GstPipeline
29 * GStreamer uses a global clock to synchronize the plugins in a pipeline.
30 * Different clock implementations are possible by implementing this abstract
33 * The #GstClock returns a monotonically increasing time with the method
34 * gst_clock_get_time(). Its accuracy and base time depend on the specific
35 * clock implementation but time is always expressed in nanoseconds. Since the
36 * baseline of the clock is undefined, the clock time returned is not
37 * meaningful in itself, what matters are the deltas between two clock times.
38 * The time returned by a clock is called the absolute time.
40 * The pipeline uses the clock to calculate the stream time. Usually all
41 * renderers synchronize to the global clock using the buffer timestamps, the
42 * newsegment events and the element's base time, see #GstPipeline.
44 * A clock implementation can support periodic and single shot clock
45 * notifications both synchronous and asynchronous.
47 * One first needs to create a #GstClockID for the periodic or single shot
48 * notification using gst_clock_new_single_shot_id() or
49 * gst_clock_new_periodic_id().
51 * To perform a blocking wait for the specific time of the #GstClockID use the
52 * gst_clock_id_wait(). To receive a callback when the specific time is reached
53 * in the clock use gst_clock_id_wait_async(). Both these calls can be
54 * interrupted with the gst_clock_id_unschedule() call. If the blocking wait is
55 * unscheduled a return value of #GST_CLOCK_UNSCHEDULED is returned.
57 * Periodic callbacks scheduled async will be repeatedly called automatically
58 * until it is unscheduled. To schedule a sync periodic callback,
59 * gst_clock_id_wait() should be called repeatedly.
61 * The async callbacks can happen from any thread, either provided by the core
62 * or from a streaming thread. The application should be prepared for this.
64 * A #GstClockID that has been unscheduled cannot be used again for any wait
65 * operation, a new #GstClockID should be created and the old unscheduled one
66 * should be destroyed with gst_clock_id_unref().
68 * It is possible to perform a blocking wait on the same #GstClockID from
69 * multiple threads. However, registering the same #GstClockID for multiple
70 * async notifications is not possible, the callback will only be called for
71 * the thread registering the entry last.
73 * None of the wait operations unref the #GstClockID, the owner is responsible
74 * for unreffing the ids itself. This holds for both periodic and single shot
75 * notifications. The reason being that the owner of the #GstClockID has to
76 * keep a handle to the #GstClockID to unblock the wait on FLUSHING events or
77 * state changes and if the entry would be unreffed automatically, the handle
78 * might become invalid without any notification.
80 * These clock operations do not operate on the stream time, so the callbacks
81 * will also occur when not in PLAYING state as if the clock just keeps on
82 * running. Some clocks however do not progress when the element that provided
83 * the clock is not PLAYING.
85 * When a clock has the #GST_CLOCK_FLAG_CAN_SET_MASTER flag set, it can be
86 * slaved to another #GstClock with the gst_clock_set_master(). The clock will
87 * then automatically be synchronized to this master clock by repeatedly
88 * sampling the master clock and the slave clock and recalibrating the slave
89 * clock with gst_clock_set_calibration(). This feature is mostly useful for
90 * plugins that have an internal clock but must operate with another clock
91 * selected by the #GstPipeline. They can track the offset and rate difference
92 * of their internal clock relative to the master clock by using the
93 * gst_clock_get_calibration() function.
95 * The master/slave synchronisation can be tuned with the #GstClock:timeout,
96 * #GstClock:window-size and #GstClock:window-threshold properties.
97 * The #GstClock:timeout property defines the interval to sample the master
98 * clock and run the calibration functions. #GstClock:window-size defines the
99 * number of samples to use when calibrating and #GstClock:window-threshold
100 * defines the minimum number of samples before the calibration is performed.
102 * Last reviewed on 2006-08-11 (0.10.10)
106 #include "gst_private.h"
109 #include "gstclock.h"
111 #include "gstutils.h"
113 #ifndef GST_DISABLE_TRACE
114 /* #define GST_WITH_ALLOC_TRACE */
115 #include "gsttrace.h"
116 static GstAllocTrace *_gst_clock_entry_trace;
119 /* #define DEBUGGING_ENABLED */
121 #define DEFAULT_STATS FALSE
122 #define DEFAULT_WINDOW_SIZE 32
123 #define DEFAULT_WINDOW_THRESHOLD 4
124 #define DEFAULT_TIMEOUT GST_SECOND / 10
131 PROP_WINDOW_THRESHOLD,
135 static void gst_clock_class_init (GstClockClass * klass);
136 static void gst_clock_init (GstClock * clock);
137 static void gst_clock_dispose (GObject * object);
138 static void gst_clock_finalize (GObject * object);
140 static void gst_clock_set_property (GObject * object, guint prop_id,
141 const GValue * value, GParamSpec * pspec);
142 static void gst_clock_get_property (GObject * object, guint prop_id,
143 GValue * value, GParamSpec * pspec);
144 static void gst_clock_update_stats (GstClock * clock);
147 static GstObjectClass *parent_class = NULL;
149 /* static guint gst_clock_signals[LAST_SIGNAL] = { 0 }; */
152 gst_clock_entry_new (GstClock * clock, GstClockTime time,
153 GstClockTime interval, GstClockEntryType type)
155 GstClockEntry *entry;
157 entry = g_slice_new (GstClockEntry);
158 #ifndef GST_DISABLE_TRACE
159 gst_alloc_trace_new (_gst_clock_entry_trace, entry);
161 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
162 "created entry %p, time %" GST_TIME_FORMAT, entry, GST_TIME_ARGS (time));
165 entry->clock = clock;
168 entry->interval = interval;
169 entry->status = GST_CLOCK_OK;
171 entry->user_data = NULL;
173 return (GstClockID) entry;
178 * @id: The #GstClockID to ref
180 * Increase the refcount of given @id.
182 * Returns: The same #GstClockID with increased refcount.
187 gst_clock_id_ref (GstClockID id)
189 g_return_val_if_fail (id != NULL, NULL);
191 g_atomic_int_inc (&((GstClockEntry *) id)->refcount);
197 _gst_clock_id_free (GstClockID id)
199 g_return_if_fail (id != NULL);
201 GST_CAT_DEBUG (GST_CAT_CLOCK, "freed entry %p", id);
203 #ifndef GST_DISABLE_TRACE
204 gst_alloc_trace_free (_gst_clock_entry_trace, id);
206 g_slice_free (GstClockEntry, id);
210 * gst_clock_id_unref:
211 * @id: The #GstClockID to unref
213 * Unref given @id. When the refcount reaches 0 the
214 * #GstClockID will be freed.
219 gst_clock_id_unref (GstClockID id)
223 g_return_if_fail (id != NULL);
225 zero = g_atomic_int_dec_and_test (&((GstClockEntry *) id)->refcount);
226 /* if we ended up with the refcount at zero, free the id */
228 _gst_clock_id_free (id);
233 * gst_clock_new_single_shot_id
234 * @clock: The #GstClockID to get a single shot notification from
235 * @time: the requested time
237 * Get a #GstClockID from @clock to trigger a single shot
238 * notification at the requested time. The single shot id should be
239 * unreffed after usage.
241 * Returns: A #GstClockID that can be used to request the time notification.
246 gst_clock_new_single_shot_id (GstClock * clock, GstClockTime time)
248 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
250 return gst_clock_entry_new (clock,
251 time, GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
255 * gst_clock_new_periodic_id
256 * @clock: The #GstClockID to get a periodic notification id from
257 * @start_time: the requested start time
258 * @interval: the requested interval
260 * Get an ID from @clock to trigger a periodic notification.
261 * The periodic notifications will start at time @start_time and
262 * will then be fired with the given @interval. @id should be unreffed
265 * Returns: A #GstClockID that can be used to request the time notification.
270 gst_clock_new_periodic_id (GstClock * clock, GstClockTime start_time,
271 GstClockTime interval)
273 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
274 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (start_time), NULL);
275 g_return_val_if_fail (interval != 0, NULL);
276 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), NULL);
278 return gst_clock_entry_new (clock,
279 start_time, interval, GST_CLOCK_ENTRY_PERIODIC);
283 * gst_clock_id_compare_func
284 * @id1: A #GstClockID
285 * @id2: A #GstClockID to compare with
287 * Compares the two #GstClockID instances. This function can be used
288 * as a GCompareFunc when sorting ids.
290 * Returns: negative value if a < b; zero if a = b; positive value if a > b
295 gst_clock_id_compare_func (gconstpointer id1, gconstpointer id2)
297 GstClockEntry *entry1, *entry2;
299 entry1 = (GstClockEntry *) id1;
300 entry2 = (GstClockEntry *) id2;
302 if (GST_CLOCK_ENTRY_TIME (entry1) > GST_CLOCK_ENTRY_TIME (entry2)) {
305 if (GST_CLOCK_ENTRY_TIME (entry1) < GST_CLOCK_ENTRY_TIME (entry2)) {
312 * gst_clock_id_get_time
313 * @id: The #GstClockID to query
315 * Get the time of the clock ID
317 * Returns: the time of the given clock id.
322 gst_clock_id_get_time (GstClockID id)
324 g_return_val_if_fail (id != NULL, GST_CLOCK_TIME_NONE);
326 return GST_CLOCK_ENTRY_TIME ((GstClockEntry *) id);
331 * @id: The #GstClockID to wait on
332 * @jitter: A pointer that will contain the jitter, can be %NULL.
334 * Perform a blocking wait on @id.
335 * @id should have been created with gst_clock_new_single_shot_id()
336 * or gst_clock_new_periodic_id() and should not have been unscheduled
337 * with a call to gst_clock_id_unschedule().
339 * If the @jitter argument is not %NULL and this function returns #GST_CLOCK_OK
340 * or #GST_CLOCK_EARLY, it will contain the difference
341 * against the clock and the time of @id when this method was
343 * Positive values indicate how late @id was relative to the clock
344 * (in which case this function will return #GST_CLOCK_EARLY).
345 * Negative values indicate how much time was spent waiting on the clock
346 * before this function returned.
348 * Returns: the result of the blocking wait. #GST_CLOCK_EARLY will be returned
349 * if the current clock time is past the time of @id, #GST_CLOCK_OK if
350 * @id was scheduled in time. #GST_CLOCK_UNSCHEDULED if @id was
351 * unscheduled with gst_clock_id_unschedule().
356 gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
358 GstClockEntry *entry;
361 GstClockTime requested;
362 GstClockClass *cclass;
364 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
366 entry = (GstClockEntry *) id;
367 requested = GST_CLOCK_ENTRY_TIME (entry);
369 clock = GST_CLOCK_ENTRY_CLOCK (entry);
371 /* can't sync on invalid times */
372 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
375 cclass = GST_CLOCK_GET_CLASS (clock);
377 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);
379 /* if we have a wait_jitter function, use that */
380 if (G_LIKELY (cclass->wait_jitter)) {
381 res = cclass->wait_jitter (clock, entry, jitter);
383 /* check if we have a simple _wait function otherwise. The function without
384 * the jitter arg is less optimal as we need to do an additional _get_time()
385 * which is not atomic with the _wait() and a typical _wait() function does
386 * yet another _get_time() anyway. */
387 if (G_UNLIKELY (cclass->wait == NULL))
391 GstClockTime now = gst_clock_get_time (clock);
393 /* jitter is the diff against the clock when this entry is scheduled. Negative
394 * values mean that the entry was in time, a positive value means that the
395 * entry was too late. */
396 *jitter = GST_CLOCK_DIFF (requested, now);
398 res = cclass->wait (clock, entry);
401 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
402 "done waiting entry %p, res: %d", id, res);
404 if (entry->type == GST_CLOCK_ENTRY_PERIODIC)
405 entry->time = requested + entry->interval;
408 gst_clock_update_stats (clock);
415 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
416 "invalid time requested, returning _BADTIME");
417 return GST_CLOCK_BADTIME;
421 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
422 return GST_CLOCK_UNSUPPORTED;
427 * gst_clock_id_wait_async:
428 * @id: a #GstClockID to wait on
429 * @func: The callback function
430 * @user_data: User data passed in the callback
432 * Register a callback on the given #GstClockID @id with the given
433 * function and user_data. When passing a #GstClockID with an invalid
434 * time to this function, the callback will be called immediately
435 * with a time set to GST_CLOCK_TIME_NONE. The callback will
436 * be called when the time of @id has been reached.
438 * The callback @func can be invoked from any thread, either provided by the
439 * core or from a streaming thread. The application should be prepared for this.
441 * Returns: the result of the non blocking wait.
446 gst_clock_id_wait_async (GstClockID id,
447 GstClockCallback func, gpointer user_data)
449 GstClockEntry *entry;
452 GstClockClass *cclass;
453 GstClockTime requested;
455 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
456 g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
458 entry = (GstClockEntry *) id;
459 requested = GST_CLOCK_ENTRY_TIME (entry);
460 clock = GST_CLOCK_ENTRY_CLOCK (entry);
462 /* can't sync on invalid times */
463 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
466 cclass = GST_CLOCK_GET_CLASS (clock);
468 if (G_UNLIKELY (cclass->wait_async == NULL))
472 entry->user_data = user_data;
474 res = cclass->wait_async (clock, entry);
481 (func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
482 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
483 "invalid time requested, returning _BADTIME");
484 return GST_CLOCK_BADTIME;
488 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
489 return GST_CLOCK_UNSUPPORTED;
494 * gst_clock_id_unschedule:
495 * @id: The id to unschedule
497 * Cancel an outstanding request with @id. This can either
498 * be an outstanding async notification or a pending sync notification.
499 * After this call, @id cannot be used anymore to receive sync or
500 * async notifications, you need to create a new #GstClockID.
505 gst_clock_id_unschedule (GstClockID id)
507 GstClockEntry *entry;
509 GstClockClass *cclass;
511 g_return_if_fail (id != NULL);
513 entry = (GstClockEntry *) id;
514 clock = entry->clock;
516 cclass = GST_CLOCK_GET_CLASS (clock);
518 if (G_LIKELY (cclass->unschedule))
519 cclass->unschedule (clock, entry);
524 * GstClock abstract base class implementation
526 G_DEFINE_TYPE (GstClock, gst_clock, GST_TYPE_OBJECT);
529 gst_clock_class_init (GstClockClass * klass)
531 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
533 parent_class = g_type_class_peek_parent (klass);
535 #ifndef GST_DISABLE_TRACE
536 _gst_clock_entry_trace =
537 gst_alloc_trace_register (GST_CLOCK_ENTRY_TRACE_NAME);
540 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_clock_dispose);
541 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_clock_finalize);
542 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_clock_set_property);
543 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_clock_get_property);
545 g_object_class_install_property (gobject_class, PROP_STATS,
546 g_param_spec_boolean ("stats", "Stats",
547 "Enable clock stats (unimplemented)", DEFAULT_STATS,
548 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
549 g_object_class_install_property (gobject_class, PROP_WINDOW_SIZE,
550 g_param_spec_int ("window-size", "Window size",
551 "The size of the window used to calculate rate and offset", 2, 1024,
552 DEFAULT_WINDOW_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
553 g_object_class_install_property (gobject_class, PROP_WINDOW_THRESHOLD,
554 g_param_spec_int ("window-threshold", "Window threshold",
555 "The threshold to start calculating rate and offset", 2, 1024,
556 DEFAULT_WINDOW_THRESHOLD,
557 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
558 g_object_class_install_property (gobject_class, PROP_TIMEOUT,
559 g_param_spec_uint64 ("timeout", "Timeout",
560 "The amount of time, in nanoseconds, to sample master and slave clocks",
561 0, G_MAXUINT64, DEFAULT_TIMEOUT,
562 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
566 gst_clock_init (GstClock * clock)
568 clock->last_time = 0;
569 clock->entries = NULL;
570 clock->entries_changed = g_cond_new ();
571 clock->stats = FALSE;
573 clock->internal_calibration = 0;
574 clock->external_calibration = 0;
575 clock->rate_numerator = 1;
576 clock->rate_denominator = 1;
578 clock->slave_lock = g_mutex_new ();
579 clock->window_size = DEFAULT_WINDOW_SIZE;
580 clock->window_threshold = DEFAULT_WINDOW_THRESHOLD;
581 clock->filling = TRUE;
582 clock->time_index = 0;
583 clock->timeout = DEFAULT_TIMEOUT;
584 clock->times = g_new0 (GstClockTime, 4 * clock->window_size);
588 gst_clock_dispose (GObject * object)
590 GstClock *clock = GST_CLOCK (object);
593 GST_OBJECT_LOCK (clock);
594 master_p = &clock->master;
595 gst_object_replace ((GstObject **) master_p, NULL);
596 GST_OBJECT_UNLOCK (clock);
598 G_OBJECT_CLASS (parent_class)->dispose (object);
602 gst_clock_finalize (GObject * object)
604 GstClock *clock = GST_CLOCK (object);
606 GST_CLOCK_SLAVE_LOCK (clock);
607 if (clock->clockid) {
608 gst_clock_id_unschedule (clock->clockid);
609 gst_clock_id_unref (clock->clockid);
610 clock->clockid = NULL;
612 g_free (clock->times);
614 GST_CLOCK_SLAVE_UNLOCK (clock);
616 g_cond_free (clock->entries_changed);
617 g_mutex_free (clock->slave_lock);
619 G_OBJECT_CLASS (parent_class)->finalize (object);
623 * gst_clock_set_resolution
624 * @clock: a #GstClock
625 * @resolution: The resolution to set
627 * Set the accuracy of the clock. Some clocks have the possibility to operate
628 * with different accuracy at the expense of more resource usage. There is
629 * normally no need to change the default resolution of a clock. The resolution
630 * of a clock can only be changed if the clock has the
631 * #GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set.
633 * Returns: the new resolution of the clock.
636 gst_clock_set_resolution (GstClock * clock, GstClockTime resolution)
638 GstClockClass *cclass;
640 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
641 g_return_val_if_fail (resolution != 0, 0);
643 cclass = GST_CLOCK_GET_CLASS (clock);
645 if (cclass->change_resolution)
647 cclass->change_resolution (clock, clock->resolution, resolution);
649 return clock->resolution;
653 * gst_clock_get_resolution
654 * @clock: a #GstClock
656 * Get the accuracy of the clock. The accuracy of the clock is the granularity
657 * of the values returned by gst_clock_get_time().
659 * Returns: the resolution of the clock in units of #GstClockTime.
664 gst_clock_get_resolution (GstClock * clock)
666 GstClockClass *cclass;
668 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
670 cclass = GST_CLOCK_GET_CLASS (clock);
672 if (cclass->get_resolution)
673 return cclass->get_resolution (clock);
679 * gst_clock_adjust_unlocked
680 * @clock: a #GstClock to use
681 * @internal: a clock time
683 * Converts the given @internal clock time to the external time, adjusting for the
684 * rate and reference time set with gst_clock_set_calibration() and making sure
685 * that the returned time is increasing. This function should be called with the
686 * clock's OBJECT_LOCK held and is mainly used by clock subclasses.
688 * This function is the reverse of gst_clock_unadjust_unlocked().
690 * Returns: the converted time of the clock.
693 gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
695 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
697 /* get calibration values for readability */
698 cinternal = clock->internal_calibration;
699 cexternal = clock->external_calibration;
700 cnum = clock->rate_numerator;
701 cdenom = clock->rate_denominator;
703 /* avoid divide by 0 */
707 /* The formula is (internal - cinternal) * cnum / cdenom + cexternal
709 * Since we do math on unsigned 64-bit ints we have to special case for
710 * internal < cinternal to get the sign right. this case is not very common,
713 if (G_LIKELY (internal >= cinternal)) {
714 ret = gst_util_uint64_scale (internal - cinternal, cnum, cdenom);
717 ret = gst_util_uint64_scale (cinternal - internal, cnum, cdenom);
720 ret = cexternal - ret;
725 /* make sure the time is increasing */
726 clock->last_time = MAX (ret, clock->last_time);
728 return clock->last_time;
732 * gst_clock_unadjust_unlocked
733 * @clock: a #GstClock to use
734 * @external: an external clock time
736 * Converts the given @external clock time to the internal time of @clock,
737 * using the rate and reference time set with gst_clock_set_calibration().
738 * This function should be called with the clock's OBJECT_LOCK held and
739 * is mainly used by clock subclasses.
741 * This function is the reverse of gst_clock_adjust_unlocked().
743 * Returns: the internal time of the clock corresponding to @external.
748 gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external)
750 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
752 /* get calibration values for readability */
753 cinternal = clock->internal_calibration;
754 cexternal = clock->external_calibration;
755 cnum = clock->rate_numerator;
756 cdenom = clock->rate_denominator;
758 /* avoid divide by 0 */
762 /* The formula is (external - cexternal) * cdenom / cnum + cinternal */
763 if (external >= cexternal) {
764 ret = gst_util_uint64_scale (external - cexternal, cdenom, cnum);
767 ret = gst_util_uint64_scale (cexternal - external, cdenom, cnum);
769 ret = cinternal - ret;
777 * gst_clock_get_internal_time
778 * @clock: a #GstClock to query
780 * Gets the current internal time of the given clock. The time is returned
781 * unadjusted for the offset and the rate.
783 * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
784 * given invalid input.
789 gst_clock_get_internal_time (GstClock * clock)
792 GstClockClass *cclass;
794 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
796 cclass = GST_CLOCK_GET_CLASS (clock);
798 if (G_UNLIKELY (cclass->get_internal_time == NULL))
801 ret = cclass->get_internal_time (clock);
803 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
804 GST_TIME_ARGS (ret));
811 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
812 "internal time not supported, return 0");
813 return G_GINT64_CONSTANT (0);
819 * @clock: a #GstClock to query
821 * Gets the current time of the given clock. The time is always
822 * monotonically increasing and adjusted according to the current
825 * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when
826 * given invalid input.
831 gst_clock_get_time (GstClock * clock)
835 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
837 ret = gst_clock_get_internal_time (clock);
839 GST_OBJECT_LOCK (clock);
840 /* this will scale for rate and offset */
841 ret = gst_clock_adjust_unlocked (clock, ret);
842 GST_OBJECT_UNLOCK (clock);
844 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "adjusted time %" GST_TIME_FORMAT,
845 GST_TIME_ARGS (ret));
851 * gst_clock_set_calibration
852 * @clock: a #GstClock to calibrate
853 * @internal: a reference internal time
854 * @external: a reference external time
855 * @rate_num: the numerator of the rate of the clock relative to its
857 * @rate_denom: the denominator of the rate of the clock
859 * Adjusts the rate and time of @clock. A rate of 1/1 is the normal speed of
860 * the clock. Values bigger than 1/1 make the clock go faster.
862 * @internal and @external are calibration parameters that arrange that
863 * gst_clock_get_time() should have been @external at internal time @internal.
864 * This internal time should not be in the future; that is, it should be less
865 * than the value of gst_clock_get_internal_time() when this function is called.
867 * Subsequent calls to gst_clock_get_time() will return clock times computed as
871 * time = (internal_time - internal) * rate_num / rate_denom + external
874 * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
875 * tries to do the integer arithmetic as precisely as possible.
877 * Note that gst_clock_get_time() always returns increasing values so when you
878 * move the clock backwards, gst_clock_get_time() will report the previous value
879 * until the clock catches up.
884 gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
885 external, GstClockTime rate_num, GstClockTime rate_denom)
887 g_return_if_fail (GST_IS_CLOCK (clock));
888 g_return_if_fail (rate_num != GST_CLOCK_TIME_NONE);
889 g_return_if_fail (rate_denom > 0 && rate_denom != GST_CLOCK_TIME_NONE);
890 g_return_if_fail (internal <= gst_clock_get_internal_time (clock));
892 GST_OBJECT_LOCK (clock);
893 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
894 "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT " %"
895 G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f", GST_TIME_ARGS (internal),
896 GST_TIME_ARGS (external), rate_num, rate_denom,
897 gst_guint64_to_gdouble (rate_num) / gst_guint64_to_gdouble (rate_denom));
899 clock->internal_calibration = internal;
900 clock->external_calibration = external;
901 clock->rate_numerator = rate_num;
902 clock->rate_denominator = rate_denom;
903 GST_OBJECT_UNLOCK (clock);
907 * gst_clock_get_calibration
908 * @clock: a #GstClock
909 * @internal: a location to store the internal time
910 * @external: a location to store the external time
911 * @rate_num: a location to store the rate numerator
912 * @rate_denom: a location to store the rate denominator
914 * Gets the internal rate and reference time of @clock. See
915 * gst_clock_set_calibration() for more information.
917 * @internal, @external, @rate_num, and @rate_denom can be left %NULL if the
918 * caller is not interested in the values.
923 gst_clock_get_calibration (GstClock * clock, GstClockTime * internal,
924 GstClockTime * external, GstClockTime * rate_num, GstClockTime * rate_denom)
926 g_return_if_fail (GST_IS_CLOCK (clock));
928 GST_OBJECT_LOCK (clock);
930 *rate_num = clock->rate_numerator;
932 *rate_denom = clock->rate_denominator;
934 *external = clock->external_calibration;
936 *internal = clock->internal_calibration;
937 GST_OBJECT_UNLOCK (clock);
940 /* will be called repeatedly to sample the master and slave clock
941 * to recalibrate the clock */
943 gst_clock_slave_callback (GstClock * master, GstClockTime time,
944 GstClockID id, GstClock * clock)
946 GstClockTime stime, mtime;
949 stime = gst_clock_get_internal_time (clock);
950 mtime = gst_clock_get_time (master);
952 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
953 "master %" GST_TIME_FORMAT ", slave %" GST_TIME_FORMAT,
954 GST_TIME_ARGS (mtime), GST_TIME_ARGS (stime));
956 gst_clock_add_observation (clock, stime, mtime, &r_squared);
958 /* FIXME, we can use the r_squared value to adjust the timeout
959 * value of the clockid */
965 * gst_clock_set_master
966 * @clock: a #GstClock
967 * @master: a master #GstClock
969 * Set @master as the master clock for @clock. @clock will be automatically
970 * calibrated so that gst_clock_get_time() reports the same time as the
973 * A clock provider that slaves its clock to a master can get the current
974 * calibration values with gst_clock_get_calibration().
976 * @master can be %NULL in which case @clock will not be slaved anymore. It will
977 * however keep reporting its time adjusted with the last configured rate
980 * Returns: %TRUE if the clock is capable of being slaved to a master clock.
981 * Trying to set a master on a clock without the
982 * #GST_CLOCK_FLAG_CAN_SET_MASTER flag will make this function return %FALSE.
987 gst_clock_set_master (GstClock * clock, GstClock * master)
991 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
992 g_return_val_if_fail (master != clock, FALSE);
994 GST_OBJECT_LOCK (clock);
995 /* we always allow setting the master to NULL */
996 if (master && !GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER))
999 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1000 "slaving %p to master clock %p", clock, master);
1001 master_p = &clock->master;
1002 gst_object_replace ((GstObject **) master_p, (GstObject *) master);
1003 GST_OBJECT_UNLOCK (clock);
1005 GST_CLOCK_SLAVE_LOCK (clock);
1006 if (clock->clockid) {
1007 gst_clock_id_unschedule (clock->clockid);
1008 gst_clock_id_unref (clock->clockid);
1009 clock->clockid = NULL;
1012 clock->filling = TRUE;
1013 clock->time_index = 0;
1014 /* use the master periodic id to schedule sampling and
1015 * clock calibration. */
1016 clock->clockid = gst_clock_new_periodic_id (master,
1017 gst_clock_get_time (master), clock->timeout);
1018 gst_clock_id_wait_async (clock->clockid,
1019 (GstClockCallback) gst_clock_slave_callback, clock);
1021 GST_CLOCK_SLAVE_UNLOCK (clock);
1028 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1029 "cannot be slaved to a master clock");
1030 GST_OBJECT_UNLOCK (clock);
1036 * gst_clock_get_master
1037 * @clock: a #GstClock
1039 * Get the master clock that @clock is slaved to or %NULL when the clock is
1040 * not slaved to any master clock.
1042 * Returns: a master #GstClock or %NULL when this clock is not slaved to a
1043 * master clock. Unref after usage.
1048 gst_clock_get_master (GstClock * clock)
1050 GstClock *result = NULL;
1052 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
1054 GST_OBJECT_LOCK (clock);
1056 result = gst_object_ref (clock->master);
1057 GST_OBJECT_UNLOCK (clock);
1062 /* http://mathworld.wolfram.com/LeastSquaresFitting.html
1066 do_linear_regression (GstClock * clock, GstClockTime * m_num,
1067 GstClockTime * m_denom, GstClockTime * b, GstClockTime * xbase,
1068 gdouble * r_squared)
1070 GstClockTime *newx, *newy;
1071 GstClockTime xmin, ymin, xbar, ybar, xbar4, ybar4;
1072 GstClockTimeDiff sxx, sxy, syy;
1073 GstClockTime *x, *y;
1077 xbar = ybar = sxx = syy = sxy = 0;
1080 y = clock->times + 2;
1081 n = clock->filling ? clock->time_index : clock->window_size;
1083 #ifdef DEBUGGING_ENABLED
1084 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "doing regression on:");
1085 for (i = j = 0; i < n; i++, j += 4)
1086 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1087 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, x[j], y[j]);
1090 xmin = ymin = G_MAXUINT64;
1091 for (i = j = 0; i < n; i++, j += 4) {
1092 xmin = MIN (xmin, x[j]);
1093 ymin = MIN (ymin, y[j]);
1096 #ifdef DEBUGGING_ENABLED
1097 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min x: %" G_GUINT64_FORMAT,
1099 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min y: %" G_GUINT64_FORMAT,
1103 newx = clock->times + 1;
1104 newy = clock->times + 3;
1106 /* strip off unnecessary bits of precision */
1107 for (i = j = 0; i < n; i++, j += 4) {
1108 newx[j] = x[j] - xmin;
1109 newy[j] = y[j] - ymin;
1112 #ifdef DEBUGGING_ENABLED
1113 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "reduced numbers:");
1114 for (i = j = 0; i < n; i++, j += 4)
1115 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1116 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, newx[j], newy[j]);
1119 /* have to do this precisely otherwise the results are pretty much useless.
1120 * should guarantee that none of these accumulators can overflow */
1122 /* quantities on the order of 1e10 -> 30 bits; window size a max of 2^10, so
1123 this addition could end up around 2^40 or so -- ample headroom */
1124 for (i = j = 0; i < n; i++, j += 4) {
1131 #ifdef DEBUGGING_ENABLED
1132 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbar = %" G_GUINT64_FORMAT,
1134 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " ybar = %" G_GUINT64_FORMAT,
1138 /* multiplying directly would give quantities on the order of 1e20 -> 60 bits;
1139 times the window size that's 70 which is too much. Instead we (1) subtract
1140 off the xbar*ybar in the loop instead of after, to avoid accumulation; (2)
1141 shift off 4 bits from each multiplicand, giving an expected ceiling of 52
1142 bits, which should be enough. Need to check the incoming range and domain
1143 to ensure this is an appropriate loss of precision though. */
1146 for (i = j = 0; i < n; i++, j += 4) {
1147 GstClockTime newx4, newy4;
1149 newx4 = newx[j] >> 4;
1150 newy4 = newy[j] >> 4;
1152 sxx += newx4 * newx4 - xbar4 * xbar4;
1153 syy += newy4 * newy4 - ybar4 * ybar4;
1154 sxy += newx4 * newy4 - xbar4 * ybar4;
1157 if (G_UNLIKELY (sxx == 0))
1163 *b = (ybar + ymin) - gst_util_uint64_scale (xbar, *m_num, *m_denom);
1164 *r_squared = ((double) sxy * (double) sxy) / ((double) sxx * (double) syy);
1166 #ifdef DEBUGGING_ENABLED
1167 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " m = %g",
1168 ((double) *m_num) / *m_denom);
1169 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " b = %" G_GUINT64_FORMAT,
1171 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbase = %" G_GUINT64_FORMAT,
1173 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " r2 = %g", *r_squared);
1180 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "sxx == 0, regression failed");
1186 * gst_clock_add_observation
1187 * @clock: a #GstClock
1188 * @slave: a time on the slave
1189 * @master: a time on the master
1190 * @r_squared: a pointer to hold the result
1192 * The time @master of the master clock and the time @slave of the slave
1193 * clock are added to the list of observations. If enough observations
1194 * are available, a linear regression algorithm is run on the
1195 * observations and @clock is recalibrated.
1197 * If this functions returns %TRUE, @r_squared will contain the
1198 * correlation coefficient of the interpolation. A value of 1.0
1199 * means a perfect regression was performed. This value can
1200 * be used to control the sampling frequency of the master and slave
1203 * Returns: %TRUE if enough observations were added to run the
1204 * regression algorithm.
1209 gst_clock_add_observation (GstClock * clock, GstClockTime slave,
1210 GstClockTime master, gdouble * r_squared)
1212 GstClockTime m_num, m_denom, b, xbase;
1214 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1215 g_return_val_if_fail (r_squared != NULL, FALSE);
1217 GST_CLOCK_SLAVE_LOCK (clock);
1219 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1220 "adding observation slave %" GST_TIME_FORMAT ", master %" GST_TIME_FORMAT,
1221 GST_TIME_ARGS (slave), GST_TIME_ARGS (master));
1223 clock->times[(4 * clock->time_index)] = slave;
1224 clock->times[(4 * clock->time_index) + 2] = master;
1226 clock->time_index++;
1227 if (G_UNLIKELY (clock->time_index == clock->window_size)) {
1228 clock->filling = FALSE;
1229 clock->time_index = 0;
1232 if (G_UNLIKELY (clock->filling
1233 && clock->time_index < clock->window_threshold))
1236 if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared))
1239 GST_CLOCK_SLAVE_UNLOCK (clock);
1241 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1242 "adjusting clock to m=%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT ", b=%"
1243 G_GUINT64_FORMAT " (rsquared=%g)", m_num, m_denom, b, *r_squared);
1245 /* if we have a valid regression, adjust the clock */
1246 gst_clock_set_calibration (clock, xbase, b, m_num, m_denom);
1252 GST_CLOCK_SLAVE_UNLOCK (clock);
1257 /* no valid regression has been done, ignore the result then */
1258 GST_CLOCK_SLAVE_UNLOCK (clock);
1264 gst_clock_update_stats (GstClock * clock)
1269 gst_clock_set_property (GObject * object, guint prop_id,
1270 const GValue * value, GParamSpec * pspec)
1274 clock = GST_CLOCK (object);
1278 GST_OBJECT_LOCK (clock);
1279 clock->stats = g_value_get_boolean (value);
1280 GST_OBJECT_UNLOCK (clock);
1281 g_object_notify (object, "stats");
1283 case PROP_WINDOW_SIZE:
1284 GST_CLOCK_SLAVE_LOCK (clock);
1285 clock->window_size = g_value_get_int (value);
1286 clock->window_threshold =
1287 MIN (clock->window_threshold, clock->window_size);
1289 g_renew (GstClockTime, clock->times, 4 * clock->window_size);
1290 /* restart calibration */
1291 clock->filling = TRUE;
1292 clock->time_index = 0;
1293 GST_CLOCK_SLAVE_UNLOCK (clock);
1295 case PROP_WINDOW_THRESHOLD:
1296 GST_CLOCK_SLAVE_LOCK (clock);
1297 clock->window_threshold =
1298 MIN (g_value_get_int (value), clock->window_size);
1299 GST_CLOCK_SLAVE_UNLOCK (clock);
1302 GST_CLOCK_SLAVE_LOCK (clock);
1303 clock->timeout = g_value_get_uint64 (value);
1304 GST_CLOCK_SLAVE_UNLOCK (clock);
1307 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1313 gst_clock_get_property (GObject * object, guint prop_id,
1314 GValue * value, GParamSpec * pspec)
1318 clock = GST_CLOCK (object);
1322 GST_OBJECT_LOCK (clock);
1323 g_value_set_boolean (value, clock->stats);
1324 GST_OBJECT_UNLOCK (clock);
1326 case PROP_WINDOW_SIZE:
1327 GST_CLOCK_SLAVE_LOCK (clock);
1328 g_value_set_int (value, clock->window_size);
1329 GST_CLOCK_SLAVE_UNLOCK (clock);
1331 case PROP_WINDOW_THRESHOLD:
1332 GST_CLOCK_SLAVE_LOCK (clock);
1333 g_value_set_int (value, clock->window_threshold);
1334 GST_CLOCK_SLAVE_UNLOCK (clock);
1337 GST_CLOCK_SLAVE_LOCK (clock);
1338 g_value_set_uint64 (value, clock->timeout);
1339 GST_CLOCK_SLAVE_UNLOCK (clock);
1342 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);