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., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, 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 2012-03-28 (0.11.3)
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 #define GST_CLOCK_SLAVE_LOCK(clock) g_mutex_lock (&GST_CLOCK_CAST (clock)->priv->slave_lock)
135 #define GST_CLOCK_SLAVE_UNLOCK(clock) g_mutex_unlock (&GST_CLOCK_CAST (clock)->priv->slave_lock)
137 struct _GstClockPrivate
139 GMutex slave_lock; /* order: SLAVE_LOCK, OBJECT_LOCK */
142 GstClockTime internal_calibration;
143 GstClockTime external_calibration;
144 GstClockTime rate_numerator;
145 GstClockTime rate_denominator;
146 GstClockTime last_time;
149 GstClockTime resolution;
151 /* for master/slave clocks */
154 /* with SLAVE_LOCK */
157 gint window_threshold;
159 GstClockTime timeout;
168 #define read_seqbegin(clock) \
169 g_atomic_int_get (&clock->priv->post_count);
171 static inline gboolean
172 read_seqretry (GstClock * clock, gint seq)
174 /* no retry if the seqnum did not change */
175 if (G_LIKELY (seq == g_atomic_int_get (&clock->priv->pre_count)))
178 /* wait for the writer to finish and retry */
179 GST_OBJECT_LOCK (clock);
180 GST_OBJECT_UNLOCK (clock);
184 #define write_seqlock(clock) \
186 GST_OBJECT_LOCK (clock); \
187 g_atomic_int_inc (&clock->priv->pre_count); \
190 #define write_sequnlock(clock) \
192 g_atomic_int_inc (&clock->priv->post_count); \
193 GST_OBJECT_UNLOCK (clock); \
196 static void gst_clock_dispose (GObject * object);
197 static void gst_clock_finalize (GObject * object);
199 static void gst_clock_set_property (GObject * object, guint prop_id,
200 const GValue * value, GParamSpec * pspec);
201 static void gst_clock_get_property (GObject * object, guint prop_id,
202 GValue * value, GParamSpec * pspec);
204 /* static guint gst_clock_signals[LAST_SIGNAL] = { 0 }; */
207 gst_clock_entry_new (GstClock * clock, GstClockTime time,
208 GstClockTime interval, GstClockEntryType type)
210 GstClockEntry *entry;
212 entry = g_slice_new (GstClockEntry);
213 #ifndef GST_DISABLE_TRACE
214 _gst_alloc_trace_new (_gst_clock_entry_trace, entry);
216 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
217 "created entry %p, time %" GST_TIME_FORMAT, entry, GST_TIME_ARGS (time));
220 entry->clock = clock;
223 entry->interval = interval;
224 entry->status = GST_CLOCK_OK;
226 entry->user_data = NULL;
227 entry->destroy_data = NULL;
228 entry->unscheduled = FALSE;
229 entry->woken_up = FALSE;
231 return (GstClockID) entry;
234 /* WARNING : Does not modify the refcount
235 * WARNING : Do not use if a pending clock operation is happening on that entry */
237 gst_clock_entry_reinit (GstClock * clock, GstClockEntry * entry,
238 GstClockTime time, GstClockTime interval, GstClockEntryType type)
240 g_return_val_if_fail (entry->status != GST_CLOCK_BUSY, FALSE);
241 g_return_val_if_fail (entry->clock == clock, FALSE);
245 entry->interval = interval;
246 entry->status = GST_CLOCK_OK;
247 entry->unscheduled = FALSE;
248 entry->woken_up = FALSE;
254 * gst_clock_single_shot_id_reinit:
255 * @clock: a #GstClock
257 * @time: The requested time.
259 * Reinitializes the provided single shot @id to the provided time. Does not
260 * modify the reference count.
262 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
263 * @time, else %FALSE.
266 gst_clock_single_shot_id_reinit (GstClock * clock, GstClockID id,
269 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, time,
270 GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
274 * gst_clock_periodic_id_reinit:
275 * @clock: a #GstClock
277 * @start_time: the requested start time
278 * @interval: the requested interval
280 * Reinitializes the provided periodic @id to the provided start time and
281 * interval. Does not modify the reference count.
283 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
284 * @time, else %FALSE.
287 gst_clock_periodic_id_reinit (GstClock * clock, GstClockID id,
288 GstClockTime start_time, GstClockTime interval)
290 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, start_time,
291 interval, GST_CLOCK_ENTRY_PERIODIC);
296 * @id: The #GstClockID to ref
298 * Increase the refcount of given @id.
300 * Returns: (transfer full): The same #GstClockID with increased refcount.
305 gst_clock_id_ref (GstClockID id)
307 g_return_val_if_fail (id != NULL, NULL);
309 g_atomic_int_inc (&((GstClockEntry *) id)->refcount);
315 _gst_clock_id_free (GstClockID id)
317 GstClockEntry *entry;
318 g_return_if_fail (id != NULL);
320 GST_CAT_DEBUG (GST_CAT_CLOCK, "freed entry %p", id);
321 entry = (GstClockEntry *) id;
322 if (entry->destroy_data)
323 entry->destroy_data (entry->user_data);
325 #ifndef GST_DISABLE_TRACE
326 _gst_alloc_trace_free (_gst_clock_entry_trace, id);
328 g_slice_free (GstClockEntry, id);
332 * gst_clock_id_unref:
333 * @id: (transfer full): The #GstClockID to unref
335 * Unref given @id. When the refcount reaches 0 the
336 * #GstClockID will be freed.
341 gst_clock_id_unref (GstClockID id)
345 g_return_if_fail (id != NULL);
347 zero = g_atomic_int_dec_and_test (&((GstClockEntry *) id)->refcount);
348 /* if we ended up with the refcount at zero, free the id */
350 _gst_clock_id_free (id);
355 * gst_clock_new_single_shot_id:
356 * @clock: The #GstClockID to get a single shot notification from
357 * @time: the requested time
359 * Get a #GstClockID from @clock to trigger a single shot
360 * notification at the requested time. The single shot id should be
361 * unreffed after usage.
363 * Free-function: gst_clock_id_unref
365 * Returns: (transfer full): a #GstClockID that can be used to request the
371 gst_clock_new_single_shot_id (GstClock * clock, GstClockTime time)
373 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
375 return gst_clock_entry_new (clock,
376 time, GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
380 * gst_clock_new_periodic_id:
381 * @clock: The #GstClockID to get a periodic notification id from
382 * @start_time: the requested start time
383 * @interval: the requested interval
385 * Get an ID from @clock to trigger a periodic notification.
386 * The periodic notifications will start at time @start_time and
387 * will then be fired with the given @interval. @id should be unreffed
390 * Free-function: gst_clock_id_unref
392 * Returns: (transfer full): a #GstClockID that can be used to request the
398 gst_clock_new_periodic_id (GstClock * clock, GstClockTime start_time,
399 GstClockTime interval)
401 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
402 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (start_time), NULL);
403 g_return_val_if_fail (interval != 0, NULL);
404 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), NULL);
406 return gst_clock_entry_new (clock,
407 start_time, interval, GST_CLOCK_ENTRY_PERIODIC);
411 * gst_clock_id_compare_func:
412 * @id1: A #GstClockID
413 * @id2: A #GstClockID to compare with
415 * Compares the two #GstClockID instances. This function can be used
416 * as a GCompareFunc when sorting ids.
418 * Returns: negative value if a < b; zero if a = b; positive value if a > b
423 gst_clock_id_compare_func (gconstpointer id1, gconstpointer id2)
425 GstClockEntry *entry1, *entry2;
427 entry1 = (GstClockEntry *) id1;
428 entry2 = (GstClockEntry *) id2;
430 if (GST_CLOCK_ENTRY_TIME (entry1) > GST_CLOCK_ENTRY_TIME (entry2)) {
433 if (GST_CLOCK_ENTRY_TIME (entry1) < GST_CLOCK_ENTRY_TIME (entry2)) {
440 * gst_clock_id_get_time:
441 * @id: The #GstClockID to query
443 * Get the time of the clock ID
445 * Returns: the time of the given clock id.
450 gst_clock_id_get_time (GstClockID id)
452 g_return_val_if_fail (id != NULL, GST_CLOCK_TIME_NONE);
454 return GST_CLOCK_ENTRY_TIME ((GstClockEntry *) id);
459 * @id: The #GstClockID to wait on
460 * @jitter: (out) (allow-none): a pointer that will contain the jitter,
463 * Perform a blocking wait on @id.
464 * @id should have been created with gst_clock_new_single_shot_id()
465 * or gst_clock_new_periodic_id() and should not have been unscheduled
466 * with a call to gst_clock_id_unschedule().
468 * If the @jitter argument is not %NULL and this function returns #GST_CLOCK_OK
469 * or #GST_CLOCK_EARLY, it will contain the difference
470 * against the clock and the time of @id when this method was
472 * Positive values indicate how late @id was relative to the clock
473 * (in which case this function will return #GST_CLOCK_EARLY).
474 * Negative values indicate how much time was spent waiting on the clock
475 * before this function returned.
477 * Returns: the result of the blocking wait. #GST_CLOCK_EARLY will be returned
478 * if the current clock time is past the time of @id, #GST_CLOCK_OK if
479 * @id was scheduled in time. #GST_CLOCK_UNSCHEDULED if @id was
480 * unscheduled with gst_clock_id_unschedule().
485 gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
487 GstClockEntry *entry;
490 GstClockTime requested;
491 GstClockClass *cclass;
493 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
495 entry = (GstClockEntry *) id;
496 requested = GST_CLOCK_ENTRY_TIME (entry);
498 clock = GST_CLOCK_ENTRY_CLOCK (entry);
500 /* can't sync on invalid times */
501 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
504 cclass = GST_CLOCK_GET_CLASS (clock);
506 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);
508 /* if we have a wait_jitter function, use that */
509 if (G_UNLIKELY (cclass->wait == NULL))
512 res = cclass->wait (clock, entry, jitter);
514 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
515 "done waiting entry %p, res: %d", id, res);
517 if (entry->type == GST_CLOCK_ENTRY_PERIODIC)
518 entry->time = requested + entry->interval;
525 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
526 "invalid time requested, returning _BADTIME");
527 return GST_CLOCK_BADTIME;
531 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
532 return GST_CLOCK_UNSUPPORTED;
537 * gst_clock_id_wait_async:
538 * @id: a #GstClockID to wait on
539 * @func: The callback function
540 * @user_data: User data passed in the callback
541 * @destroy_data: #GDestroyNotify for user_data
543 * Register a callback on the given #GstClockID @id with the given
544 * function and user_data. When passing a #GstClockID with an invalid
545 * time to this function, the callback will be called immediately
546 * with a time set to GST_CLOCK_TIME_NONE. The callback will
547 * be called when the time of @id has been reached.
549 * The callback @func can be invoked from any thread, either provided by the
550 * core or from a streaming thread. The application should be prepared for this.
552 * Returns: the result of the non blocking wait.
557 gst_clock_id_wait_async (GstClockID id,
558 GstClockCallback func, gpointer user_data, GDestroyNotify destroy_data)
560 GstClockEntry *entry;
563 GstClockClass *cclass;
564 GstClockTime requested;
566 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
567 g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
569 entry = (GstClockEntry *) id;
570 requested = GST_CLOCK_ENTRY_TIME (entry);
571 clock = GST_CLOCK_ENTRY_CLOCK (entry);
573 /* can't sync on invalid times */
574 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
577 cclass = GST_CLOCK_GET_CLASS (clock);
579 if (G_UNLIKELY (cclass->wait_async == NULL))
583 entry->user_data = user_data;
584 entry->destroy_data = destroy_data;
586 res = cclass->wait_async (clock, entry);
593 (func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
594 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
595 "invalid time requested, returning _BADTIME");
596 return GST_CLOCK_BADTIME;
600 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
601 return GST_CLOCK_UNSUPPORTED;
606 * gst_clock_id_unschedule:
607 * @id: The id to unschedule
609 * Cancel an outstanding request with @id. This can either
610 * be an outstanding async notification or a pending sync notification.
611 * After this call, @id cannot be used anymore to receive sync or
612 * async notifications, you need to create a new #GstClockID.
617 gst_clock_id_unschedule (GstClockID id)
619 GstClockEntry *entry;
621 GstClockClass *cclass;
623 g_return_if_fail (id != NULL);
625 entry = (GstClockEntry *) id;
626 clock = entry->clock;
628 cclass = GST_CLOCK_GET_CLASS (clock);
630 if (G_LIKELY (cclass->unschedule))
631 cclass->unschedule (clock, entry);
636 * GstClock abstract base class implementation
638 #define gst_clock_parent_class parent_class
639 G_DEFINE_ABSTRACT_TYPE (GstClock, gst_clock, GST_TYPE_OBJECT);
642 gst_clock_class_init (GstClockClass * klass)
644 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
646 #ifndef GST_DISABLE_TRACE
647 _gst_clock_entry_trace = _gst_alloc_trace_register ("GstClockEntry", -1);
650 gobject_class->dispose = gst_clock_dispose;
651 gobject_class->finalize = gst_clock_finalize;
652 gobject_class->set_property = gst_clock_set_property;
653 gobject_class->get_property = gst_clock_get_property;
655 g_object_class_install_property (gobject_class, PROP_WINDOW_SIZE,
656 g_param_spec_int ("window-size", "Window size",
657 "The size of the window used to calculate rate and offset", 2, 1024,
658 DEFAULT_WINDOW_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
659 g_object_class_install_property (gobject_class, PROP_WINDOW_THRESHOLD,
660 g_param_spec_int ("window-threshold", "Window threshold",
661 "The threshold to start calculating rate and offset", 2, 1024,
662 DEFAULT_WINDOW_THRESHOLD,
663 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
664 g_object_class_install_property (gobject_class, PROP_TIMEOUT,
665 g_param_spec_uint64 ("timeout", "Timeout",
666 "The amount of time, in nanoseconds, to sample master and slave clocks",
667 0, G_MAXUINT64, DEFAULT_TIMEOUT,
668 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
670 g_type_class_add_private (klass, sizeof (GstClockPrivate));
674 gst_clock_init (GstClock * clock)
676 GstClockPrivate *priv;
679 G_TYPE_INSTANCE_GET_PRIVATE (clock, GST_TYPE_CLOCK, GstClockPrivate);
683 priv->internal_calibration = 0;
684 priv->external_calibration = 0;
685 priv->rate_numerator = 1;
686 priv->rate_denominator = 1;
688 g_mutex_init (&priv->slave_lock);
689 priv->window_size = DEFAULT_WINDOW_SIZE;
690 priv->window_threshold = DEFAULT_WINDOW_THRESHOLD;
691 priv->filling = TRUE;
692 priv->time_index = 0;
693 priv->timeout = DEFAULT_TIMEOUT;
694 priv->times = g_new0 (GstClockTime, 4 * priv->window_size);
696 /* clear floating flag */
697 gst_object_ref_sink (clock);
701 gst_clock_dispose (GObject * object)
703 GstClock *clock = GST_CLOCK (object);
706 GST_OBJECT_LOCK (clock);
707 master_p = &clock->priv->master;
708 gst_object_replace ((GstObject **) master_p, NULL);
709 GST_OBJECT_UNLOCK (clock);
711 G_OBJECT_CLASS (parent_class)->dispose (object);
715 gst_clock_finalize (GObject * object)
717 GstClock *clock = GST_CLOCK (object);
719 GST_CLOCK_SLAVE_LOCK (clock);
720 if (clock->priv->clockid) {
721 gst_clock_id_unschedule (clock->priv->clockid);
722 gst_clock_id_unref (clock->priv->clockid);
723 clock->priv->clockid = NULL;
725 g_free (clock->priv->times);
726 clock->priv->times = NULL;
727 GST_CLOCK_SLAVE_UNLOCK (clock);
729 g_mutex_clear (&clock->priv->slave_lock);
731 G_OBJECT_CLASS (parent_class)->finalize (object);
735 * gst_clock_set_resolution:
736 * @clock: a #GstClock
737 * @resolution: The resolution to set
739 * Set the accuracy of the clock. Some clocks have the possibility to operate
740 * with different accuracy at the expense of more resource usage. There is
741 * normally no need to change the default resolution of a clock. The resolution
742 * of a clock can only be changed if the clock has the
743 * #GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set.
745 * Returns: the new resolution of the clock.
748 gst_clock_set_resolution (GstClock * clock, GstClockTime resolution)
750 GstClockPrivate *priv;
751 GstClockClass *cclass;
753 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
754 g_return_val_if_fail (resolution != 0, 0);
756 cclass = GST_CLOCK_GET_CLASS (clock);
759 if (cclass->change_resolution)
761 cclass->change_resolution (clock, priv->resolution, resolution);
763 return priv->resolution;
767 * gst_clock_get_resolution:
768 * @clock: a #GstClock
770 * Get the accuracy of the clock. The accuracy of the clock is the granularity
771 * of the values returned by gst_clock_get_time().
773 * Returns: the resolution of the clock in units of #GstClockTime.
778 gst_clock_get_resolution (GstClock * clock)
780 GstClockClass *cclass;
782 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
784 cclass = GST_CLOCK_GET_CLASS (clock);
786 if (cclass->get_resolution)
787 return cclass->get_resolution (clock);
793 * gst_clock_adjust_unlocked:
794 * @clock: a #GstClock to use
795 * @internal: a clock time
797 * Converts the given @internal clock time to the external time, adjusting for the
798 * rate and reference time set with gst_clock_set_calibration() and making sure
799 * that the returned time is increasing. This function should be called with the
800 * clock's OBJECT_LOCK held and is mainly used by clock subclasses.
802 * This function is the reverse of gst_clock_unadjust_unlocked().
804 * Returns: the converted time of the clock.
807 gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
809 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
810 GstClockPrivate *priv = clock->priv;
812 /* get calibration values for readability */
813 cinternal = priv->internal_calibration;
814 cexternal = priv->external_calibration;
815 cnum = priv->rate_numerator;
816 cdenom = priv->rate_denominator;
818 /* avoid divide by 0 */
819 if (G_UNLIKELY (cdenom == 0))
822 /* The formula is (internal - cinternal) * cnum / cdenom + cexternal
824 * Since we do math on unsigned 64-bit ints we have to special case for
825 * internal < cinternal to get the sign right. this case is not very common,
828 if (G_LIKELY (internal >= cinternal)) {
829 ret = internal - cinternal;
830 ret = gst_util_uint64_scale (ret, cnum, cdenom);
833 ret = cinternal - internal;
834 ret = gst_util_uint64_scale (ret, cnum, cdenom);
836 if (G_LIKELY (cexternal > ret))
837 ret = cexternal - ret;
842 /* make sure the time is increasing */
843 priv->last_time = MAX (ret, priv->last_time);
845 return priv->last_time;
849 * gst_clock_unadjust_unlocked:
850 * @clock: a #GstClock to use
851 * @external: an external clock time
853 * Converts the given @external clock time to the internal time of @clock,
854 * using the rate and reference time set with gst_clock_set_calibration().
855 * This function should be called with the clock's OBJECT_LOCK held and
856 * is mainly used by clock subclasses.
858 * This function is the reverse of gst_clock_adjust_unlocked().
860 * Returns: the internal time of the clock corresponding to @external.
863 gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external)
865 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
866 GstClockPrivate *priv = clock->priv;
868 /* get calibration values for readability */
869 cinternal = priv->internal_calibration;
870 cexternal = priv->external_calibration;
871 cnum = priv->rate_numerator;
872 cdenom = priv->rate_denominator;
874 /* avoid divide by 0 */
875 if (G_UNLIKELY (cnum == 0))
878 /* The formula is (external - cexternal) * cdenom / cnum + cinternal */
879 if (G_LIKELY (external >= cexternal)) {
880 ret = external - cexternal;
881 ret = gst_util_uint64_scale (ret, cdenom, cnum);
884 ret = cexternal - external;
885 ret = gst_util_uint64_scale (ret, cdenom, cnum);
886 if (G_LIKELY (cinternal > ret))
887 ret = cinternal - ret;
895 * gst_clock_get_internal_time:
896 * @clock: a #GstClock to query
898 * Gets the current internal time of the given clock. The time is returned
899 * unadjusted for the offset and the rate.
901 * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
902 * given invalid input.
907 gst_clock_get_internal_time (GstClock * clock)
910 GstClockClass *cclass;
912 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
914 cclass = GST_CLOCK_GET_CLASS (clock);
916 if (G_UNLIKELY (cclass->get_internal_time == NULL))
919 ret = cclass->get_internal_time (clock);
921 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
922 GST_TIME_ARGS (ret));
929 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
930 "internal time not supported, return 0");
931 return G_GINT64_CONSTANT (0);
936 * gst_clock_get_time:
937 * @clock: a #GstClock to query
939 * Gets the current time of the given clock. The time is always
940 * monotonically increasing and adjusted according to the current
943 * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when
944 * given invalid input.
949 gst_clock_get_time (GstClock * clock)
954 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
957 /* reget the internal time when we retry to get the most current
959 ret = gst_clock_get_internal_time (clock);
961 seq = read_seqbegin (clock);
962 /* this will scale for rate and offset */
963 ret = gst_clock_adjust_unlocked (clock, ret);
964 } while (read_seqretry (clock, seq));
966 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "adjusted time %" GST_TIME_FORMAT,
967 GST_TIME_ARGS (ret));
973 * gst_clock_set_calibration:
974 * @clock: a #GstClock to calibrate
975 * @internal: a reference internal time
976 * @external: a reference external time
977 * @rate_num: the numerator of the rate of the clock relative to its
979 * @rate_denom: the denominator of the rate of the clock
981 * Adjusts the rate and time of @clock. A rate of 1/1 is the normal speed of
982 * the clock. Values bigger than 1/1 make the clock go faster.
984 * @internal and @external are calibration parameters that arrange that
985 * gst_clock_get_time() should have been @external at internal time @internal.
986 * This internal time should not be in the future; that is, it should be less
987 * than the value of gst_clock_get_internal_time() when this function is called.
989 * Subsequent calls to gst_clock_get_time() will return clock times computed as
993 * time = (internal_time - internal) * rate_num / rate_denom + external
996 * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
997 * tries to do the integer arithmetic as precisely as possible.
999 * Note that gst_clock_get_time() always returns increasing values so when you
1000 * move the clock backwards, gst_clock_get_time() will report the previous value
1001 * until the clock catches up.
1006 gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
1007 external, GstClockTime rate_num, GstClockTime rate_denom)
1009 GstClockPrivate *priv;
1011 g_return_if_fail (GST_IS_CLOCK (clock));
1012 g_return_if_fail (rate_num != GST_CLOCK_TIME_NONE);
1013 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 priv->internal_calibration = internal;
1025 priv->external_calibration = external;
1026 priv->rate_numerator = rate_num;
1027 priv->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)
1052 GstClockPrivate *priv;
1054 g_return_if_fail (GST_IS_CLOCK (clock));
1059 seq = read_seqbegin (clock);
1061 *rate_num = priv->rate_numerator;
1063 *rate_denom = priv->rate_denominator;
1065 *external = priv->external_calibration;
1067 *internal = priv->internal_calibration;
1068 } while (read_seqretry (clock, seq));
1071 /* will be called repeatedly to sample the master and slave clock
1072 * to recalibrate the clock */
1074 gst_clock_slave_callback (GstClock * master, GstClockTime time,
1075 GstClockID id, GstClock * clock)
1077 GstClockTime stime, mtime;
1080 stime = gst_clock_get_internal_time (clock);
1081 mtime = gst_clock_get_time (master);
1083 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1084 "master %" GST_TIME_FORMAT ", slave %" GST_TIME_FORMAT,
1085 GST_TIME_ARGS (mtime), GST_TIME_ARGS (stime));
1087 gst_clock_add_observation (clock, stime, mtime, &r_squared);
1089 /* FIXME, we can use the r_squared value to adjust the timeout
1090 * value of the clockid */
1096 * gst_clock_set_master:
1097 * @clock: a #GstClock
1098 * @master: (allow-none): a master #GstClock
1100 * Set @master as the master clock for @clock. @clock will be automatically
1101 * calibrated so that gst_clock_get_time() reports the same time as the
1104 * A clock provider that slaves its clock to a master can get the current
1105 * calibration values with gst_clock_get_calibration().
1107 * @master can be %NULL in which case @clock will not be slaved anymore. It will
1108 * however keep reporting its time adjusted with the last configured rate
1111 * Returns: %TRUE if the clock is capable of being slaved to a master clock.
1112 * Trying to set a master on a clock without the
1113 * #GST_CLOCK_FLAG_CAN_SET_MASTER flag will make this function return %FALSE.
1118 gst_clock_set_master (GstClock * clock, GstClock * master)
1120 GstClock **master_p;
1121 GstClockPrivate *priv;
1123 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1124 g_return_val_if_fail (master != clock, FALSE);
1126 GST_OBJECT_LOCK (clock);
1127 /* we always allow setting the master to NULL */
1128 if (master && !GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER))
1130 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1131 "slaving %p to master clock %p", clock, master);
1132 GST_OBJECT_UNLOCK (clock);
1136 GST_CLOCK_SLAVE_LOCK (clock);
1137 if (priv->clockid) {
1138 gst_clock_id_unschedule (priv->clockid);
1139 gst_clock_id_unref (priv->clockid);
1140 priv->clockid = NULL;
1143 priv->filling = TRUE;
1144 priv->time_index = 0;
1145 /* use the master periodic id to schedule sampling and
1146 * clock calibration. */
1147 priv->clockid = gst_clock_new_periodic_id (master,
1148 gst_clock_get_time (master), priv->timeout);
1149 gst_clock_id_wait_async (priv->clockid,
1150 (GstClockCallback) gst_clock_slave_callback,
1151 gst_object_ref (clock), (GDestroyNotify) gst_object_unref);
1153 GST_CLOCK_SLAVE_UNLOCK (clock);
1155 GST_OBJECT_LOCK (clock);
1156 master_p = &priv->master;
1157 gst_object_replace ((GstObject **) master_p, (GstObject *) master);
1158 GST_OBJECT_UNLOCK (clock);
1165 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1166 "cannot be slaved to a master clock");
1167 GST_OBJECT_UNLOCK (clock);
1173 * gst_clock_get_master:
1174 * @clock: a #GstClock
1176 * Get the master clock that @clock is slaved to or %NULL when the clock is
1177 * not slaved to any master clock.
1179 * Returns: (transfer full): a master #GstClock or %NULL when this clock is
1180 * not slaved to a master clock. Unref after usage.
1185 gst_clock_get_master (GstClock * clock)
1187 GstClock *result = NULL;
1188 GstClockPrivate *priv;
1190 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
1194 GST_OBJECT_LOCK (clock);
1196 result = gst_object_ref (priv->master);
1197 GST_OBJECT_UNLOCK (clock);
1202 /* http://mathworld.wolfram.com/LeastSquaresFitting.html
1206 do_linear_regression (GstClock * clock, GstClockTime * m_num,
1207 GstClockTime * m_denom, GstClockTime * b, GstClockTime * xbase,
1208 gdouble * r_squared)
1210 GstClockTime *newx, *newy;
1211 GstClockTime xmin, ymin, xbar, ybar, xbar4, ybar4;
1212 GstClockTimeDiff sxx, sxy, syy;
1213 GstClockTime *x, *y;
1216 GstClockPrivate *priv;
1218 xbar = ybar = sxx = syy = sxy = 0;
1223 y = priv->times + 2;
1224 n = priv->filling ? priv->time_index : priv->window_size;
1226 #ifdef DEBUGGING_ENABLED
1227 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "doing regression on:");
1228 for (i = j = 0; i < n; i++, j += 4)
1229 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1230 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, x[j], y[j]);
1233 xmin = ymin = G_MAXUINT64;
1234 for (i = j = 0; i < n; i++, j += 4) {
1235 xmin = MIN (xmin, x[j]);
1236 ymin = MIN (ymin, y[j]);
1239 #ifdef DEBUGGING_ENABLED
1240 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min x: %" G_GUINT64_FORMAT,
1242 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min y: %" G_GUINT64_FORMAT,
1246 newx = priv->times + 1;
1247 newy = priv->times + 3;
1249 /* strip off unnecessary bits of precision */
1250 for (i = j = 0; i < n; i++, j += 4) {
1251 newx[j] = x[j] - xmin;
1252 newy[j] = y[j] - ymin;
1255 #ifdef DEBUGGING_ENABLED
1256 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "reduced numbers:");
1257 for (i = j = 0; i < n; i++, j += 4)
1258 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1259 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, newx[j], newy[j]);
1262 /* have to do this precisely otherwise the results are pretty much useless.
1263 * should guarantee that none of these accumulators can overflow */
1265 /* quantities on the order of 1e10 -> 30 bits; window size a max of 2^10, so
1266 this addition could end up around 2^40 or so -- ample headroom */
1267 for (i = j = 0; i < n; i++, j += 4) {
1274 #ifdef DEBUGGING_ENABLED
1275 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbar = %" G_GUINT64_FORMAT,
1277 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " ybar = %" G_GUINT64_FORMAT,
1281 /* multiplying directly would give quantities on the order of 1e20 -> 60 bits;
1282 times the window size that's 70 which is too much. Instead we (1) subtract
1283 off the xbar*ybar in the loop instead of after, to avoid accumulation; (2)
1284 shift off 4 bits from each multiplicand, giving an expected ceiling of 52
1285 bits, which should be enough. Need to check the incoming range and domain
1286 to ensure this is an appropriate loss of precision though. */
1289 for (i = j = 0; i < n; i++, j += 4) {
1290 GstClockTime newx4, newy4;
1292 newx4 = newx[j] >> 4;
1293 newy4 = newy[j] >> 4;
1295 sxx += newx4 * newx4 - xbar4 * xbar4;
1296 syy += newy4 * newy4 - ybar4 * ybar4;
1297 sxy += newx4 * newy4 - xbar4 * ybar4;
1300 if (G_UNLIKELY (sxx == 0))
1306 *b = (ybar + ymin) - gst_util_uint64_scale (xbar, *m_num, *m_denom);
1307 *r_squared = ((double) sxy * (double) sxy) / ((double) sxx * (double) syy);
1309 #ifdef DEBUGGING_ENABLED
1310 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " m = %g",
1311 ((double) *m_num) / *m_denom);
1312 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " b = %" G_GUINT64_FORMAT,
1314 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbase = %" G_GUINT64_FORMAT,
1316 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " r2 = %g", *r_squared);
1323 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "sxx == 0, regression failed");
1329 * gst_clock_add_observation:
1330 * @clock: a #GstClock
1331 * @slave: a time on the slave
1332 * @master: a time on the master
1333 * @r_squared: (out): a pointer to hold the result
1335 * The time @master of the master clock and the time @slave of the slave
1336 * clock are added to the list of observations. If enough observations
1337 * are available, a linear regression algorithm is run on the
1338 * observations and @clock is recalibrated.
1340 * If this functions returns %TRUE, @r_squared will contain the
1341 * correlation coefficient of the interpolation. A value of 1.0
1342 * means a perfect regression was performed. This value can
1343 * be used to control the sampling frequency of the master and slave
1346 * Returns: %TRUE if enough observations were added to run the
1347 * regression algorithm.
1352 gst_clock_add_observation (GstClock * clock, GstClockTime slave,
1353 GstClockTime master, gdouble * r_squared)
1355 GstClockTime m_num, m_denom, b, xbase;
1356 GstClockPrivate *priv;
1358 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1359 g_return_val_if_fail (r_squared != NULL, FALSE);
1363 GST_CLOCK_SLAVE_LOCK (clock);
1365 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1366 "adding observation slave %" GST_TIME_FORMAT ", master %" GST_TIME_FORMAT,
1367 GST_TIME_ARGS (slave), GST_TIME_ARGS (master));
1369 priv->times[(4 * priv->time_index)] = slave;
1370 priv->times[(4 * priv->time_index) + 2] = master;
1373 if (G_UNLIKELY (priv->time_index == priv->window_size)) {
1374 priv->filling = FALSE;
1375 priv->time_index = 0;
1378 if (G_UNLIKELY (priv->filling && priv->time_index < priv->window_threshold))
1381 if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared))
1384 GST_CLOCK_SLAVE_UNLOCK (clock);
1386 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1387 "adjusting clock to m=%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT ", b=%"
1388 G_GUINT64_FORMAT " (rsquared=%g)", m_num, m_denom, b, *r_squared);
1390 /* if we have a valid regression, adjust the clock */
1391 gst_clock_set_calibration (clock, xbase, b, m_num, m_denom);
1397 GST_CLOCK_SLAVE_UNLOCK (clock);
1402 /* no valid regression has been done, ignore the result then */
1403 GST_CLOCK_SLAVE_UNLOCK (clock);
1409 * gst_clock_set_timeout:
1410 * @clock: a #GstClock
1411 * @timeout: a timeout
1413 * Set the amount of time, in nanoseconds, to sample master and slave
1417 gst_clock_set_timeout (GstClock * clock, GstClockTime timeout)
1419 g_return_if_fail (GST_IS_CLOCK (clock));
1421 GST_CLOCK_SLAVE_LOCK (clock);
1422 clock->priv->timeout = timeout;
1423 GST_CLOCK_SLAVE_UNLOCK (clock);
1427 * gst_clock_get_timeout:
1428 * @clock: a #GstClock
1430 * Get the amount of time that master and slave clocks are sampled.
1432 * Returns: the interval between samples.
1435 gst_clock_get_timeout (GstClock * clock)
1437 GstClockTime result;
1439 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
1441 GST_CLOCK_SLAVE_LOCK (clock);
1442 result = clock->priv->timeout;
1443 GST_CLOCK_SLAVE_UNLOCK (clock);
1449 gst_clock_set_property (GObject * object, guint prop_id,
1450 const GValue * value, GParamSpec * pspec)
1453 GstClockPrivate *priv;
1455 clock = GST_CLOCK (object);
1459 case PROP_WINDOW_SIZE:
1460 GST_CLOCK_SLAVE_LOCK (clock);
1461 priv->window_size = g_value_get_int (value);
1462 priv->window_threshold = MIN (priv->window_threshold, priv->window_size);
1463 priv->times = g_renew (GstClockTime, priv->times, 4 * priv->window_size);
1464 /* restart calibration */
1465 priv->filling = TRUE;
1466 priv->time_index = 0;
1467 GST_CLOCK_SLAVE_UNLOCK (clock);
1469 case PROP_WINDOW_THRESHOLD:
1470 GST_CLOCK_SLAVE_LOCK (clock);
1471 priv->window_threshold = MIN (g_value_get_int (value), priv->window_size);
1472 GST_CLOCK_SLAVE_UNLOCK (clock);
1475 gst_clock_set_timeout (clock, g_value_get_uint64 (value));
1478 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1484 gst_clock_get_property (GObject * object, guint prop_id,
1485 GValue * value, GParamSpec * pspec)
1488 GstClockPrivate *priv;
1490 clock = GST_CLOCK (object);
1494 case PROP_WINDOW_SIZE:
1495 GST_CLOCK_SLAVE_LOCK (clock);
1496 g_value_set_int (value, priv->window_size);
1497 GST_CLOCK_SLAVE_UNLOCK (clock);
1499 case PROP_WINDOW_THRESHOLD:
1500 GST_CLOCK_SLAVE_LOCK (clock);
1501 g_value_set_int (value, priv->window_threshold);
1502 GST_CLOCK_SLAVE_UNLOCK (clock);
1505 g_value_set_uint64 (value, gst_clock_get_timeout (clock));
1508 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);