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.
104 #include "gst_private.h"
107 #include "gstclock.h"
109 #include "gstutils.h"
110 #include "glib-compat-private.h"
112 #ifndef GST_DISABLE_TRACE
113 /* #define GST_WITH_ALLOC_TRACE */
114 #include "gsttrace.h"
115 static GstAllocTrace *_gst_clock_entry_trace;
118 /* #define DEBUGGING_ENABLED */
120 #define DEFAULT_WINDOW_SIZE 32
121 #define DEFAULT_WINDOW_THRESHOLD 4
122 #define DEFAULT_TIMEOUT GST_SECOND / 10
128 PROP_WINDOW_THRESHOLD,
132 #define GST_CLOCK_SLAVE_LOCK(clock) g_mutex_lock (&GST_CLOCK_CAST (clock)->priv->slave_lock)
133 #define GST_CLOCK_SLAVE_UNLOCK(clock) g_mutex_unlock (&GST_CLOCK_CAST (clock)->priv->slave_lock)
135 struct _GstClockPrivate
137 GMutex slave_lock; /* order: SLAVE_LOCK, OBJECT_LOCK */
140 GstClockTime internal_calibration;
141 GstClockTime external_calibration;
142 GstClockTime rate_numerator;
143 GstClockTime rate_denominator;
144 GstClockTime last_time;
147 GstClockTime resolution;
149 /* for master/slave clocks */
152 /* with SLAVE_LOCK */
155 gint window_threshold;
157 GstClockTime timeout;
166 #define read_seqbegin(clock) \
167 g_atomic_int_get (&clock->priv->post_count);
169 static inline gboolean
170 read_seqretry (GstClock * clock, gint seq)
172 /* no retry if the seqnum did not change */
173 if (G_LIKELY (seq == g_atomic_int_get (&clock->priv->pre_count)))
176 /* wait for the writer to finish and retry */
177 GST_OBJECT_LOCK (clock);
178 GST_OBJECT_UNLOCK (clock);
182 #define write_seqlock(clock) \
184 GST_OBJECT_LOCK (clock); \
185 g_atomic_int_inc (&clock->priv->pre_count); \
188 #define write_sequnlock(clock) \
190 g_atomic_int_inc (&clock->priv->post_count); \
191 GST_OBJECT_UNLOCK (clock); \
194 #ifndef GST_DISABLE_GST_DEBUG
196 gst_clock_return_get_name (GstClockReturn ret)
201 case GST_CLOCK_EARLY:
203 case GST_CLOCK_UNSCHEDULED:
204 return "unscheduled";
207 case GST_CLOCK_BADTIME:
209 case GST_CLOCK_ERROR:
211 case GST_CLOCK_UNSUPPORTED:
212 return "unsupported";
221 #endif /* GST_DISABLE_GST_DEBUG */
223 static void gst_clock_dispose (GObject * object);
224 static void gst_clock_finalize (GObject * object);
226 static void gst_clock_set_property (GObject * object, guint prop_id,
227 const GValue * value, GParamSpec * pspec);
228 static void gst_clock_get_property (GObject * object, guint prop_id,
229 GValue * value, GParamSpec * pspec);
231 /* static guint gst_clock_signals[LAST_SIGNAL] = { 0 }; */
234 gst_clock_entry_new (GstClock * clock, GstClockTime time,
235 GstClockTime interval, GstClockEntryType type)
237 GstClockEntry *entry;
239 entry = g_slice_new (GstClockEntry);
240 #ifndef GST_DISABLE_TRACE
241 _gst_alloc_trace_new (_gst_clock_entry_trace, entry);
243 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
244 "created entry %p, time %" GST_TIME_FORMAT, entry, GST_TIME_ARGS (time));
247 entry->clock = clock;
250 entry->interval = interval;
251 entry->status = GST_CLOCK_OK;
253 entry->user_data = NULL;
254 entry->destroy_data = NULL;
255 entry->unscheduled = FALSE;
256 entry->woken_up = FALSE;
258 return (GstClockID) entry;
261 /* WARNING : Does not modify the refcount
262 * WARNING : Do not use if a pending clock operation is happening on that entry */
264 gst_clock_entry_reinit (GstClock * clock, GstClockEntry * entry,
265 GstClockTime time, GstClockTime interval, GstClockEntryType type)
267 g_return_val_if_fail (entry->status != GST_CLOCK_BUSY, FALSE);
268 g_return_val_if_fail (entry->clock == clock, FALSE);
272 entry->interval = interval;
273 entry->status = GST_CLOCK_OK;
274 entry->unscheduled = FALSE;
275 entry->woken_up = FALSE;
281 * gst_clock_single_shot_id_reinit:
282 * @clock: a #GstClock
284 * @time: The requested time.
286 * Reinitializes the provided single shot @id to the provided time. Does not
287 * modify the reference count.
289 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
290 * @time, else %FALSE.
293 gst_clock_single_shot_id_reinit (GstClock * clock, GstClockID id,
296 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, time,
297 GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
301 * gst_clock_periodic_id_reinit:
302 * @clock: a #GstClock
304 * @start_time: the requested start time
305 * @interval: the requested interval
307 * Reinitializes the provided periodic @id to the provided start time and
308 * interval. Does not modify the reference count.
310 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
311 * @time, else %FALSE.
314 gst_clock_periodic_id_reinit (GstClock * clock, GstClockID id,
315 GstClockTime start_time, GstClockTime interval)
317 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, start_time,
318 interval, GST_CLOCK_ENTRY_PERIODIC);
323 * @id: The #GstClockID to ref
325 * Increase the refcount of given @id.
327 * Returns: (transfer full): The same #GstClockID with increased refcount.
332 gst_clock_id_ref (GstClockID id)
334 g_return_val_if_fail (id != NULL, NULL);
336 g_atomic_int_inc (&((GstClockEntry *) id)->refcount);
342 _gst_clock_id_free (GstClockID id)
344 GstClockEntry *entry;
345 g_return_if_fail (id != NULL);
347 GST_CAT_DEBUG (GST_CAT_CLOCK, "freed entry %p", id);
348 entry = (GstClockEntry *) id;
349 if (entry->destroy_data)
350 entry->destroy_data (entry->user_data);
352 #ifndef GST_DISABLE_TRACE
353 _gst_alloc_trace_free (_gst_clock_entry_trace, id);
355 g_slice_free (GstClockEntry, id);
359 * gst_clock_id_unref:
360 * @id: (transfer full): The #GstClockID to unref
362 * Unref given @id. When the refcount reaches 0 the
363 * #GstClockID will be freed.
368 gst_clock_id_unref (GstClockID id)
372 g_return_if_fail (id != NULL);
374 zero = g_atomic_int_dec_and_test (&((GstClockEntry *) id)->refcount);
375 /* if we ended up with the refcount at zero, free the id */
377 _gst_clock_id_free (id);
382 * gst_clock_new_single_shot_id:
383 * @clock: The #GstClockID to get a single shot notification from
384 * @time: the requested time
386 * Get a #GstClockID from @clock to trigger a single shot
387 * notification at the requested time. The single shot id should be
388 * unreffed after usage.
390 * Free-function: gst_clock_id_unref
392 * Returns: (transfer full): a #GstClockID that can be used to request the
398 gst_clock_new_single_shot_id (GstClock * clock, GstClockTime time)
400 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
402 return gst_clock_entry_new (clock,
403 time, GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
407 * gst_clock_new_periodic_id:
408 * @clock: The #GstClockID to get a periodic notification id from
409 * @start_time: the requested start time
410 * @interval: the requested interval
412 * Get an ID from @clock to trigger a periodic notification.
413 * The periodic notifications will start at time @start_time and
414 * will then be fired with the given @interval. @id should be unreffed
417 * Free-function: gst_clock_id_unref
419 * Returns: (transfer full): a #GstClockID that can be used to request the
425 gst_clock_new_periodic_id (GstClock * clock, GstClockTime start_time,
426 GstClockTime interval)
428 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
429 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (start_time), NULL);
430 g_return_val_if_fail (interval != 0, NULL);
431 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), NULL);
433 return gst_clock_entry_new (clock,
434 start_time, interval, GST_CLOCK_ENTRY_PERIODIC);
438 * gst_clock_id_compare_func:
439 * @id1: A #GstClockID
440 * @id2: A #GstClockID to compare with
442 * Compares the two #GstClockID instances. This function can be used
443 * as a GCompareFunc when sorting ids.
445 * Returns: negative value if a < b; zero if a = b; positive value if a > b
450 gst_clock_id_compare_func (gconstpointer id1, gconstpointer id2)
452 GstClockEntry *entry1, *entry2;
454 entry1 = (GstClockEntry *) id1;
455 entry2 = (GstClockEntry *) id2;
457 if (GST_CLOCK_ENTRY_TIME (entry1) > GST_CLOCK_ENTRY_TIME (entry2)) {
460 if (GST_CLOCK_ENTRY_TIME (entry1) < GST_CLOCK_ENTRY_TIME (entry2)) {
467 * gst_clock_id_get_time:
468 * @id: The #GstClockID to query
470 * Get the time of the clock ID
472 * Returns: the time of the given clock id.
477 gst_clock_id_get_time (GstClockID id)
479 g_return_val_if_fail (id != NULL, GST_CLOCK_TIME_NONE);
481 return GST_CLOCK_ENTRY_TIME ((GstClockEntry *) id);
486 * @id: The #GstClockID to wait on
487 * @jitter: (out) (allow-none): a pointer that will contain the jitter,
490 * Perform a blocking wait on @id.
491 * @id should have been created with gst_clock_new_single_shot_id()
492 * or gst_clock_new_periodic_id() and should not have been unscheduled
493 * with a call to gst_clock_id_unschedule().
495 * If the @jitter argument is not %NULL and this function returns #GST_CLOCK_OK
496 * or #GST_CLOCK_EARLY, it will contain the difference
497 * against the clock and the time of @id when this method was
499 * Positive values indicate how late @id was relative to the clock
500 * (in which case this function will return #GST_CLOCK_EARLY).
501 * Negative values indicate how much time was spent waiting on the clock
502 * before this function returned.
504 * Returns: the result of the blocking wait. #GST_CLOCK_EARLY will be returned
505 * if the current clock time is past the time of @id, #GST_CLOCK_OK if
506 * @id was scheduled in time. #GST_CLOCK_UNSCHEDULED if @id was
507 * unscheduled with gst_clock_id_unschedule().
512 gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
514 GstClockEntry *entry;
517 GstClockTime requested;
518 GstClockClass *cclass;
520 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
522 entry = (GstClockEntry *) id;
523 requested = GST_CLOCK_ENTRY_TIME (entry);
525 clock = GST_CLOCK_ENTRY_CLOCK (entry);
527 /* can't sync on invalid times */
528 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
531 cclass = GST_CLOCK_GET_CLASS (clock);
533 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);
535 /* if we have a wait_jitter function, use that */
536 if (G_UNLIKELY (cclass->wait == NULL))
539 res = cclass->wait (clock, entry, jitter);
541 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
542 "done waiting entry %p, res: %d (%s)", id, res,
543 gst_clock_return_get_name (res));
545 if (entry->type == GST_CLOCK_ENTRY_PERIODIC)
546 entry->time = requested + entry->interval;
553 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
554 "invalid time requested, returning _BADTIME");
555 return GST_CLOCK_BADTIME;
559 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
560 return GST_CLOCK_UNSUPPORTED;
565 * gst_clock_id_wait_async:
566 * @id: a #GstClockID to wait on
567 * @func: The callback function
568 * @user_data: User data passed in the callback
569 * @destroy_data: #GDestroyNotify for user_data
571 * Register a callback on the given #GstClockID @id with the given
572 * function and user_data. When passing a #GstClockID with an invalid
573 * time to this function, the callback will be called immediately
574 * with a time set to GST_CLOCK_TIME_NONE. The callback will
575 * be called when the time of @id has been reached.
577 * The callback @func can be invoked from any thread, either provided by the
578 * core or from a streaming thread. The application should be prepared for this.
580 * Returns: the result of the non blocking wait.
585 gst_clock_id_wait_async (GstClockID id,
586 GstClockCallback func, gpointer user_data, GDestroyNotify destroy_data)
588 GstClockEntry *entry;
591 GstClockClass *cclass;
592 GstClockTime requested;
594 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
595 g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
597 entry = (GstClockEntry *) id;
598 requested = GST_CLOCK_ENTRY_TIME (entry);
599 clock = GST_CLOCK_ENTRY_CLOCK (entry);
601 /* can't sync on invalid times */
602 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
605 cclass = GST_CLOCK_GET_CLASS (clock);
607 if (G_UNLIKELY (cclass->wait_async == NULL))
611 entry->user_data = user_data;
612 entry->destroy_data = destroy_data;
614 res = cclass->wait_async (clock, entry);
621 (func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
622 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
623 "invalid time requested, returning _BADTIME");
624 return GST_CLOCK_BADTIME;
628 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
629 return GST_CLOCK_UNSUPPORTED;
634 * gst_clock_id_unschedule:
635 * @id: The id to unschedule
637 * Cancel an outstanding request with @id. This can either
638 * be an outstanding async notification or a pending sync notification.
639 * After this call, @id cannot be used anymore to receive sync or
640 * async notifications, you need to create a new #GstClockID.
645 gst_clock_id_unschedule (GstClockID id)
647 GstClockEntry *entry;
649 GstClockClass *cclass;
651 g_return_if_fail (id != NULL);
653 entry = (GstClockEntry *) id;
654 clock = entry->clock;
656 cclass = GST_CLOCK_GET_CLASS (clock);
658 if (G_LIKELY (cclass->unschedule))
659 cclass->unschedule (clock, entry);
664 * GstClock abstract base class implementation
666 #define gst_clock_parent_class parent_class
667 G_DEFINE_ABSTRACT_TYPE (GstClock, gst_clock, GST_TYPE_OBJECT);
670 gst_clock_class_init (GstClockClass * klass)
672 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
674 #ifndef GST_DISABLE_TRACE
675 _gst_clock_entry_trace = _gst_alloc_trace_register ("GstClockEntry", -1);
678 gobject_class->dispose = gst_clock_dispose;
679 gobject_class->finalize = gst_clock_finalize;
680 gobject_class->set_property = gst_clock_set_property;
681 gobject_class->get_property = gst_clock_get_property;
683 g_object_class_install_property (gobject_class, PROP_WINDOW_SIZE,
684 g_param_spec_int ("window-size", "Window size",
685 "The size of the window used to calculate rate and offset", 2, 1024,
686 DEFAULT_WINDOW_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
687 g_object_class_install_property (gobject_class, PROP_WINDOW_THRESHOLD,
688 g_param_spec_int ("window-threshold", "Window threshold",
689 "The threshold to start calculating rate and offset", 2, 1024,
690 DEFAULT_WINDOW_THRESHOLD,
691 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
692 g_object_class_install_property (gobject_class, PROP_TIMEOUT,
693 g_param_spec_uint64 ("timeout", "Timeout",
694 "The amount of time, in nanoseconds, to sample master and slave clocks",
695 0, G_MAXUINT64, DEFAULT_TIMEOUT,
696 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
698 g_type_class_add_private (klass, sizeof (GstClockPrivate));
702 gst_clock_init (GstClock * clock)
704 GstClockPrivate *priv;
707 G_TYPE_INSTANCE_GET_PRIVATE (clock, GST_TYPE_CLOCK, GstClockPrivate);
711 priv->internal_calibration = 0;
712 priv->external_calibration = 0;
713 priv->rate_numerator = 1;
714 priv->rate_denominator = 1;
716 g_mutex_init (&priv->slave_lock);
717 priv->window_size = DEFAULT_WINDOW_SIZE;
718 priv->window_threshold = DEFAULT_WINDOW_THRESHOLD;
719 priv->filling = TRUE;
720 priv->time_index = 0;
721 priv->timeout = DEFAULT_TIMEOUT;
722 priv->times = g_new0 (GstClockTime, 4 * priv->window_size);
724 /* clear floating flag */
725 gst_object_ref_sink (clock);
729 gst_clock_dispose (GObject * object)
731 GstClock *clock = GST_CLOCK (object);
734 GST_OBJECT_LOCK (clock);
735 master_p = &clock->priv->master;
736 gst_object_replace ((GstObject **) master_p, NULL);
737 GST_OBJECT_UNLOCK (clock);
739 G_OBJECT_CLASS (parent_class)->dispose (object);
743 gst_clock_finalize (GObject * object)
745 GstClock *clock = GST_CLOCK (object);
747 GST_CLOCK_SLAVE_LOCK (clock);
748 if (clock->priv->clockid) {
749 gst_clock_id_unschedule (clock->priv->clockid);
750 gst_clock_id_unref (clock->priv->clockid);
751 clock->priv->clockid = NULL;
753 g_free (clock->priv->times);
754 clock->priv->times = NULL;
755 GST_CLOCK_SLAVE_UNLOCK (clock);
757 g_mutex_clear (&clock->priv->slave_lock);
759 G_OBJECT_CLASS (parent_class)->finalize (object);
763 * gst_clock_set_resolution:
764 * @clock: a #GstClock
765 * @resolution: The resolution to set
767 * Set the accuracy of the clock. Some clocks have the possibility to operate
768 * with different accuracy at the expense of more resource usage. There is
769 * normally no need to change the default resolution of a clock. The resolution
770 * of a clock can only be changed if the clock has the
771 * #GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set.
773 * Returns: the new resolution of the clock.
776 gst_clock_set_resolution (GstClock * clock, GstClockTime resolution)
778 GstClockPrivate *priv;
779 GstClockClass *cclass;
781 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
782 g_return_val_if_fail (resolution != 0, 0);
784 cclass = GST_CLOCK_GET_CLASS (clock);
787 if (cclass->change_resolution)
789 cclass->change_resolution (clock, priv->resolution, resolution);
791 return priv->resolution;
795 * gst_clock_get_resolution:
796 * @clock: a #GstClock
798 * Get the accuracy of the clock. The accuracy of the clock is the granularity
799 * of the values returned by gst_clock_get_time().
801 * Returns: the resolution of the clock in units of #GstClockTime.
806 gst_clock_get_resolution (GstClock * clock)
808 GstClockClass *cclass;
810 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
812 cclass = GST_CLOCK_GET_CLASS (clock);
814 if (cclass->get_resolution)
815 return cclass->get_resolution (clock);
821 * gst_clock_adjust_unlocked:
822 * @clock: a #GstClock to use
823 * @internal: a clock time
825 * Converts the given @internal clock time to the external time, adjusting for the
826 * rate and reference time set with gst_clock_set_calibration() and making sure
827 * that the returned time is increasing. This function should be called with the
828 * clock's OBJECT_LOCK held and is mainly used by clock subclasses.
830 * This function is the reverse of gst_clock_unadjust_unlocked().
832 * Returns: the converted time of the clock.
835 gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
837 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
838 GstClockPrivate *priv = clock->priv;
840 /* get calibration values for readability */
841 cinternal = priv->internal_calibration;
842 cexternal = priv->external_calibration;
843 cnum = priv->rate_numerator;
844 cdenom = priv->rate_denominator;
846 /* avoid divide by 0 */
847 if (G_UNLIKELY (cdenom == 0))
850 /* The formula is (internal - cinternal) * cnum / cdenom + cexternal
852 * Since we do math on unsigned 64-bit ints we have to special case for
853 * internal < cinternal to get the sign right. this case is not very common,
856 if (G_LIKELY (internal >= cinternal)) {
857 ret = internal - cinternal;
858 ret = gst_util_uint64_scale (ret, cnum, cdenom);
861 ret = cinternal - internal;
862 ret = gst_util_uint64_scale (ret, cnum, cdenom);
864 if (G_LIKELY (cexternal > ret))
865 ret = cexternal - ret;
870 /* make sure the time is increasing */
871 priv->last_time = MAX (ret, priv->last_time);
873 return priv->last_time;
877 * gst_clock_unadjust_unlocked:
878 * @clock: a #GstClock to use
879 * @external: an external clock time
881 * Converts the given @external clock time to the internal time of @clock,
882 * using the rate and reference time set with gst_clock_set_calibration().
883 * This function should be called with the clock's OBJECT_LOCK held and
884 * is mainly used by clock subclasses.
886 * This function is the reverse of gst_clock_adjust_unlocked().
888 * Returns: the internal time of the clock corresponding to @external.
891 gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external)
893 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
894 GstClockPrivate *priv = clock->priv;
896 /* get calibration values for readability */
897 cinternal = priv->internal_calibration;
898 cexternal = priv->external_calibration;
899 cnum = priv->rate_numerator;
900 cdenom = priv->rate_denominator;
902 /* avoid divide by 0 */
903 if (G_UNLIKELY (cnum == 0))
906 /* The formula is (external - cexternal) * cdenom / cnum + cinternal */
907 if (G_LIKELY (external >= cexternal)) {
908 ret = external - cexternal;
909 ret = gst_util_uint64_scale (ret, cdenom, cnum);
912 ret = cexternal - external;
913 ret = gst_util_uint64_scale (ret, cdenom, cnum);
914 if (G_LIKELY (cinternal > ret))
915 ret = cinternal - ret;
923 * gst_clock_get_internal_time:
924 * @clock: a #GstClock to query
926 * Gets the current internal time of the given clock. The time is returned
927 * unadjusted for the offset and the rate.
929 * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
930 * given invalid input.
935 gst_clock_get_internal_time (GstClock * clock)
938 GstClockClass *cclass;
940 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
942 cclass = GST_CLOCK_GET_CLASS (clock);
944 if (G_UNLIKELY (cclass->get_internal_time == NULL))
947 ret = cclass->get_internal_time (clock);
949 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
950 GST_TIME_ARGS (ret));
957 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
958 "internal time not supported, return 0");
959 return G_GINT64_CONSTANT (0);
964 * gst_clock_get_time:
965 * @clock: a #GstClock to query
967 * Gets the current time of the given clock. The time is always
968 * monotonically increasing and adjusted according to the current
971 * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when
972 * given invalid input.
977 gst_clock_get_time (GstClock * clock)
982 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
985 /* reget the internal time when we retry to get the most current
987 ret = gst_clock_get_internal_time (clock);
989 seq = read_seqbegin (clock);
990 /* this will scale for rate and offset */
991 ret = gst_clock_adjust_unlocked (clock, ret);
992 } while (read_seqretry (clock, seq));
994 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "adjusted time %" GST_TIME_FORMAT,
995 GST_TIME_ARGS (ret));
1001 * gst_clock_set_calibration:
1002 * @clock: a #GstClock to calibrate
1003 * @internal: a reference internal time
1004 * @external: a reference external time
1005 * @rate_num: the numerator of the rate of the clock relative to its
1007 * @rate_denom: the denominator of the rate of the clock
1009 * Adjusts the rate and time of @clock. A rate of 1/1 is the normal speed of
1010 * the clock. Values bigger than 1/1 make the clock go faster.
1012 * @internal and @external are calibration parameters that arrange that
1013 * gst_clock_get_time() should have been @external at internal time @internal.
1014 * This internal time should not be in the future; that is, it should be less
1015 * than the value of gst_clock_get_internal_time() when this function is called.
1017 * Subsequent calls to gst_clock_get_time() will return clock times computed as
1021 * time = (internal_time - internal) * rate_num / rate_denom + external
1024 * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
1025 * tries to do the integer arithmetic as precisely as possible.
1027 * Note that gst_clock_get_time() always returns increasing values so when you
1028 * move the clock backwards, gst_clock_get_time() will report the previous value
1029 * until the clock catches up.
1034 gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
1035 external, GstClockTime rate_num, GstClockTime rate_denom)
1037 GstClockPrivate *priv;
1039 g_return_if_fail (GST_IS_CLOCK (clock));
1040 g_return_if_fail (rate_num != GST_CLOCK_TIME_NONE);
1041 g_return_if_fail (rate_denom > 0 && rate_denom != GST_CLOCK_TIME_NONE);
1045 write_seqlock (clock);
1046 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1047 "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT " %"
1048 G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f", GST_TIME_ARGS (internal),
1049 GST_TIME_ARGS (external), rate_num, rate_denom,
1050 gst_guint64_to_gdouble (rate_num) / gst_guint64_to_gdouble (rate_denom));
1052 priv->internal_calibration = internal;
1053 priv->external_calibration = external;
1054 priv->rate_numerator = rate_num;
1055 priv->rate_denominator = rate_denom;
1056 write_sequnlock (clock);
1060 * gst_clock_get_calibration:
1061 * @clock: a #GstClock
1062 * @internal: (out) (allow-none): a location to store the internal time
1063 * @external: (out) (allow-none): a location to store the external time
1064 * @rate_num: (out) (allow-none): a location to store the rate numerator
1065 * @rate_denom: (out) (allow-none): a location to store the rate denominator
1067 * Gets the internal rate and reference time of @clock. See
1068 * gst_clock_set_calibration() for more information.
1070 * @internal, @external, @rate_num, and @rate_denom can be left %NULL if the
1071 * caller is not interested in the values.
1076 gst_clock_get_calibration (GstClock * clock, GstClockTime * internal,
1077 GstClockTime * external, GstClockTime * rate_num, GstClockTime * rate_denom)
1080 GstClockPrivate *priv;
1082 g_return_if_fail (GST_IS_CLOCK (clock));
1087 seq = read_seqbegin (clock);
1089 *rate_num = priv->rate_numerator;
1091 *rate_denom = priv->rate_denominator;
1093 *external = priv->external_calibration;
1095 *internal = priv->internal_calibration;
1096 } while (read_seqretry (clock, seq));
1099 /* will be called repeatedly to sample the master and slave clock
1100 * to recalibrate the clock */
1102 gst_clock_slave_callback (GstClock * master, GstClockTime time,
1103 GstClockID id, GstClock * clock)
1105 GstClockTime stime, mtime;
1108 stime = gst_clock_get_internal_time (clock);
1109 mtime = gst_clock_get_time (master);
1111 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1112 "master %" GST_TIME_FORMAT ", slave %" GST_TIME_FORMAT,
1113 GST_TIME_ARGS (mtime), GST_TIME_ARGS (stime));
1115 gst_clock_add_observation (clock, stime, mtime, &r_squared);
1117 /* FIXME, we can use the r_squared value to adjust the timeout
1118 * value of the clockid */
1124 * gst_clock_set_master:
1125 * @clock: a #GstClock
1126 * @master: (allow-none): a master #GstClock
1128 * Set @master as the master clock for @clock. @clock will be automatically
1129 * calibrated so that gst_clock_get_time() reports the same time as the
1132 * A clock provider that slaves its clock to a master can get the current
1133 * calibration values with gst_clock_get_calibration().
1135 * @master can be %NULL in which case @clock will not be slaved anymore. It will
1136 * however keep reporting its time adjusted with the last configured rate
1139 * Returns: %TRUE if the clock is capable of being slaved to a master clock.
1140 * Trying to set a master on a clock without the
1141 * #GST_CLOCK_FLAG_CAN_SET_MASTER flag will make this function return %FALSE.
1146 gst_clock_set_master (GstClock * clock, GstClock * master)
1148 GstClock **master_p;
1149 GstClockPrivate *priv;
1151 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1152 g_return_val_if_fail (master != clock, FALSE);
1154 GST_OBJECT_LOCK (clock);
1155 /* we always allow setting the master to NULL */
1156 if (master && !GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER))
1158 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1159 "slaving %p to master clock %p", clock, master);
1160 GST_OBJECT_UNLOCK (clock);
1164 GST_CLOCK_SLAVE_LOCK (clock);
1165 if (priv->clockid) {
1166 gst_clock_id_unschedule (priv->clockid);
1167 gst_clock_id_unref (priv->clockid);
1168 priv->clockid = NULL;
1171 priv->filling = TRUE;
1172 priv->time_index = 0;
1173 /* use the master periodic id to schedule sampling and
1174 * clock calibration. */
1175 priv->clockid = gst_clock_new_periodic_id (master,
1176 gst_clock_get_time (master), priv->timeout);
1177 gst_clock_id_wait_async (priv->clockid,
1178 (GstClockCallback) gst_clock_slave_callback,
1179 gst_object_ref (clock), (GDestroyNotify) gst_object_unref);
1181 GST_CLOCK_SLAVE_UNLOCK (clock);
1183 GST_OBJECT_LOCK (clock);
1184 master_p = &priv->master;
1185 gst_object_replace ((GstObject **) master_p, (GstObject *) master);
1186 GST_OBJECT_UNLOCK (clock);
1193 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1194 "cannot be slaved to a master clock");
1195 GST_OBJECT_UNLOCK (clock);
1201 * gst_clock_get_master:
1202 * @clock: a #GstClock
1204 * Get the master clock that @clock is slaved to or %NULL when the clock is
1205 * not slaved to any master clock.
1207 * Returns: (transfer full): a master #GstClock or %NULL when this clock is
1208 * not slaved to a master clock. Unref after usage.
1213 gst_clock_get_master (GstClock * clock)
1215 GstClock *result = NULL;
1216 GstClockPrivate *priv;
1218 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
1222 GST_OBJECT_LOCK (clock);
1224 result = gst_object_ref (priv->master);
1225 GST_OBJECT_UNLOCK (clock);
1230 /* http://mathworld.wolfram.com/LeastSquaresFitting.html
1234 do_linear_regression (GstClock * clock, GstClockTime * m_num,
1235 GstClockTime * m_denom, GstClockTime * b, GstClockTime * xbase,
1236 gdouble * r_squared)
1238 GstClockTime *newx, *newy;
1239 GstClockTime xmin, ymin, xbar, ybar, xbar4, ybar4;
1240 GstClockTimeDiff sxx, sxy, syy;
1241 GstClockTime *x, *y;
1244 GstClockPrivate *priv;
1246 xbar = ybar = sxx = syy = sxy = 0;
1251 y = priv->times + 2;
1252 n = priv->filling ? priv->time_index : priv->window_size;
1254 #ifdef DEBUGGING_ENABLED
1255 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "doing regression on:");
1256 for (i = j = 0; i < n; i++, j += 4)
1257 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1258 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, x[j], y[j]);
1261 xmin = ymin = G_MAXUINT64;
1262 for (i = j = 0; i < n; i++, j += 4) {
1263 xmin = MIN (xmin, x[j]);
1264 ymin = MIN (ymin, y[j]);
1267 #ifdef DEBUGGING_ENABLED
1268 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min x: %" G_GUINT64_FORMAT,
1270 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min y: %" G_GUINT64_FORMAT,
1274 newx = priv->times + 1;
1275 newy = priv->times + 3;
1277 /* strip off unnecessary bits of precision */
1278 for (i = j = 0; i < n; i++, j += 4) {
1279 newx[j] = x[j] - xmin;
1280 newy[j] = y[j] - ymin;
1283 #ifdef DEBUGGING_ENABLED
1284 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "reduced numbers:");
1285 for (i = j = 0; i < n; i++, j += 4)
1286 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1287 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, newx[j], newy[j]);
1290 /* have to do this precisely otherwise the results are pretty much useless.
1291 * should guarantee that none of these accumulators can overflow */
1293 /* quantities on the order of 1e10 -> 30 bits; window size a max of 2^10, so
1294 this addition could end up around 2^40 or so -- ample headroom */
1295 for (i = j = 0; i < n; i++, j += 4) {
1302 #ifdef DEBUGGING_ENABLED
1303 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbar = %" G_GUINT64_FORMAT,
1305 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " ybar = %" G_GUINT64_FORMAT,
1309 /* multiplying directly would give quantities on the order of 1e20 -> 60 bits;
1310 times the window size that's 70 which is too much. Instead we (1) subtract
1311 off the xbar*ybar in the loop instead of after, to avoid accumulation; (2)
1312 shift off 4 bits from each multiplicand, giving an expected ceiling of 52
1313 bits, which should be enough. Need to check the incoming range and domain
1314 to ensure this is an appropriate loss of precision though. */
1317 for (i = j = 0; i < n; i++, j += 4) {
1318 GstClockTime newx4, newy4;
1320 newx4 = newx[j] >> 4;
1321 newy4 = newy[j] >> 4;
1323 sxx += newx4 * newx4 - xbar4 * xbar4;
1324 syy += newy4 * newy4 - ybar4 * ybar4;
1325 sxy += newx4 * newy4 - xbar4 * ybar4;
1328 if (G_UNLIKELY (sxx == 0))
1334 *b = (ybar + ymin) - gst_util_uint64_scale (xbar, *m_num, *m_denom);
1335 *r_squared = ((double) sxy * (double) sxy) / ((double) sxx * (double) syy);
1337 #ifdef DEBUGGING_ENABLED
1338 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " m = %g",
1339 ((double) *m_num) / *m_denom);
1340 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " b = %" G_GUINT64_FORMAT,
1342 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbase = %" G_GUINT64_FORMAT,
1344 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " r2 = %g", *r_squared);
1351 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "sxx == 0, regression failed");
1357 * gst_clock_add_observation:
1358 * @clock: a #GstClock
1359 * @slave: a time on the slave
1360 * @master: a time on the master
1361 * @r_squared: (out): a pointer to hold the result
1363 * The time @master of the master clock and the time @slave of the slave
1364 * clock are added to the list of observations. If enough observations
1365 * are available, a linear regression algorithm is run on the
1366 * observations and @clock is recalibrated.
1368 * If this functions returns %TRUE, @r_squared will contain the
1369 * correlation coefficient of the interpolation. A value of 1.0
1370 * means a perfect regression was performed. This value can
1371 * be used to control the sampling frequency of the master and slave
1374 * Returns: %TRUE if enough observations were added to run the
1375 * regression algorithm.
1380 gst_clock_add_observation (GstClock * clock, GstClockTime slave,
1381 GstClockTime master, gdouble * r_squared)
1383 GstClockTime m_num, m_denom, b, xbase;
1384 GstClockPrivate *priv;
1386 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1387 g_return_val_if_fail (r_squared != NULL, FALSE);
1391 GST_CLOCK_SLAVE_LOCK (clock);
1393 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1394 "adding observation slave %" GST_TIME_FORMAT ", master %" GST_TIME_FORMAT,
1395 GST_TIME_ARGS (slave), GST_TIME_ARGS (master));
1397 priv->times[(4 * priv->time_index)] = slave;
1398 priv->times[(4 * priv->time_index) + 2] = master;
1401 if (G_UNLIKELY (priv->time_index == priv->window_size)) {
1402 priv->filling = FALSE;
1403 priv->time_index = 0;
1406 if (G_UNLIKELY (priv->filling && priv->time_index < priv->window_threshold))
1409 if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared))
1412 GST_CLOCK_SLAVE_UNLOCK (clock);
1414 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1415 "adjusting clock to m=%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT ", b=%"
1416 G_GUINT64_FORMAT " (rsquared=%g)", m_num, m_denom, b, *r_squared);
1418 /* if we have a valid regression, adjust the clock */
1419 gst_clock_set_calibration (clock, xbase, b, m_num, m_denom);
1425 GST_CLOCK_SLAVE_UNLOCK (clock);
1430 /* no valid regression has been done, ignore the result then */
1431 GST_CLOCK_SLAVE_UNLOCK (clock);
1437 * gst_clock_set_timeout:
1438 * @clock: a #GstClock
1439 * @timeout: a timeout
1441 * Set the amount of time, in nanoseconds, to sample master and slave
1445 gst_clock_set_timeout (GstClock * clock, GstClockTime timeout)
1447 g_return_if_fail (GST_IS_CLOCK (clock));
1449 GST_CLOCK_SLAVE_LOCK (clock);
1450 clock->priv->timeout = timeout;
1451 GST_CLOCK_SLAVE_UNLOCK (clock);
1455 * gst_clock_get_timeout:
1456 * @clock: a #GstClock
1458 * Get the amount of time that master and slave clocks are sampled.
1460 * Returns: the interval between samples.
1463 gst_clock_get_timeout (GstClock * clock)
1465 GstClockTime result;
1467 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
1469 GST_CLOCK_SLAVE_LOCK (clock);
1470 result = clock->priv->timeout;
1471 GST_CLOCK_SLAVE_UNLOCK (clock);
1477 gst_clock_set_property (GObject * object, guint prop_id,
1478 const GValue * value, GParamSpec * pspec)
1481 GstClockPrivate *priv;
1483 clock = GST_CLOCK (object);
1487 case PROP_WINDOW_SIZE:
1488 GST_CLOCK_SLAVE_LOCK (clock);
1489 priv->window_size = g_value_get_int (value);
1490 priv->window_threshold = MIN (priv->window_threshold, priv->window_size);
1491 priv->times = g_renew (GstClockTime, priv->times, 4 * priv->window_size);
1492 /* restart calibration */
1493 priv->filling = TRUE;
1494 priv->time_index = 0;
1495 GST_CLOCK_SLAVE_UNLOCK (clock);
1497 case PROP_WINDOW_THRESHOLD:
1498 GST_CLOCK_SLAVE_LOCK (clock);
1499 priv->window_threshold = MIN (g_value_get_int (value), priv->window_size);
1500 GST_CLOCK_SLAVE_UNLOCK (clock);
1503 gst_clock_set_timeout (clock, g_value_get_uint64 (value));
1506 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1512 gst_clock_get_property (GObject * object, guint prop_id,
1513 GValue * value, GParamSpec * pspec)
1516 GstClockPrivate *priv;
1518 clock = GST_CLOCK (object);
1522 case PROP_WINDOW_SIZE:
1523 GST_CLOCK_SLAVE_LOCK (clock);
1524 g_value_set_int (value, priv->window_size);
1525 GST_CLOCK_SLAVE_UNLOCK (clock);
1527 case PROP_WINDOW_THRESHOLD:
1528 GST_CLOCK_SLAVE_LOCK (clock);
1529 g_value_set_int (value, priv->window_threshold);
1530 GST_CLOCK_SLAVE_UNLOCK (clock);
1533 g_value_set_uint64 (value, gst_clock_get_timeout (clock));
1536 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);