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
31 * base class or, more conveniently, by subclassing #GstSystemClock.
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 running 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 running 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 2009-05-21 (0.10.24)
106 #include "gst_private.h"
109 #include "gstclock.h"
111 #include "gstutils.h"
112 #include "glib-compat-private.h"
114 #ifndef GST_DISABLE_TRACE
115 /* #define GST_WITH_ALLOC_TRACE */
116 #include "gsttrace.h"
117 static GstAllocTrace *_gst_clock_entry_trace;
120 /* #define DEBUGGING_ENABLED */
122 #define DEFAULT_WINDOW_SIZE 32
123 #define DEFAULT_WINDOW_THRESHOLD 4
124 #define DEFAULT_TIMEOUT GST_SECOND / 10
130 PROP_WINDOW_THRESHOLD,
134 struct _GstClockPrivate
141 #define read_seqbegin(clock) \
142 g_atomic_int_get (&clock->priv->post_count);
144 static inline gboolean
145 read_seqretry (GstClock * clock, gint seq)
147 /* no retry if the seqnum did not change */
148 if (G_LIKELY (seq == g_atomic_int_get (&clock->priv->pre_count)))
151 /* wait for the writer to finish and retry */
152 GST_OBJECT_LOCK (clock);
153 GST_OBJECT_UNLOCK (clock);
157 #define write_seqlock(clock) \
159 GST_OBJECT_LOCK (clock); \
160 g_atomic_int_inc (&clock->priv->pre_count); \
163 #define write_sequnlock(clock) \
165 g_atomic_int_inc (&clock->priv->post_count); \
166 GST_OBJECT_UNLOCK (clock); \
169 static void gst_clock_dispose (GObject * object);
170 static void gst_clock_finalize (GObject * object);
172 static void gst_clock_set_property (GObject * object, guint prop_id,
173 const GValue * value, GParamSpec * pspec);
174 static void gst_clock_get_property (GObject * object, guint prop_id,
175 GValue * value, GParamSpec * pspec);
176 static void gst_clock_update_stats (GstClock * clock);
179 /* static guint gst_clock_signals[LAST_SIGNAL] = { 0 }; */
182 gst_clock_entry_new (GstClock * clock, GstClockTime time,
183 GstClockTime interval, GstClockEntryType type)
185 GstClockEntry *entry;
187 entry = g_slice_new (GstClockEntry);
188 #ifndef GST_DISABLE_TRACE
189 _gst_alloc_trace_new (_gst_clock_entry_trace, entry);
191 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
192 "created entry %p, time %" GST_TIME_FORMAT, entry, GST_TIME_ARGS (time));
195 entry->clock = clock;
198 entry->interval = interval;
199 entry->status = GST_CLOCK_OK;
201 entry->user_data = NULL;
202 entry->destroy_data = NULL;
203 entry->unscheduled = FALSE;
204 entry->woken_up = FALSE;
206 return (GstClockID) entry;
209 /* WARNING : Does not modify the refcount
210 * WARNING : Do not use if a pending clock operation is happening on that entry */
212 gst_clock_entry_reinit (GstClock * clock, GstClockEntry * entry,
213 GstClockTime time, GstClockTime interval, GstClockEntryType type)
215 g_return_val_if_fail (entry->status != GST_CLOCK_BUSY, FALSE);
216 g_return_val_if_fail (entry->clock == clock, FALSE);
220 entry->interval = interval;
221 entry->status = GST_CLOCK_OK;
222 entry->unscheduled = FALSE;
223 entry->woken_up = FALSE;
229 * gst_clock_single_shot_id_reinit:
230 * @clock: a #GstClock
232 * @time: The requested time.
234 * Reinitializes the provided single shot @id to the provided time. Does not
235 * modify the reference count.
237 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
238 * @time, else %FALSE.
243 gst_clock_single_shot_id_reinit (GstClock * clock, GstClockID id,
246 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, time,
247 GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
251 * gst_clock_periodic_id_reinit:
252 * @clock: a #GstClock
254 * @start_time: the requested start time
255 * @interval: the requested interval
257 * Reinitializes the provided periodic @id to the provided start time and
258 * interval. Does not modify the reference count.
260 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
261 * @time, else %FALSE.
267 gst_clock_periodic_id_reinit (GstClock * clock, GstClockID id,
268 GstClockTime start_time, GstClockTime interval)
270 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, start_time,
271 interval, GST_CLOCK_ENTRY_PERIODIC);
276 * @id: The #GstClockID to ref
278 * Increase the refcount of given @id.
280 * Returns: (transfer full): The same #GstClockID with increased refcount.
285 gst_clock_id_ref (GstClockID id)
287 g_return_val_if_fail (id != NULL, NULL);
289 g_atomic_int_inc (&((GstClockEntry *) id)->refcount);
295 _gst_clock_id_free (GstClockID id)
297 GstClockEntry *entry;
298 g_return_if_fail (id != NULL);
300 GST_CAT_DEBUG (GST_CAT_CLOCK, "freed entry %p", id);
301 entry = (GstClockEntry *) id;
302 if (entry->destroy_data)
303 entry->destroy_data (entry->user_data);
305 #ifndef GST_DISABLE_TRACE
306 _gst_alloc_trace_free (_gst_clock_entry_trace, id);
308 g_slice_free (GstClockEntry, id);
312 * gst_clock_id_unref:
313 * @id: (transfer full): The #GstClockID to unref
315 * Unref given @id. When the refcount reaches 0 the
316 * #GstClockID will be freed.
321 gst_clock_id_unref (GstClockID id)
325 g_return_if_fail (id != NULL);
327 zero = g_atomic_int_dec_and_test (&((GstClockEntry *) id)->refcount);
328 /* if we ended up with the refcount at zero, free the id */
330 _gst_clock_id_free (id);
335 * gst_clock_new_single_shot_id:
336 * @clock: The #GstClockID to get a single shot notification from
337 * @time: the requested time
339 * Get a #GstClockID from @clock to trigger a single shot
340 * notification at the requested time. The single shot id should be
341 * unreffed after usage.
343 * Free-function: gst_clock_id_unref
345 * Returns: (transfer full): a #GstClockID that can be used to request the
351 gst_clock_new_single_shot_id (GstClock * clock, GstClockTime time)
353 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
355 return gst_clock_entry_new (clock,
356 time, GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
360 * gst_clock_new_periodic_id:
361 * @clock: The #GstClockID to get a periodic notification id from
362 * @start_time: the requested start time
363 * @interval: the requested interval
365 * Get an ID from @clock to trigger a periodic notification.
366 * The periodic notifications will start at time @start_time and
367 * will then be fired with the given @interval. @id should be unreffed
370 * Free-function: gst_clock_id_unref
372 * Returns: (transfer full): a #GstClockID that can be used to request the
378 gst_clock_new_periodic_id (GstClock * clock, GstClockTime start_time,
379 GstClockTime interval)
381 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
382 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (start_time), NULL);
383 g_return_val_if_fail (interval != 0, NULL);
384 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), NULL);
386 return gst_clock_entry_new (clock,
387 start_time, interval, GST_CLOCK_ENTRY_PERIODIC);
391 * gst_clock_id_compare_func
392 * @id1: A #GstClockID
393 * @id2: A #GstClockID to compare with
395 * Compares the two #GstClockID instances. This function can be used
396 * as a GCompareFunc when sorting ids.
398 * Returns: negative value if a < b; zero if a = b; positive value if a > b
403 gst_clock_id_compare_func (gconstpointer id1, gconstpointer id2)
405 GstClockEntry *entry1, *entry2;
407 entry1 = (GstClockEntry *) id1;
408 entry2 = (GstClockEntry *) id2;
410 if (GST_CLOCK_ENTRY_TIME (entry1) > GST_CLOCK_ENTRY_TIME (entry2)) {
413 if (GST_CLOCK_ENTRY_TIME (entry1) < GST_CLOCK_ENTRY_TIME (entry2)) {
420 * gst_clock_id_get_time
421 * @id: The #GstClockID to query
423 * Get the time of the clock ID
425 * Returns: the time of the given clock id.
430 gst_clock_id_get_time (GstClockID id)
432 g_return_val_if_fail (id != NULL, GST_CLOCK_TIME_NONE);
434 return GST_CLOCK_ENTRY_TIME ((GstClockEntry *) id);
439 * @id: The #GstClockID to wait on
440 * @jitter: (out) (allow-none): a pointer that will contain the jitter,
443 * Perform a blocking wait on @id.
444 * @id should have been created with gst_clock_new_single_shot_id()
445 * or gst_clock_new_periodic_id() and should not have been unscheduled
446 * with a call to gst_clock_id_unschedule().
448 * If the @jitter argument is not %NULL and this function returns #GST_CLOCK_OK
449 * or #GST_CLOCK_EARLY, it will contain the difference
450 * against the clock and the time of @id when this method was
452 * Positive values indicate how late @id was relative to the clock
453 * (in which case this function will return #GST_CLOCK_EARLY).
454 * Negative values indicate how much time was spent waiting on the clock
455 * before this function returned.
457 * Returns: the result of the blocking wait. #GST_CLOCK_EARLY will be returned
458 * if the current clock time is past the time of @id, #GST_CLOCK_OK if
459 * @id was scheduled in time. #GST_CLOCK_UNSCHEDULED if @id was
460 * unscheduled with gst_clock_id_unschedule().
465 gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
467 GstClockEntry *entry;
470 GstClockTime requested;
471 GstClockClass *cclass;
473 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
475 entry = (GstClockEntry *) id;
476 requested = GST_CLOCK_ENTRY_TIME (entry);
478 clock = GST_CLOCK_ENTRY_CLOCK (entry);
480 /* can't sync on invalid times */
481 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
484 cclass = GST_CLOCK_GET_CLASS (clock);
486 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);
488 /* if we have a wait_jitter function, use that */
489 if (G_UNLIKELY (cclass->wait == NULL))
492 res = cclass->wait (clock, entry, jitter);
494 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
495 "done waiting entry %p, res: %d", id, res);
497 if (entry->type == GST_CLOCK_ENTRY_PERIODIC)
498 entry->time = requested + entry->interval;
505 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
506 "invalid time requested, returning _BADTIME");
507 return GST_CLOCK_BADTIME;
511 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
512 return GST_CLOCK_UNSUPPORTED;
517 * gst_clock_id_wait_async_full:
518 * @id: a #GstClockID to wait on
519 * @func: The callback function
520 * @user_data: User data passed in the callback
521 * @destroy_data: #GDestroyNotify for user_data
523 * Register a callback on the given #GstClockID @id with the given
524 * function and user_data. When passing a #GstClockID with an invalid
525 * time to this function, the callback will be called immediately
526 * with a time set to GST_CLOCK_TIME_NONE. The callback will
527 * be called when the time of @id has been reached.
529 * The callback @func can be invoked from any thread, either provided by the
530 * core or from a streaming thread. The application should be prepared for this.
532 * Returns: the result of the non blocking wait.
539 gst_clock_id_wait_async_full (GstClockID id,
540 GstClockCallback func, gpointer user_data, GDestroyNotify destroy_data)
542 GstClockEntry *entry;
545 GstClockClass *cclass;
546 GstClockTime requested;
548 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
549 g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
551 entry = (GstClockEntry *) id;
552 requested = GST_CLOCK_ENTRY_TIME (entry);
553 clock = GST_CLOCK_ENTRY_CLOCK (entry);
555 /* can't sync on invalid times */
556 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
559 cclass = GST_CLOCK_GET_CLASS (clock);
561 if (G_UNLIKELY (cclass->wait_async == NULL))
565 entry->user_data = user_data;
566 entry->destroy_data = destroy_data;
568 res = cclass->wait_async (clock, entry);
575 (func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
576 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
577 "invalid time requested, returning _BADTIME");
578 return GST_CLOCK_BADTIME;
582 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
583 return GST_CLOCK_UNSUPPORTED;
588 * gst_clock_id_wait_async:
589 * @id: a #GstClockID to wait on
590 * @func: The callback function
591 * @user_data: User data passed in the callback
593 * Register a callback on the given #GstClockID @id with the given
594 * function and user_data. When passing a #GstClockID with an invalid
595 * time to this function, the callback will be called immediately
596 * with a time set to GST_CLOCK_TIME_NONE. The callback will
597 * be called when the time of @id has been reached.
599 * The callback @func can be invoked from any thread, either provided by the
600 * core or from a streaming thread. The application should be prepared for this.
602 * Returns: the result of the non blocking wait.
607 gst_clock_id_wait_async (GstClockID id,
608 GstClockCallback func, gpointer user_data)
610 return gst_clock_id_wait_async_full (id, func, user_data, NULL);
614 * gst_clock_id_unschedule:
615 * @id: The id to unschedule
617 * Cancel an outstanding request with @id. This can either
618 * be an outstanding async notification or a pending sync notification.
619 * After this call, @id cannot be used anymore to receive sync or
620 * async notifications, you need to create a new #GstClockID.
625 gst_clock_id_unschedule (GstClockID id)
627 GstClockEntry *entry;
629 GstClockClass *cclass;
631 g_return_if_fail (id != NULL);
633 entry = (GstClockEntry *) id;
634 clock = entry->clock;
636 cclass = GST_CLOCK_GET_CLASS (clock);
638 if (G_LIKELY (cclass->unschedule))
639 cclass->unschedule (clock, entry);
644 * GstClock abstract base class implementation
646 #define gst_clock_parent_class parent_class
647 G_DEFINE_TYPE (GstClock, gst_clock, GST_TYPE_OBJECT);
650 gst_clock_class_init (GstClockClass * klass)
652 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
654 #ifndef GST_DISABLE_TRACE
655 _gst_clock_entry_trace = _gst_alloc_trace_register ("GstClockEntry", -1);
658 gobject_class->dispose = gst_clock_dispose;
659 gobject_class->finalize = gst_clock_finalize;
660 gobject_class->set_property = gst_clock_set_property;
661 gobject_class->get_property = gst_clock_get_property;
663 g_object_class_install_property (gobject_class, PROP_WINDOW_SIZE,
664 g_param_spec_int ("window-size", "Window size",
665 "The size of the window used to calculate rate and offset", 2, 1024,
666 DEFAULT_WINDOW_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
667 g_object_class_install_property (gobject_class, PROP_WINDOW_THRESHOLD,
668 g_param_spec_int ("window-threshold", "Window threshold",
669 "The threshold to start calculating rate and offset", 2, 1024,
670 DEFAULT_WINDOW_THRESHOLD,
671 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
672 g_object_class_install_property (gobject_class, PROP_TIMEOUT,
673 g_param_spec_uint64 ("timeout", "Timeout",
674 "The amount of time, in nanoseconds, to sample master and slave clocks",
675 0, G_MAXUINT64, DEFAULT_TIMEOUT,
676 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
678 g_type_class_add_private (klass, sizeof (GstClockPrivate));
682 gst_clock_init (GstClock * clock)
684 clock->last_time = 0;
685 clock->entries = NULL;
686 g_cond_init (&clock->entries_changed);
689 G_TYPE_INSTANCE_GET_PRIVATE (clock, GST_TYPE_CLOCK, GstClockPrivate);
691 clock->internal_calibration = 0;
692 clock->external_calibration = 0;
693 clock->rate_numerator = 1;
694 clock->rate_denominator = 1;
696 g_mutex_init (&clock->slave_lock);
697 clock->window_size = DEFAULT_WINDOW_SIZE;
698 clock->window_threshold = DEFAULT_WINDOW_THRESHOLD;
699 clock->filling = TRUE;
700 clock->time_index = 0;
701 clock->timeout = DEFAULT_TIMEOUT;
702 clock->times = g_new0 (GstClockTime, 4 * clock->window_size);
706 gst_clock_dispose (GObject * object)
708 GstClock *clock = GST_CLOCK (object);
711 GST_OBJECT_LOCK (clock);
712 master_p = &clock->master;
713 gst_object_replace ((GstObject **) master_p, NULL);
714 GST_OBJECT_UNLOCK (clock);
716 G_OBJECT_CLASS (parent_class)->dispose (object);
720 gst_clock_finalize (GObject * object)
722 GstClock *clock = GST_CLOCK (object);
724 GST_CLOCK_SLAVE_LOCK (clock);
725 if (clock->clockid) {
726 gst_clock_id_unschedule (clock->clockid);
727 gst_clock_id_unref (clock->clockid);
728 clock->clockid = NULL;
730 g_free (clock->times);
732 GST_CLOCK_SLAVE_UNLOCK (clock);
734 g_cond_clear (&clock->entries_changed);
735 g_mutex_clear (&clock->slave_lock);
737 G_OBJECT_CLASS (parent_class)->finalize (object);
741 * gst_clock_set_resolution
742 * @clock: a #GstClock
743 * @resolution: The resolution to set
745 * Set the accuracy of the clock. Some clocks have the possibility to operate
746 * with different accuracy at the expense of more resource usage. There is
747 * normally no need to change the default resolution of a clock. The resolution
748 * of a clock can only be changed if the clock has the
749 * #GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set.
751 * Returns: the new resolution of the clock.
754 gst_clock_set_resolution (GstClock * clock, GstClockTime resolution)
756 GstClockClass *cclass;
758 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
759 g_return_val_if_fail (resolution != 0, 0);
761 cclass = GST_CLOCK_GET_CLASS (clock);
763 if (cclass->change_resolution)
765 cclass->change_resolution (clock, clock->resolution, resolution);
767 return clock->resolution;
771 * gst_clock_get_resolution
772 * @clock: a #GstClock
774 * Get the accuracy of the clock. The accuracy of the clock is the granularity
775 * of the values returned by gst_clock_get_time().
777 * Returns: the resolution of the clock in units of #GstClockTime.
782 gst_clock_get_resolution (GstClock * clock)
784 GstClockClass *cclass;
786 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
788 cclass = GST_CLOCK_GET_CLASS (clock);
790 if (cclass->get_resolution)
791 return cclass->get_resolution (clock);
797 * gst_clock_adjust_unlocked
798 * @clock: a #GstClock to use
799 * @internal: a clock time
801 * Converts the given @internal clock time to the external time, adjusting for the
802 * rate and reference time set with gst_clock_set_calibration() and making sure
803 * that the returned time is increasing. This function should be called with the
804 * clock's OBJECT_LOCK held and is mainly used by clock subclasses.
806 * This function is the reverse of gst_clock_unadjust_unlocked().
808 * Returns: the converted time of the clock.
811 gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
813 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
815 /* get calibration values for readability */
816 cinternal = clock->internal_calibration;
817 cexternal = clock->external_calibration;
818 cnum = clock->rate_numerator;
819 cdenom = clock->rate_denominator;
821 /* avoid divide by 0 */
822 if (G_UNLIKELY (cdenom == 0))
825 /* The formula is (internal - cinternal) * cnum / cdenom + cexternal
827 * Since we do math on unsigned 64-bit ints we have to special case for
828 * internal < cinternal to get the sign right. this case is not very common,
831 if (G_LIKELY (internal >= cinternal)) {
832 ret = internal - cinternal;
833 ret = gst_util_uint64_scale (ret, cnum, cdenom);
836 ret = cinternal - internal;
837 ret = gst_util_uint64_scale (ret, cnum, cdenom);
839 if (G_LIKELY (cexternal > ret))
840 ret = cexternal - ret;
845 /* make sure the time is increasing */
846 clock->last_time = MAX (ret, clock->last_time);
848 return clock->last_time;
852 * gst_clock_unadjust_unlocked
853 * @clock: a #GstClock to use
854 * @external: an external clock time
856 * Converts the given @external clock time to the internal time of @clock,
857 * using the rate and reference time set with gst_clock_set_calibration().
858 * This function should be called with the clock's OBJECT_LOCK held and
859 * is mainly used by clock subclasses.
861 * This function is the reverse of gst_clock_adjust_unlocked().
863 * Returns: the internal time of the clock corresponding to @external.
868 gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external)
870 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
872 /* get calibration values for readability */
873 cinternal = clock->internal_calibration;
874 cexternal = clock->external_calibration;
875 cnum = clock->rate_numerator;
876 cdenom = clock->rate_denominator;
878 /* avoid divide by 0 */
879 if (G_UNLIKELY (cnum == 0))
882 /* The formula is (external - cexternal) * cdenom / cnum + cinternal */
883 if (G_LIKELY (external >= cexternal)) {
884 ret = external - cexternal;
885 ret = gst_util_uint64_scale (ret, cdenom, cnum);
888 ret = cexternal - external;
889 ret = gst_util_uint64_scale (ret, cdenom, cnum);
890 if (G_LIKELY (cinternal > ret))
891 ret = cinternal - ret;
899 * gst_clock_get_internal_time
900 * @clock: a #GstClock to query
902 * Gets the current internal time of the given clock. The time is returned
903 * unadjusted for the offset and the rate.
905 * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
906 * given invalid input.
911 gst_clock_get_internal_time (GstClock * clock)
914 GstClockClass *cclass;
916 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
918 cclass = GST_CLOCK_GET_CLASS (clock);
920 if (G_UNLIKELY (cclass->get_internal_time == NULL))
923 ret = cclass->get_internal_time (clock);
925 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
926 GST_TIME_ARGS (ret));
933 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
934 "internal time not supported, return 0");
935 return G_GINT64_CONSTANT (0);
941 * @clock: a #GstClock to query
943 * Gets the current time of the given clock. The time is always
944 * monotonically increasing and adjusted according to the current
947 * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when
948 * given invalid input.
953 gst_clock_get_time (GstClock * clock)
958 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
961 /* reget the internal time when we retry to get the most current
963 ret = gst_clock_get_internal_time (clock);
965 seq = read_seqbegin (clock);
966 /* this will scale for rate and offset */
967 ret = gst_clock_adjust_unlocked (clock, ret);
968 } while (read_seqretry (clock, seq));
970 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "adjusted time %" GST_TIME_FORMAT,
971 GST_TIME_ARGS (ret));
977 * gst_clock_set_calibration
978 * @clock: a #GstClock to calibrate
979 * @internal: a reference internal time
980 * @external: a reference external time
981 * @rate_num: the numerator of the rate of the clock relative to its
983 * @rate_denom: the denominator of the rate of the clock
985 * Adjusts the rate and time of @clock. A rate of 1/1 is the normal speed of
986 * the clock. Values bigger than 1/1 make the clock go faster.
988 * @internal and @external are calibration parameters that arrange that
989 * gst_clock_get_time() should have been @external at internal time @internal.
990 * This internal time should not be in the future; that is, it should be less
991 * than the value of gst_clock_get_internal_time() when this function is called.
993 * Subsequent calls to gst_clock_get_time() will return clock times computed as
997 * time = (internal_time - internal) * rate_num / rate_denom + external
1000 * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
1001 * tries to do the integer arithmetic as precisely as possible.
1003 * Note that gst_clock_get_time() always returns increasing values so when you
1004 * move the clock backwards, gst_clock_get_time() will report the previous value
1005 * until the clock catches up.
1010 gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
1011 external, GstClockTime rate_num, GstClockTime rate_denom)
1013 g_return_if_fail (GST_IS_CLOCK (clock));
1014 g_return_if_fail (rate_num != GST_CLOCK_TIME_NONE);
1015 g_return_if_fail (rate_denom > 0 && rate_denom != GST_CLOCK_TIME_NONE);
1017 write_seqlock (clock);
1018 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1019 "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT " %"
1020 G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f", GST_TIME_ARGS (internal),
1021 GST_TIME_ARGS (external), rate_num, rate_denom,
1022 gst_guint64_to_gdouble (rate_num) / gst_guint64_to_gdouble (rate_denom));
1024 clock->internal_calibration = internal;
1025 clock->external_calibration = external;
1026 clock->rate_numerator = rate_num;
1027 clock->rate_denominator = rate_denom;
1028 write_sequnlock (clock);
1032 * gst_clock_get_calibration
1033 * @clock: a #GstClock
1034 * @internal: (out) (allow-none): a location to store the internal time
1035 * @external: (out) (allow-none): a location to store the external time
1036 * @rate_num: (out) (allow-none): a location to store the rate numerator
1037 * @rate_denom: (out) (allow-none): a location to store the rate denominator
1039 * Gets the internal rate and reference time of @clock. See
1040 * gst_clock_set_calibration() for more information.
1042 * @internal, @external, @rate_num, and @rate_denom can be left %NULL if the
1043 * caller is not interested in the values.
1048 gst_clock_get_calibration (GstClock * clock, GstClockTime * internal,
1049 GstClockTime * external, GstClockTime * rate_num, GstClockTime * rate_denom)
1053 g_return_if_fail (GST_IS_CLOCK (clock));
1056 seq = read_seqbegin (clock);
1058 *rate_num = clock->rate_numerator;
1060 *rate_denom = clock->rate_denominator;
1062 *external = clock->external_calibration;
1064 *internal = clock->internal_calibration;
1065 } while (read_seqretry (clock, seq));
1068 /* will be called repeatedly to sample the master and slave clock
1069 * to recalibrate the clock */
1071 gst_clock_slave_callback (GstClock * master, GstClockTime time,
1072 GstClockID id, GstClock * clock)
1074 GstClockTime stime, mtime;
1077 stime = gst_clock_get_internal_time (clock);
1078 mtime = gst_clock_get_time (master);
1080 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1081 "master %" GST_TIME_FORMAT ", slave %" GST_TIME_FORMAT,
1082 GST_TIME_ARGS (mtime), GST_TIME_ARGS (stime));
1084 gst_clock_add_observation (clock, stime, mtime, &r_squared);
1086 /* FIXME, we can use the r_squared value to adjust the timeout
1087 * value of the clockid */
1093 * gst_clock_set_master
1094 * @clock: a #GstClock
1095 * @master: (allow-none): a master #GstClock
1097 * Set @master as the master clock for @clock. @clock will be automatically
1098 * calibrated so that gst_clock_get_time() reports the same time as the
1101 * A clock provider that slaves its clock to a master can get the current
1102 * calibration values with gst_clock_get_calibration().
1104 * @master can be %NULL in which case @clock will not be slaved anymore. It will
1105 * however keep reporting its time adjusted with the last configured rate
1108 * Returns: %TRUE if the clock is capable of being slaved to a master clock.
1109 * Trying to set a master on a clock without the
1110 * #GST_CLOCK_FLAG_CAN_SET_MASTER flag will make this function return %FALSE.
1115 gst_clock_set_master (GstClock * clock, GstClock * master)
1117 GstClock **master_p;
1119 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1120 g_return_val_if_fail (master != clock, FALSE);
1122 GST_OBJECT_LOCK (clock);
1123 /* we always allow setting the master to NULL */
1124 if (master && !GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER))
1126 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1127 "slaving %p to master clock %p", clock, master);
1128 GST_OBJECT_UNLOCK (clock);
1130 GST_CLOCK_SLAVE_LOCK (clock);
1131 if (clock->clockid) {
1132 gst_clock_id_unschedule (clock->clockid);
1133 gst_clock_id_unref (clock->clockid);
1134 clock->clockid = NULL;
1137 clock->filling = TRUE;
1138 clock->time_index = 0;
1139 /* use the master periodic id to schedule sampling and
1140 * clock calibration. */
1141 clock->clockid = gst_clock_new_periodic_id (master,
1142 gst_clock_get_time (master), clock->timeout);
1143 gst_clock_id_wait_async_full (clock->clockid,
1144 (GstClockCallback) gst_clock_slave_callback,
1145 gst_object_ref (clock), (GDestroyNotify) gst_object_unref);
1147 GST_CLOCK_SLAVE_UNLOCK (clock);
1149 GST_OBJECT_LOCK (clock);
1150 master_p = &clock->master;
1151 gst_object_replace ((GstObject **) master_p, (GstObject *) master);
1152 GST_OBJECT_UNLOCK (clock);
1159 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1160 "cannot be slaved to a master clock");
1161 GST_OBJECT_UNLOCK (clock);
1167 * gst_clock_get_master:
1168 * @clock: a #GstClock
1170 * Get the master clock that @clock is slaved to or %NULL when the clock is
1171 * not slaved to any master clock.
1173 * Returns: (transfer full): a master #GstClock or %NULL when this clock is
1174 * not slaved to a master clock. Unref after usage.
1179 gst_clock_get_master (GstClock * clock)
1181 GstClock *result = NULL;
1183 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
1185 GST_OBJECT_LOCK (clock);
1187 result = gst_object_ref (clock->master);
1188 GST_OBJECT_UNLOCK (clock);
1193 /* http://mathworld.wolfram.com/LeastSquaresFitting.html
1197 do_linear_regression (GstClock * clock, GstClockTime * m_num,
1198 GstClockTime * m_denom, GstClockTime * b, GstClockTime * xbase,
1199 gdouble * r_squared)
1201 GstClockTime *newx, *newy;
1202 GstClockTime xmin, ymin, xbar, ybar, xbar4, ybar4;
1203 GstClockTimeDiff sxx, sxy, syy;
1204 GstClockTime *x, *y;
1208 xbar = ybar = sxx = syy = sxy = 0;
1211 y = clock->times + 2;
1212 n = clock->filling ? clock->time_index : clock->window_size;
1214 #ifdef DEBUGGING_ENABLED
1215 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "doing regression on:");
1216 for (i = j = 0; i < n; i++, j += 4)
1217 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1218 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, x[j], y[j]);
1221 xmin = ymin = G_MAXUINT64;
1222 for (i = j = 0; i < n; i++, j += 4) {
1223 xmin = MIN (xmin, x[j]);
1224 ymin = MIN (ymin, y[j]);
1227 #ifdef DEBUGGING_ENABLED
1228 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min x: %" G_GUINT64_FORMAT,
1230 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min y: %" G_GUINT64_FORMAT,
1234 newx = clock->times + 1;
1235 newy = clock->times + 3;
1237 /* strip off unnecessary bits of precision */
1238 for (i = j = 0; i < n; i++, j += 4) {
1239 newx[j] = x[j] - xmin;
1240 newy[j] = y[j] - ymin;
1243 #ifdef DEBUGGING_ENABLED
1244 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "reduced numbers:");
1245 for (i = j = 0; i < n; i++, j += 4)
1246 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1247 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, newx[j], newy[j]);
1250 /* have to do this precisely otherwise the results are pretty much useless.
1251 * should guarantee that none of these accumulators can overflow */
1253 /* quantities on the order of 1e10 -> 30 bits; window size a max of 2^10, so
1254 this addition could end up around 2^40 or so -- ample headroom */
1255 for (i = j = 0; i < n; i++, j += 4) {
1262 #ifdef DEBUGGING_ENABLED
1263 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbar = %" G_GUINT64_FORMAT,
1265 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " ybar = %" G_GUINT64_FORMAT,
1269 /* multiplying directly would give quantities on the order of 1e20 -> 60 bits;
1270 times the window size that's 70 which is too much. Instead we (1) subtract
1271 off the xbar*ybar in the loop instead of after, to avoid accumulation; (2)
1272 shift off 4 bits from each multiplicand, giving an expected ceiling of 52
1273 bits, which should be enough. Need to check the incoming range and domain
1274 to ensure this is an appropriate loss of precision though. */
1277 for (i = j = 0; i < n; i++, j += 4) {
1278 GstClockTime newx4, newy4;
1280 newx4 = newx[j] >> 4;
1281 newy4 = newy[j] >> 4;
1283 sxx += newx4 * newx4 - xbar4 * xbar4;
1284 syy += newy4 * newy4 - ybar4 * ybar4;
1285 sxy += newx4 * newy4 - xbar4 * ybar4;
1288 if (G_UNLIKELY (sxx == 0))
1294 *b = (ybar + ymin) - gst_util_uint64_scale (xbar, *m_num, *m_denom);
1295 *r_squared = ((double) sxy * (double) sxy) / ((double) sxx * (double) syy);
1297 #ifdef DEBUGGING_ENABLED
1298 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " m = %g",
1299 ((double) *m_num) / *m_denom);
1300 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " b = %" G_GUINT64_FORMAT,
1302 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbase = %" G_GUINT64_FORMAT,
1304 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " r2 = %g", *r_squared);
1311 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "sxx == 0, regression failed");
1317 * gst_clock_add_observation
1318 * @clock: a #GstClock
1319 * @slave: a time on the slave
1320 * @master: a time on the master
1321 * @r_squared: (out): a pointer to hold the result
1323 * The time @master of the master clock and the time @slave of the slave
1324 * clock are added to the list of observations. If enough observations
1325 * are available, a linear regression algorithm is run on the
1326 * observations and @clock is recalibrated.
1328 * If this functions returns %TRUE, @r_squared will contain the
1329 * correlation coefficient of the interpolation. A value of 1.0
1330 * means a perfect regression was performed. This value can
1331 * be used to control the sampling frequency of the master and slave
1334 * Returns: %TRUE if enough observations were added to run the
1335 * regression algorithm.
1340 gst_clock_add_observation (GstClock * clock, GstClockTime slave,
1341 GstClockTime master, gdouble * r_squared)
1343 GstClockTime m_num, m_denom, b, xbase;
1345 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1346 g_return_val_if_fail (r_squared != NULL, FALSE);
1348 GST_CLOCK_SLAVE_LOCK (clock);
1350 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1351 "adding observation slave %" GST_TIME_FORMAT ", master %" GST_TIME_FORMAT,
1352 GST_TIME_ARGS (slave), GST_TIME_ARGS (master));
1354 clock->times[(4 * clock->time_index)] = slave;
1355 clock->times[(4 * clock->time_index) + 2] = master;
1357 clock->time_index++;
1358 if (G_UNLIKELY (clock->time_index == clock->window_size)) {
1359 clock->filling = FALSE;
1360 clock->time_index = 0;
1363 if (G_UNLIKELY (clock->filling
1364 && clock->time_index < clock->window_threshold))
1367 if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared))
1370 GST_CLOCK_SLAVE_UNLOCK (clock);
1372 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1373 "adjusting clock to m=%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT ", b=%"
1374 G_GUINT64_FORMAT " (rsquared=%g)", m_num, m_denom, b, *r_squared);
1376 /* if we have a valid regression, adjust the clock */
1377 gst_clock_set_calibration (clock, xbase, b, m_num, m_denom);
1383 GST_CLOCK_SLAVE_UNLOCK (clock);
1388 /* no valid regression has been done, ignore the result then */
1389 GST_CLOCK_SLAVE_UNLOCK (clock);
1395 gst_clock_set_property (GObject * object, guint prop_id,
1396 const GValue * value, GParamSpec * pspec)
1400 clock = GST_CLOCK (object);
1403 case PROP_WINDOW_SIZE:
1404 GST_CLOCK_SLAVE_LOCK (clock);
1405 clock->window_size = g_value_get_int (value);
1406 clock->window_threshold =
1407 MIN (clock->window_threshold, clock->window_size);
1409 g_renew (GstClockTime, clock->times, 4 * clock->window_size);
1410 /* restart calibration */
1411 clock->filling = TRUE;
1412 clock->time_index = 0;
1413 GST_CLOCK_SLAVE_UNLOCK (clock);
1415 case PROP_WINDOW_THRESHOLD:
1416 GST_CLOCK_SLAVE_LOCK (clock);
1417 clock->window_threshold =
1418 MIN (g_value_get_int (value), clock->window_size);
1419 GST_CLOCK_SLAVE_UNLOCK (clock);
1422 GST_CLOCK_SLAVE_LOCK (clock);
1423 clock->timeout = g_value_get_uint64 (value);
1424 GST_CLOCK_SLAVE_UNLOCK (clock);
1427 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1433 gst_clock_get_property (GObject * object, guint prop_id,
1434 GValue * value, GParamSpec * pspec)
1438 clock = GST_CLOCK (object);
1441 case PROP_WINDOW_SIZE:
1442 GST_CLOCK_SLAVE_LOCK (clock);
1443 g_value_set_int (value, clock->window_size);
1444 GST_CLOCK_SLAVE_UNLOCK (clock);
1446 case PROP_WINDOW_THRESHOLD:
1447 GST_CLOCK_SLAVE_LOCK (clock);
1448 g_value_set_int (value, clock->window_threshold);
1449 GST_CLOCK_SLAVE_UNLOCK (clock);
1452 GST_CLOCK_SLAVE_LOCK (clock);
1453 g_value_set_uint64 (value, clock->timeout);
1454 GST_CLOCK_SLAVE_UNLOCK (clock);
1457 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);