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);
177 /* static guint gst_clock_signals[LAST_SIGNAL] = { 0 }; */
180 gst_clock_entry_new (GstClock * clock, GstClockTime time,
181 GstClockTime interval, GstClockEntryType type)
183 GstClockEntry *entry;
185 entry = g_slice_new (GstClockEntry);
186 #ifndef GST_DISABLE_TRACE
187 _gst_alloc_trace_new (_gst_clock_entry_trace, entry);
189 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
190 "created entry %p, time %" GST_TIME_FORMAT, entry, GST_TIME_ARGS (time));
193 entry->clock = clock;
196 entry->interval = interval;
197 entry->status = GST_CLOCK_OK;
199 entry->user_data = NULL;
200 entry->destroy_data = NULL;
201 entry->unscheduled = FALSE;
202 entry->woken_up = FALSE;
204 return (GstClockID) entry;
207 /* WARNING : Does not modify the refcount
208 * WARNING : Do not use if a pending clock operation is happening on that entry */
210 gst_clock_entry_reinit (GstClock * clock, GstClockEntry * entry,
211 GstClockTime time, GstClockTime interval, GstClockEntryType type)
213 g_return_val_if_fail (entry->status != GST_CLOCK_BUSY, FALSE);
214 g_return_val_if_fail (entry->clock == clock, FALSE);
218 entry->interval = interval;
219 entry->status = GST_CLOCK_OK;
220 entry->unscheduled = FALSE;
221 entry->woken_up = FALSE;
227 * gst_clock_single_shot_id_reinit:
228 * @clock: a #GstClock
230 * @time: The requested time.
232 * Reinitializes the provided single shot @id to the provided time. Does not
233 * modify the reference count.
235 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
236 * @time, else %FALSE.
241 gst_clock_single_shot_id_reinit (GstClock * clock, GstClockID id,
244 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, time,
245 GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
249 * gst_clock_periodic_id_reinit:
250 * @clock: a #GstClock
252 * @start_time: the requested start time
253 * @interval: the requested interval
255 * Reinitializes the provided periodic @id to the provided start time and
256 * interval. Does not modify the reference count.
258 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
259 * @time, else %FALSE.
265 gst_clock_periodic_id_reinit (GstClock * clock, GstClockID id,
266 GstClockTime start_time, GstClockTime interval)
268 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, start_time,
269 interval, GST_CLOCK_ENTRY_PERIODIC);
274 * @id: The #GstClockID to ref
276 * Increase the refcount of given @id.
278 * Returns: (transfer full): The same #GstClockID with increased refcount.
283 gst_clock_id_ref (GstClockID id)
285 g_return_val_if_fail (id != NULL, NULL);
287 g_atomic_int_inc (&((GstClockEntry *) id)->refcount);
293 _gst_clock_id_free (GstClockID id)
295 GstClockEntry *entry;
296 g_return_if_fail (id != NULL);
298 GST_CAT_DEBUG (GST_CAT_CLOCK, "freed entry %p", id);
299 entry = (GstClockEntry *) id;
300 if (entry->destroy_data)
301 entry->destroy_data (entry->user_data);
303 #ifndef GST_DISABLE_TRACE
304 _gst_alloc_trace_free (_gst_clock_entry_trace, id);
306 g_slice_free (GstClockEntry, id);
310 * gst_clock_id_unref:
311 * @id: (transfer full): The #GstClockID to unref
313 * Unref given @id. When the refcount reaches 0 the
314 * #GstClockID will be freed.
319 gst_clock_id_unref (GstClockID id)
323 g_return_if_fail (id != NULL);
325 zero = g_atomic_int_dec_and_test (&((GstClockEntry *) id)->refcount);
326 /* if we ended up with the refcount at zero, free the id */
328 _gst_clock_id_free (id);
333 * gst_clock_new_single_shot_id:
334 * @clock: The #GstClockID to get a single shot notification from
335 * @time: the requested time
337 * Get a #GstClockID from @clock to trigger a single shot
338 * notification at the requested time. The single shot id should be
339 * unreffed after usage.
341 * Free-function: gst_clock_id_unref
343 * Returns: (transfer full): a #GstClockID that can be used to request the
349 gst_clock_new_single_shot_id (GstClock * clock, GstClockTime time)
351 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
353 return gst_clock_entry_new (clock,
354 time, GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
358 * gst_clock_new_periodic_id:
359 * @clock: The #GstClockID to get a periodic notification id from
360 * @start_time: the requested start time
361 * @interval: the requested interval
363 * Get an ID from @clock to trigger a periodic notification.
364 * The periodic notifications will start at time @start_time and
365 * will then be fired with the given @interval. @id should be unreffed
368 * Free-function: gst_clock_id_unref
370 * Returns: (transfer full): a #GstClockID that can be used to request the
376 gst_clock_new_periodic_id (GstClock * clock, GstClockTime start_time,
377 GstClockTime interval)
379 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
380 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (start_time), NULL);
381 g_return_val_if_fail (interval != 0, NULL);
382 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), NULL);
384 return gst_clock_entry_new (clock,
385 start_time, interval, GST_CLOCK_ENTRY_PERIODIC);
389 * gst_clock_id_compare_func
390 * @id1: A #GstClockID
391 * @id2: A #GstClockID to compare with
393 * Compares the two #GstClockID instances. This function can be used
394 * as a GCompareFunc when sorting ids.
396 * Returns: negative value if a < b; zero if a = b; positive value if a > b
401 gst_clock_id_compare_func (gconstpointer id1, gconstpointer id2)
403 GstClockEntry *entry1, *entry2;
405 entry1 = (GstClockEntry *) id1;
406 entry2 = (GstClockEntry *) id2;
408 if (GST_CLOCK_ENTRY_TIME (entry1) > GST_CLOCK_ENTRY_TIME (entry2)) {
411 if (GST_CLOCK_ENTRY_TIME (entry1) < GST_CLOCK_ENTRY_TIME (entry2)) {
418 * gst_clock_id_get_time
419 * @id: The #GstClockID to query
421 * Get the time of the clock ID
423 * Returns: the time of the given clock id.
428 gst_clock_id_get_time (GstClockID id)
430 g_return_val_if_fail (id != NULL, GST_CLOCK_TIME_NONE);
432 return GST_CLOCK_ENTRY_TIME ((GstClockEntry *) id);
437 * @id: The #GstClockID to wait on
438 * @jitter: (out) (allow-none): a pointer that will contain the jitter,
441 * Perform a blocking wait on @id.
442 * @id should have been created with gst_clock_new_single_shot_id()
443 * or gst_clock_new_periodic_id() and should not have been unscheduled
444 * with a call to gst_clock_id_unschedule().
446 * If the @jitter argument is not %NULL and this function returns #GST_CLOCK_OK
447 * or #GST_CLOCK_EARLY, it will contain the difference
448 * against the clock and the time of @id when this method was
450 * Positive values indicate how late @id was relative to the clock
451 * (in which case this function will return #GST_CLOCK_EARLY).
452 * Negative values indicate how much time was spent waiting on the clock
453 * before this function returned.
455 * Returns: the result of the blocking wait. #GST_CLOCK_EARLY will be returned
456 * if the current clock time is past the time of @id, #GST_CLOCK_OK if
457 * @id was scheduled in time. #GST_CLOCK_UNSCHEDULED if @id was
458 * unscheduled with gst_clock_id_unschedule().
463 gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
465 GstClockEntry *entry;
468 GstClockTime requested;
469 GstClockClass *cclass;
471 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
473 entry = (GstClockEntry *) id;
474 requested = GST_CLOCK_ENTRY_TIME (entry);
476 clock = GST_CLOCK_ENTRY_CLOCK (entry);
478 /* can't sync on invalid times */
479 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
482 cclass = GST_CLOCK_GET_CLASS (clock);
484 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);
486 /* if we have a wait_jitter function, use that */
487 if (G_UNLIKELY (cclass->wait == NULL))
490 res = cclass->wait (clock, entry, jitter);
492 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
493 "done waiting entry %p, res: %d", id, res);
495 if (entry->type == GST_CLOCK_ENTRY_PERIODIC)
496 entry->time = requested + entry->interval;
503 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
504 "invalid time requested, returning _BADTIME");
505 return GST_CLOCK_BADTIME;
509 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
510 return GST_CLOCK_UNSUPPORTED;
515 * gst_clock_id_wait_async_full:
516 * @id: a #GstClockID to wait on
517 * @func: The callback function
518 * @user_data: User data passed in the callback
519 * @destroy_data: #GDestroyNotify for user_data
521 * Register a callback on the given #GstClockID @id with the given
522 * function and user_data. When passing a #GstClockID with an invalid
523 * time to this function, the callback will be called immediately
524 * with a time set to GST_CLOCK_TIME_NONE. The callback will
525 * be called when the time of @id has been reached.
527 * The callback @func can be invoked from any thread, either provided by the
528 * core or from a streaming thread. The application should be prepared for this.
530 * Returns: the result of the non blocking wait.
537 gst_clock_id_wait_async_full (GstClockID id,
538 GstClockCallback func, gpointer user_data, GDestroyNotify destroy_data)
540 GstClockEntry *entry;
543 GstClockClass *cclass;
544 GstClockTime requested;
546 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
547 g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
549 entry = (GstClockEntry *) id;
550 requested = GST_CLOCK_ENTRY_TIME (entry);
551 clock = GST_CLOCK_ENTRY_CLOCK (entry);
553 /* can't sync on invalid times */
554 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
557 cclass = GST_CLOCK_GET_CLASS (clock);
559 if (G_UNLIKELY (cclass->wait_async == NULL))
563 entry->user_data = user_data;
564 entry->destroy_data = destroy_data;
566 res = cclass->wait_async (clock, entry);
573 (func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
574 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
575 "invalid time requested, returning _BADTIME");
576 return GST_CLOCK_BADTIME;
580 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
581 return GST_CLOCK_UNSUPPORTED;
586 * gst_clock_id_wait_async:
587 * @id: a #GstClockID to wait on
588 * @func: The callback function
589 * @user_data: User data passed in the callback
591 * Register a callback on the given #GstClockID @id with the given
592 * function and user_data. When passing a #GstClockID with an invalid
593 * time to this function, the callback will be called immediately
594 * with a time set to GST_CLOCK_TIME_NONE. The callback will
595 * be called when the time of @id has been reached.
597 * The callback @func can be invoked from any thread, either provided by the
598 * core or from a streaming thread. The application should be prepared for this.
600 * Returns: the result of the non blocking wait.
605 gst_clock_id_wait_async (GstClockID id,
606 GstClockCallback func, gpointer user_data)
608 return gst_clock_id_wait_async_full (id, func, user_data, NULL);
612 * gst_clock_id_unschedule:
613 * @id: The id to unschedule
615 * Cancel an outstanding request with @id. This can either
616 * be an outstanding async notification or a pending sync notification.
617 * After this call, @id cannot be used anymore to receive sync or
618 * async notifications, you need to create a new #GstClockID.
623 gst_clock_id_unschedule (GstClockID id)
625 GstClockEntry *entry;
627 GstClockClass *cclass;
629 g_return_if_fail (id != NULL);
631 entry = (GstClockEntry *) id;
632 clock = entry->clock;
634 cclass = GST_CLOCK_GET_CLASS (clock);
636 if (G_LIKELY (cclass->unschedule))
637 cclass->unschedule (clock, entry);
642 * GstClock abstract base class implementation
644 #define gst_clock_parent_class parent_class
645 G_DEFINE_TYPE (GstClock, gst_clock, GST_TYPE_OBJECT);
648 gst_clock_class_init (GstClockClass * klass)
650 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
652 #ifndef GST_DISABLE_TRACE
653 _gst_clock_entry_trace = _gst_alloc_trace_register ("GstClockEntry", -1);
656 gobject_class->dispose = gst_clock_dispose;
657 gobject_class->finalize = gst_clock_finalize;
658 gobject_class->set_property = gst_clock_set_property;
659 gobject_class->get_property = gst_clock_get_property;
661 g_object_class_install_property (gobject_class, PROP_WINDOW_SIZE,
662 g_param_spec_int ("window-size", "Window size",
663 "The size of the window used to calculate rate and offset", 2, 1024,
664 DEFAULT_WINDOW_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
665 g_object_class_install_property (gobject_class, PROP_WINDOW_THRESHOLD,
666 g_param_spec_int ("window-threshold", "Window threshold",
667 "The threshold to start calculating rate and offset", 2, 1024,
668 DEFAULT_WINDOW_THRESHOLD,
669 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
670 g_object_class_install_property (gobject_class, PROP_TIMEOUT,
671 g_param_spec_uint64 ("timeout", "Timeout",
672 "The amount of time, in nanoseconds, to sample master and slave clocks",
673 0, G_MAXUINT64, DEFAULT_TIMEOUT,
674 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
676 g_type_class_add_private (klass, sizeof (GstClockPrivate));
680 gst_clock_init (GstClock * clock)
682 clock->last_time = 0;
683 clock->entries = NULL;
684 g_cond_init (&clock->entries_changed);
687 G_TYPE_INSTANCE_GET_PRIVATE (clock, GST_TYPE_CLOCK, GstClockPrivate);
689 clock->internal_calibration = 0;
690 clock->external_calibration = 0;
691 clock->rate_numerator = 1;
692 clock->rate_denominator = 1;
694 g_mutex_init (&clock->slave_lock);
695 clock->window_size = DEFAULT_WINDOW_SIZE;
696 clock->window_threshold = DEFAULT_WINDOW_THRESHOLD;
697 clock->filling = TRUE;
698 clock->time_index = 0;
699 clock->timeout = DEFAULT_TIMEOUT;
700 clock->times = g_new0 (GstClockTime, 4 * clock->window_size);
704 gst_clock_dispose (GObject * object)
706 GstClock *clock = GST_CLOCK (object);
709 GST_OBJECT_LOCK (clock);
710 master_p = &clock->master;
711 gst_object_replace ((GstObject **) master_p, NULL);
712 GST_OBJECT_UNLOCK (clock);
714 G_OBJECT_CLASS (parent_class)->dispose (object);
718 gst_clock_finalize (GObject * object)
720 GstClock *clock = GST_CLOCK (object);
722 GST_CLOCK_SLAVE_LOCK (clock);
723 if (clock->clockid) {
724 gst_clock_id_unschedule (clock->clockid);
725 gst_clock_id_unref (clock->clockid);
726 clock->clockid = NULL;
728 g_free (clock->times);
730 GST_CLOCK_SLAVE_UNLOCK (clock);
732 g_cond_clear (&clock->entries_changed);
733 g_mutex_clear (&clock->slave_lock);
735 G_OBJECT_CLASS (parent_class)->finalize (object);
739 * gst_clock_set_resolution
740 * @clock: a #GstClock
741 * @resolution: The resolution to set
743 * Set the accuracy of the clock. Some clocks have the possibility to operate
744 * with different accuracy at the expense of more resource usage. There is
745 * normally no need to change the default resolution of a clock. The resolution
746 * of a clock can only be changed if the clock has the
747 * #GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set.
749 * Returns: the new resolution of the clock.
752 gst_clock_set_resolution (GstClock * clock, GstClockTime resolution)
754 GstClockClass *cclass;
756 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
757 g_return_val_if_fail (resolution != 0, 0);
759 cclass = GST_CLOCK_GET_CLASS (clock);
761 if (cclass->change_resolution)
763 cclass->change_resolution (clock, clock->resolution, resolution);
765 return clock->resolution;
769 * gst_clock_get_resolution
770 * @clock: a #GstClock
772 * Get the accuracy of the clock. The accuracy of the clock is the granularity
773 * of the values returned by gst_clock_get_time().
775 * Returns: the resolution of the clock in units of #GstClockTime.
780 gst_clock_get_resolution (GstClock * clock)
782 GstClockClass *cclass;
784 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
786 cclass = GST_CLOCK_GET_CLASS (clock);
788 if (cclass->get_resolution)
789 return cclass->get_resolution (clock);
795 * gst_clock_adjust_unlocked
796 * @clock: a #GstClock to use
797 * @internal: a clock time
799 * Converts the given @internal clock time to the external time, adjusting for the
800 * rate and reference time set with gst_clock_set_calibration() and making sure
801 * that the returned time is increasing. This function should be called with the
802 * clock's OBJECT_LOCK held and is mainly used by clock subclasses.
804 * This function is the reverse of gst_clock_unadjust_unlocked().
806 * Returns: the converted time of the clock.
809 gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
811 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
813 /* get calibration values for readability */
814 cinternal = clock->internal_calibration;
815 cexternal = clock->external_calibration;
816 cnum = clock->rate_numerator;
817 cdenom = clock->rate_denominator;
819 /* avoid divide by 0 */
820 if (G_UNLIKELY (cdenom == 0))
823 /* The formula is (internal - cinternal) * cnum / cdenom + cexternal
825 * Since we do math on unsigned 64-bit ints we have to special case for
826 * internal < cinternal to get the sign right. this case is not very common,
829 if (G_LIKELY (internal >= cinternal)) {
830 ret = internal - cinternal;
831 ret = gst_util_uint64_scale (ret, cnum, cdenom);
834 ret = cinternal - internal;
835 ret = gst_util_uint64_scale (ret, cnum, cdenom);
837 if (G_LIKELY (cexternal > ret))
838 ret = cexternal - ret;
843 /* make sure the time is increasing */
844 clock->last_time = MAX (ret, clock->last_time);
846 return clock->last_time;
850 * gst_clock_unadjust_unlocked
851 * @clock: a #GstClock to use
852 * @external: an external clock time
854 * Converts the given @external clock time to the internal time of @clock,
855 * using the rate and reference time set with gst_clock_set_calibration().
856 * This function should be called with the clock's OBJECT_LOCK held and
857 * is mainly used by clock subclasses.
859 * This function is the reverse of gst_clock_adjust_unlocked().
861 * Returns: the internal time of the clock corresponding to @external.
866 gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external)
868 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
870 /* get calibration values for readability */
871 cinternal = clock->internal_calibration;
872 cexternal = clock->external_calibration;
873 cnum = clock->rate_numerator;
874 cdenom = clock->rate_denominator;
876 /* avoid divide by 0 */
877 if (G_UNLIKELY (cnum == 0))
880 /* The formula is (external - cexternal) * cdenom / cnum + cinternal */
881 if (G_LIKELY (external >= cexternal)) {
882 ret = external - cexternal;
883 ret = gst_util_uint64_scale (ret, cdenom, cnum);
886 ret = cexternal - external;
887 ret = gst_util_uint64_scale (ret, cdenom, cnum);
888 if (G_LIKELY (cinternal > ret))
889 ret = cinternal - ret;
897 * gst_clock_get_internal_time
898 * @clock: a #GstClock to query
900 * Gets the current internal time of the given clock. The time is returned
901 * unadjusted for the offset and the rate.
903 * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
904 * given invalid input.
909 gst_clock_get_internal_time (GstClock * clock)
912 GstClockClass *cclass;
914 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
916 cclass = GST_CLOCK_GET_CLASS (clock);
918 if (G_UNLIKELY (cclass->get_internal_time == NULL))
921 ret = cclass->get_internal_time (clock);
923 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
924 GST_TIME_ARGS (ret));
931 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
932 "internal time not supported, return 0");
933 return G_GINT64_CONSTANT (0);
939 * @clock: a #GstClock to query
941 * Gets the current time of the given clock. The time is always
942 * monotonically increasing and adjusted according to the current
945 * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when
946 * given invalid input.
951 gst_clock_get_time (GstClock * clock)
956 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
959 /* reget the internal time when we retry to get the most current
961 ret = gst_clock_get_internal_time (clock);
963 seq = read_seqbegin (clock);
964 /* this will scale for rate and offset */
965 ret = gst_clock_adjust_unlocked (clock, ret);
966 } while (read_seqretry (clock, seq));
968 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "adjusted time %" GST_TIME_FORMAT,
969 GST_TIME_ARGS (ret));
975 * gst_clock_set_calibration
976 * @clock: a #GstClock to calibrate
977 * @internal: a reference internal time
978 * @external: a reference external time
979 * @rate_num: the numerator of the rate of the clock relative to its
981 * @rate_denom: the denominator of the rate of the clock
983 * Adjusts the rate and time of @clock. A rate of 1/1 is the normal speed of
984 * the clock. Values bigger than 1/1 make the clock go faster.
986 * @internal and @external are calibration parameters that arrange that
987 * gst_clock_get_time() should have been @external at internal time @internal.
988 * This internal time should not be in the future; that is, it should be less
989 * than the value of gst_clock_get_internal_time() when this function is called.
991 * Subsequent calls to gst_clock_get_time() will return clock times computed as
995 * time = (internal_time - internal) * rate_num / rate_denom + external
998 * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
999 * tries to do the integer arithmetic as precisely as possible.
1001 * Note that gst_clock_get_time() always returns increasing values so when you
1002 * move the clock backwards, gst_clock_get_time() will report the previous value
1003 * until the clock catches up.
1008 gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
1009 external, GstClockTime rate_num, GstClockTime rate_denom)
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);
1015 write_seqlock (clock);
1016 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1017 "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT " %"
1018 G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f", GST_TIME_ARGS (internal),
1019 GST_TIME_ARGS (external), rate_num, rate_denom,
1020 gst_guint64_to_gdouble (rate_num) / gst_guint64_to_gdouble (rate_denom));
1022 clock->internal_calibration = internal;
1023 clock->external_calibration = external;
1024 clock->rate_numerator = rate_num;
1025 clock->rate_denominator = rate_denom;
1026 write_sequnlock (clock);
1030 * gst_clock_get_calibration
1031 * @clock: a #GstClock
1032 * @internal: (out) (allow-none): a location to store the internal time
1033 * @external: (out) (allow-none): a location to store the external time
1034 * @rate_num: (out) (allow-none): a location to store the rate numerator
1035 * @rate_denom: (out) (allow-none): a location to store the rate denominator
1037 * Gets the internal rate and reference time of @clock. See
1038 * gst_clock_set_calibration() for more information.
1040 * @internal, @external, @rate_num, and @rate_denom can be left %NULL if the
1041 * caller is not interested in the values.
1046 gst_clock_get_calibration (GstClock * clock, GstClockTime * internal,
1047 GstClockTime * external, GstClockTime * rate_num, GstClockTime * rate_denom)
1051 g_return_if_fail (GST_IS_CLOCK (clock));
1054 seq = read_seqbegin (clock);
1056 *rate_num = clock->rate_numerator;
1058 *rate_denom = clock->rate_denominator;
1060 *external = clock->external_calibration;
1062 *internal = clock->internal_calibration;
1063 } while (read_seqretry (clock, seq));
1066 /* will be called repeatedly to sample the master and slave clock
1067 * to recalibrate the clock */
1069 gst_clock_slave_callback (GstClock * master, GstClockTime time,
1070 GstClockID id, GstClock * clock)
1072 GstClockTime stime, mtime;
1075 stime = gst_clock_get_internal_time (clock);
1076 mtime = gst_clock_get_time (master);
1078 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1079 "master %" GST_TIME_FORMAT ", slave %" GST_TIME_FORMAT,
1080 GST_TIME_ARGS (mtime), GST_TIME_ARGS (stime));
1082 gst_clock_add_observation (clock, stime, mtime, &r_squared);
1084 /* FIXME, we can use the r_squared value to adjust the timeout
1085 * value of the clockid */
1091 * gst_clock_set_master
1092 * @clock: a #GstClock
1093 * @master: (allow-none): a master #GstClock
1095 * Set @master as the master clock for @clock. @clock will be automatically
1096 * calibrated so that gst_clock_get_time() reports the same time as the
1099 * A clock provider that slaves its clock to a master can get the current
1100 * calibration values with gst_clock_get_calibration().
1102 * @master can be %NULL in which case @clock will not be slaved anymore. It will
1103 * however keep reporting its time adjusted with the last configured rate
1106 * Returns: %TRUE if the clock is capable of being slaved to a master clock.
1107 * Trying to set a master on a clock without the
1108 * #GST_CLOCK_FLAG_CAN_SET_MASTER flag will make this function return %FALSE.
1113 gst_clock_set_master (GstClock * clock, GstClock * master)
1115 GstClock **master_p;
1117 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1118 g_return_val_if_fail (master != clock, FALSE);
1120 GST_OBJECT_LOCK (clock);
1121 /* we always allow setting the master to NULL */
1122 if (master && !GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER))
1124 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1125 "slaving %p to master clock %p", clock, master);
1126 GST_OBJECT_UNLOCK (clock);
1128 GST_CLOCK_SLAVE_LOCK (clock);
1129 if (clock->clockid) {
1130 gst_clock_id_unschedule (clock->clockid);
1131 gst_clock_id_unref (clock->clockid);
1132 clock->clockid = NULL;
1135 clock->filling = TRUE;
1136 clock->time_index = 0;
1137 /* use the master periodic id to schedule sampling and
1138 * clock calibration. */
1139 clock->clockid = gst_clock_new_periodic_id (master,
1140 gst_clock_get_time (master), clock->timeout);
1141 gst_clock_id_wait_async_full (clock->clockid,
1142 (GstClockCallback) gst_clock_slave_callback,
1143 gst_object_ref (clock), (GDestroyNotify) gst_object_unref);
1145 GST_CLOCK_SLAVE_UNLOCK (clock);
1147 GST_OBJECT_LOCK (clock);
1148 master_p = &clock->master;
1149 gst_object_replace ((GstObject **) master_p, (GstObject *) master);
1150 GST_OBJECT_UNLOCK (clock);
1157 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1158 "cannot be slaved to a master clock");
1159 GST_OBJECT_UNLOCK (clock);
1165 * gst_clock_get_master:
1166 * @clock: a #GstClock
1168 * Get the master clock that @clock is slaved to or %NULL when the clock is
1169 * not slaved to any master clock.
1171 * Returns: (transfer full): a master #GstClock or %NULL when this clock is
1172 * not slaved to a master clock. Unref after usage.
1177 gst_clock_get_master (GstClock * clock)
1179 GstClock *result = NULL;
1181 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
1183 GST_OBJECT_LOCK (clock);
1185 result = gst_object_ref (clock->master);
1186 GST_OBJECT_UNLOCK (clock);
1191 /* http://mathworld.wolfram.com/LeastSquaresFitting.html
1195 do_linear_regression (GstClock * clock, GstClockTime * m_num,
1196 GstClockTime * m_denom, GstClockTime * b, GstClockTime * xbase,
1197 gdouble * r_squared)
1199 GstClockTime *newx, *newy;
1200 GstClockTime xmin, ymin, xbar, ybar, xbar4, ybar4;
1201 GstClockTimeDiff sxx, sxy, syy;
1202 GstClockTime *x, *y;
1206 xbar = ybar = sxx = syy = sxy = 0;
1209 y = clock->times + 2;
1210 n = clock->filling ? clock->time_index : clock->window_size;
1212 #ifdef DEBUGGING_ENABLED
1213 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "doing regression on:");
1214 for (i = j = 0; i < n; i++, j += 4)
1215 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1216 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, x[j], y[j]);
1219 xmin = ymin = G_MAXUINT64;
1220 for (i = j = 0; i < n; i++, j += 4) {
1221 xmin = MIN (xmin, x[j]);
1222 ymin = MIN (ymin, y[j]);
1225 #ifdef DEBUGGING_ENABLED
1226 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min x: %" G_GUINT64_FORMAT,
1228 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min y: %" G_GUINT64_FORMAT,
1232 newx = clock->times + 1;
1233 newy = clock->times + 3;
1235 /* strip off unnecessary bits of precision */
1236 for (i = j = 0; i < n; i++, j += 4) {
1237 newx[j] = x[j] - xmin;
1238 newy[j] = y[j] - ymin;
1241 #ifdef DEBUGGING_ENABLED
1242 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "reduced numbers:");
1243 for (i = j = 0; i < n; i++, j += 4)
1244 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1245 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, newx[j], newy[j]);
1248 /* have to do this precisely otherwise the results are pretty much useless.
1249 * should guarantee that none of these accumulators can overflow */
1251 /* quantities on the order of 1e10 -> 30 bits; window size a max of 2^10, so
1252 this addition could end up around 2^40 or so -- ample headroom */
1253 for (i = j = 0; i < n; i++, j += 4) {
1260 #ifdef DEBUGGING_ENABLED
1261 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbar = %" G_GUINT64_FORMAT,
1263 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " ybar = %" G_GUINT64_FORMAT,
1267 /* multiplying directly would give quantities on the order of 1e20 -> 60 bits;
1268 times the window size that's 70 which is too much. Instead we (1) subtract
1269 off the xbar*ybar in the loop instead of after, to avoid accumulation; (2)
1270 shift off 4 bits from each multiplicand, giving an expected ceiling of 52
1271 bits, which should be enough. Need to check the incoming range and domain
1272 to ensure this is an appropriate loss of precision though. */
1275 for (i = j = 0; i < n; i++, j += 4) {
1276 GstClockTime newx4, newy4;
1278 newx4 = newx[j] >> 4;
1279 newy4 = newy[j] >> 4;
1281 sxx += newx4 * newx4 - xbar4 * xbar4;
1282 syy += newy4 * newy4 - ybar4 * ybar4;
1283 sxy += newx4 * newy4 - xbar4 * ybar4;
1286 if (G_UNLIKELY (sxx == 0))
1292 *b = (ybar + ymin) - gst_util_uint64_scale (xbar, *m_num, *m_denom);
1293 *r_squared = ((double) sxy * (double) sxy) / ((double) sxx * (double) syy);
1295 #ifdef DEBUGGING_ENABLED
1296 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " m = %g",
1297 ((double) *m_num) / *m_denom);
1298 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " b = %" G_GUINT64_FORMAT,
1300 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbase = %" G_GUINT64_FORMAT,
1302 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " r2 = %g", *r_squared);
1309 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "sxx == 0, regression failed");
1315 * gst_clock_add_observation
1316 * @clock: a #GstClock
1317 * @slave: a time on the slave
1318 * @master: a time on the master
1319 * @r_squared: (out): a pointer to hold the result
1321 * The time @master of the master clock and the time @slave of the slave
1322 * clock are added to the list of observations. If enough observations
1323 * are available, a linear regression algorithm is run on the
1324 * observations and @clock is recalibrated.
1326 * If this functions returns %TRUE, @r_squared will contain the
1327 * correlation coefficient of the interpolation. A value of 1.0
1328 * means a perfect regression was performed. This value can
1329 * be used to control the sampling frequency of the master and slave
1332 * Returns: %TRUE if enough observations were added to run the
1333 * regression algorithm.
1338 gst_clock_add_observation (GstClock * clock, GstClockTime slave,
1339 GstClockTime master, gdouble * r_squared)
1341 GstClockTime m_num, m_denom, b, xbase;
1343 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1344 g_return_val_if_fail (r_squared != NULL, FALSE);
1346 GST_CLOCK_SLAVE_LOCK (clock);
1348 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1349 "adding observation slave %" GST_TIME_FORMAT ", master %" GST_TIME_FORMAT,
1350 GST_TIME_ARGS (slave), GST_TIME_ARGS (master));
1352 clock->times[(4 * clock->time_index)] = slave;
1353 clock->times[(4 * clock->time_index) + 2] = master;
1355 clock->time_index++;
1356 if (G_UNLIKELY (clock->time_index == clock->window_size)) {
1357 clock->filling = FALSE;
1358 clock->time_index = 0;
1361 if (G_UNLIKELY (clock->filling
1362 && clock->time_index < clock->window_threshold))
1365 if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared))
1368 GST_CLOCK_SLAVE_UNLOCK (clock);
1370 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1371 "adjusting clock to m=%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT ", b=%"
1372 G_GUINT64_FORMAT " (rsquared=%g)", m_num, m_denom, b, *r_squared);
1374 /* if we have a valid regression, adjust the clock */
1375 gst_clock_set_calibration (clock, xbase, b, m_num, m_denom);
1381 GST_CLOCK_SLAVE_UNLOCK (clock);
1386 /* no valid regression has been done, ignore the result then */
1387 GST_CLOCK_SLAVE_UNLOCK (clock);
1393 gst_clock_set_property (GObject * object, guint prop_id,
1394 const GValue * value, GParamSpec * pspec)
1398 clock = GST_CLOCK (object);
1401 case PROP_WINDOW_SIZE:
1402 GST_CLOCK_SLAVE_LOCK (clock);
1403 clock->window_size = g_value_get_int (value);
1404 clock->window_threshold =
1405 MIN (clock->window_threshold, clock->window_size);
1407 g_renew (GstClockTime, clock->times, 4 * clock->window_size);
1408 /* restart calibration */
1409 clock->filling = TRUE;
1410 clock->time_index = 0;
1411 GST_CLOCK_SLAVE_UNLOCK (clock);
1413 case PROP_WINDOW_THRESHOLD:
1414 GST_CLOCK_SLAVE_LOCK (clock);
1415 clock->window_threshold =
1416 MIN (g_value_get_int (value), clock->window_size);
1417 GST_CLOCK_SLAVE_UNLOCK (clock);
1420 GST_CLOCK_SLAVE_LOCK (clock);
1421 clock->timeout = g_value_get_uint64 (value);
1422 GST_CLOCK_SLAVE_UNLOCK (clock);
1425 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1431 gst_clock_get_property (GObject * object, guint prop_id,
1432 GValue * value, GParamSpec * pspec)
1436 clock = GST_CLOCK (object);
1439 case PROP_WINDOW_SIZE:
1440 GST_CLOCK_SLAVE_LOCK (clock);
1441 g_value_set_int (value, clock->window_size);
1442 GST_CLOCK_SLAVE_UNLOCK (clock);
1444 case PROP_WINDOW_THRESHOLD:
1445 GST_CLOCK_SLAVE_LOCK (clock);
1446 g_value_set_int (value, clock->window_threshold);
1447 GST_CLOCK_SLAVE_UNLOCK (clock);
1450 GST_CLOCK_SLAVE_LOCK (clock);
1451 g_value_set_uint64 (value, clock->timeout);
1452 GST_CLOCK_SLAVE_UNLOCK (clock);
1455 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);