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 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.
268 gst_clock_single_shot_id_reinit (GstClock * clock, GstClockID id,
271 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, time,
272 GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
276 * gst_clock_periodic_id_reinit:
277 * @clock: a #GstClock
279 * @start_time: the requested start time
280 * @interval: the requested interval
282 * Reinitializes the provided periodic @id to the provided start time and
283 * interval. Does not modify the reference count.
285 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
286 * @time, else %FALSE.
292 gst_clock_periodic_id_reinit (GstClock * clock, GstClockID id,
293 GstClockTime start_time, GstClockTime interval)
295 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, start_time,
296 interval, GST_CLOCK_ENTRY_PERIODIC);
301 * @id: The #GstClockID to ref
303 * Increase the refcount of given @id.
305 * Returns: (transfer full): The same #GstClockID with increased refcount.
310 gst_clock_id_ref (GstClockID id)
312 g_return_val_if_fail (id != NULL, NULL);
314 g_atomic_int_inc (&((GstClockEntry *) id)->refcount);
320 _gst_clock_id_free (GstClockID id)
322 GstClockEntry *entry;
323 g_return_if_fail (id != NULL);
325 GST_CAT_DEBUG (GST_CAT_CLOCK, "freed entry %p", id);
326 entry = (GstClockEntry *) id;
327 if (entry->destroy_data)
328 entry->destroy_data (entry->user_data);
330 #ifndef GST_DISABLE_TRACE
331 _gst_alloc_trace_free (_gst_clock_entry_trace, id);
333 g_slice_free (GstClockEntry, id);
337 * gst_clock_id_unref:
338 * @id: (transfer full): The #GstClockID to unref
340 * Unref given @id. When the refcount reaches 0 the
341 * #GstClockID will be freed.
346 gst_clock_id_unref (GstClockID id)
350 g_return_if_fail (id != NULL);
352 zero = g_atomic_int_dec_and_test (&((GstClockEntry *) id)->refcount);
353 /* if we ended up with the refcount at zero, free the id */
355 _gst_clock_id_free (id);
360 * gst_clock_new_single_shot_id:
361 * @clock: The #GstClockID to get a single shot notification from
362 * @time: the requested time
364 * Get a #GstClockID from @clock to trigger a single shot
365 * notification at the requested time. The single shot id should be
366 * unreffed after usage.
368 * Free-function: gst_clock_id_unref
370 * Returns: (transfer full): a #GstClockID that can be used to request the
376 gst_clock_new_single_shot_id (GstClock * clock, GstClockTime time)
378 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
380 return gst_clock_entry_new (clock,
381 time, GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
385 * gst_clock_new_periodic_id:
386 * @clock: The #GstClockID to get a periodic notification id from
387 * @start_time: the requested start time
388 * @interval: the requested interval
390 * Get an ID from @clock to trigger a periodic notification.
391 * The periodic notifications will start at time @start_time and
392 * will then be fired with the given @interval. @id should be unreffed
395 * Free-function: gst_clock_id_unref
397 * Returns: (transfer full): a #GstClockID that can be used to request the
403 gst_clock_new_periodic_id (GstClock * clock, GstClockTime start_time,
404 GstClockTime interval)
406 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
407 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (start_time), NULL);
408 g_return_val_if_fail (interval != 0, NULL);
409 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), NULL);
411 return gst_clock_entry_new (clock,
412 start_time, interval, GST_CLOCK_ENTRY_PERIODIC);
416 * gst_clock_id_compare_func:
417 * @id1: A #GstClockID
418 * @id2: A #GstClockID to compare with
420 * Compares the two #GstClockID instances. This function can be used
421 * as a GCompareFunc when sorting ids.
423 * Returns: negative value if a < b; zero if a = b; positive value if a > b
428 gst_clock_id_compare_func (gconstpointer id1, gconstpointer id2)
430 GstClockEntry *entry1, *entry2;
432 entry1 = (GstClockEntry *) id1;
433 entry2 = (GstClockEntry *) id2;
435 if (GST_CLOCK_ENTRY_TIME (entry1) > GST_CLOCK_ENTRY_TIME (entry2)) {
438 if (GST_CLOCK_ENTRY_TIME (entry1) < GST_CLOCK_ENTRY_TIME (entry2)) {
445 * gst_clock_id_get_time:
446 * @id: The #GstClockID to query
448 * Get the time of the clock ID
450 * Returns: the time of the given clock id.
455 gst_clock_id_get_time (GstClockID id)
457 g_return_val_if_fail (id != NULL, GST_CLOCK_TIME_NONE);
459 return GST_CLOCK_ENTRY_TIME ((GstClockEntry *) id);
464 * @id: The #GstClockID to wait on
465 * @jitter: (out) (allow-none): a pointer that will contain the jitter,
468 * Perform a blocking wait on @id.
469 * @id should have been created with gst_clock_new_single_shot_id()
470 * or gst_clock_new_periodic_id() and should not have been unscheduled
471 * with a call to gst_clock_id_unschedule().
473 * If the @jitter argument is not %NULL and this function returns #GST_CLOCK_OK
474 * or #GST_CLOCK_EARLY, it will contain the difference
475 * against the clock and the time of @id when this method was
477 * Positive values indicate how late @id was relative to the clock
478 * (in which case this function will return #GST_CLOCK_EARLY).
479 * Negative values indicate how much time was spent waiting on the clock
480 * before this function returned.
482 * Returns: the result of the blocking wait. #GST_CLOCK_EARLY will be returned
483 * if the current clock time is past the time of @id, #GST_CLOCK_OK if
484 * @id was scheduled in time. #GST_CLOCK_UNSCHEDULED if @id was
485 * unscheduled with gst_clock_id_unschedule().
490 gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
492 GstClockEntry *entry;
495 GstClockTime requested;
496 GstClockClass *cclass;
498 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
500 entry = (GstClockEntry *) id;
501 requested = GST_CLOCK_ENTRY_TIME (entry);
503 clock = GST_CLOCK_ENTRY_CLOCK (entry);
505 /* can't sync on invalid times */
506 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
509 cclass = GST_CLOCK_GET_CLASS (clock);
511 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);
513 /* if we have a wait_jitter function, use that */
514 if (G_UNLIKELY (cclass->wait == NULL))
517 res = cclass->wait (clock, entry, jitter);
519 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
520 "done waiting entry %p, res: %d", id, res);
522 if (entry->type == GST_CLOCK_ENTRY_PERIODIC)
523 entry->time = requested + entry->interval;
530 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
531 "invalid time requested, returning _BADTIME");
532 return GST_CLOCK_BADTIME;
536 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
537 return GST_CLOCK_UNSUPPORTED;
542 * gst_clock_id_wait_async:
543 * @id: a #GstClockID to wait on
544 * @func: The callback function
545 * @user_data: User data passed in the callback
546 * @destroy_data: #GDestroyNotify for user_data
548 * Register a callback on the given #GstClockID @id with the given
549 * function and user_data. When passing a #GstClockID with an invalid
550 * time to this function, the callback will be called immediately
551 * with a time set to GST_CLOCK_TIME_NONE. The callback will
552 * be called when the time of @id has been reached.
554 * The callback @func can be invoked from any thread, either provided by the
555 * core or from a streaming thread. The application should be prepared for this.
557 * Returns: the result of the non blocking wait.
564 gst_clock_id_wait_async (GstClockID id,
565 GstClockCallback func, gpointer user_data, GDestroyNotify destroy_data)
567 GstClockEntry *entry;
570 GstClockClass *cclass;
571 GstClockTime requested;
573 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
574 g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
576 entry = (GstClockEntry *) id;
577 requested = GST_CLOCK_ENTRY_TIME (entry);
578 clock = GST_CLOCK_ENTRY_CLOCK (entry);
580 /* can't sync on invalid times */
581 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
584 cclass = GST_CLOCK_GET_CLASS (clock);
586 if (G_UNLIKELY (cclass->wait_async == NULL))
590 entry->user_data = user_data;
591 entry->destroy_data = destroy_data;
593 res = cclass->wait_async (clock, entry);
600 (func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
601 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
602 "invalid time requested, returning _BADTIME");
603 return GST_CLOCK_BADTIME;
607 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
608 return GST_CLOCK_UNSUPPORTED;
613 * gst_clock_id_unschedule:
614 * @id: The id to unschedule
616 * Cancel an outstanding request with @id. This can either
617 * be an outstanding async notification or a pending sync notification.
618 * After this call, @id cannot be used anymore to receive sync or
619 * async notifications, you need to create a new #GstClockID.
624 gst_clock_id_unschedule (GstClockID id)
626 GstClockEntry *entry;
628 GstClockClass *cclass;
630 g_return_if_fail (id != NULL);
632 entry = (GstClockEntry *) id;
633 clock = entry->clock;
635 cclass = GST_CLOCK_GET_CLASS (clock);
637 if (G_LIKELY (cclass->unschedule))
638 cclass->unschedule (clock, entry);
643 * GstClock abstract base class implementation
645 #define gst_clock_parent_class parent_class
646 G_DEFINE_ABSTRACT_TYPE (GstClock, gst_clock, GST_TYPE_OBJECT);
649 gst_clock_class_init (GstClockClass * klass)
651 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
653 #ifndef GST_DISABLE_TRACE
654 _gst_clock_entry_trace = _gst_alloc_trace_register ("GstClockEntry", -1);
657 gobject_class->dispose = gst_clock_dispose;
658 gobject_class->finalize = gst_clock_finalize;
659 gobject_class->set_property = gst_clock_set_property;
660 gobject_class->get_property = gst_clock_get_property;
662 g_object_class_install_property (gobject_class, PROP_WINDOW_SIZE,
663 g_param_spec_int ("window-size", "Window size",
664 "The size of the window used to calculate rate and offset", 2, 1024,
665 DEFAULT_WINDOW_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
666 g_object_class_install_property (gobject_class, PROP_WINDOW_THRESHOLD,
667 g_param_spec_int ("window-threshold", "Window threshold",
668 "The threshold to start calculating rate and offset", 2, 1024,
669 DEFAULT_WINDOW_THRESHOLD,
670 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
671 g_object_class_install_property (gobject_class, PROP_TIMEOUT,
672 g_param_spec_uint64 ("timeout", "Timeout",
673 "The amount of time, in nanoseconds, to sample master and slave clocks",
674 0, G_MAXUINT64, DEFAULT_TIMEOUT,
675 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
677 g_type_class_add_private (klass, sizeof (GstClockPrivate));
681 gst_clock_init (GstClock * clock)
683 GstClockPrivate *priv;
686 G_TYPE_INSTANCE_GET_PRIVATE (clock, GST_TYPE_CLOCK, GstClockPrivate);
690 priv->internal_calibration = 0;
691 priv->external_calibration = 0;
692 priv->rate_numerator = 1;
693 priv->rate_denominator = 1;
695 g_mutex_init (&priv->slave_lock);
696 priv->window_size = DEFAULT_WINDOW_SIZE;
697 priv->window_threshold = DEFAULT_WINDOW_THRESHOLD;
698 priv->filling = TRUE;
699 priv->time_index = 0;
700 priv->timeout = DEFAULT_TIMEOUT;
701 priv->times = g_new0 (GstClockTime, 4 * priv->window_size);
703 /* clear floating flag */
704 gst_object_ref_sink (clock);
708 gst_clock_dispose (GObject * object)
710 GstClock *clock = GST_CLOCK (object);
713 GST_OBJECT_LOCK (clock);
714 master_p = &clock->priv->master;
715 gst_object_replace ((GstObject **) master_p, NULL);
716 GST_OBJECT_UNLOCK (clock);
718 G_OBJECT_CLASS (parent_class)->dispose (object);
722 gst_clock_finalize (GObject * object)
724 GstClock *clock = GST_CLOCK (object);
726 GST_CLOCK_SLAVE_LOCK (clock);
727 if (clock->priv->clockid) {
728 gst_clock_id_unschedule (clock->priv->clockid);
729 gst_clock_id_unref (clock->priv->clockid);
730 clock->priv->clockid = NULL;
732 g_free (clock->priv->times);
733 clock->priv->times = NULL;
734 GST_CLOCK_SLAVE_UNLOCK (clock);
736 g_mutex_clear (&clock->priv->slave_lock);
738 G_OBJECT_CLASS (parent_class)->finalize (object);
742 * gst_clock_set_resolution:
743 * @clock: a #GstClock
744 * @resolution: The resolution to set
746 * Set the accuracy of the clock. Some clocks have the possibility to operate
747 * with different accuracy at the expense of more resource usage. There is
748 * normally no need to change the default resolution of a clock. The resolution
749 * of a clock can only be changed if the clock has the
750 * #GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set.
752 * Returns: the new resolution of the clock.
755 gst_clock_set_resolution (GstClock * clock, GstClockTime resolution)
757 GstClockPrivate *priv;
758 GstClockClass *cclass;
760 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
761 g_return_val_if_fail (resolution != 0, 0);
763 cclass = GST_CLOCK_GET_CLASS (clock);
766 if (cclass->change_resolution)
768 cclass->change_resolution (clock, priv->resolution, resolution);
770 return priv->resolution;
774 * gst_clock_get_resolution:
775 * @clock: a #GstClock
777 * Get the accuracy of the clock. The accuracy of the clock is the granularity
778 * of the values returned by gst_clock_get_time().
780 * Returns: the resolution of the clock in units of #GstClockTime.
785 gst_clock_get_resolution (GstClock * clock)
787 GstClockClass *cclass;
789 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
791 cclass = GST_CLOCK_GET_CLASS (clock);
793 if (cclass->get_resolution)
794 return cclass->get_resolution (clock);
800 * gst_clock_adjust_unlocked:
801 * @clock: a #GstClock to use
802 * @internal: a clock time
804 * Converts the given @internal clock time to the external time, adjusting for the
805 * rate and reference time set with gst_clock_set_calibration() and making sure
806 * that the returned time is increasing. This function should be called with the
807 * clock's OBJECT_LOCK held and is mainly used by clock subclasses.
809 * This function is the reverse of gst_clock_unadjust_unlocked().
811 * Returns: the converted time of the clock.
814 gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
816 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
817 GstClockPrivate *priv = clock->priv;
819 /* get calibration values for readability */
820 cinternal = priv->internal_calibration;
821 cexternal = priv->external_calibration;
822 cnum = priv->rate_numerator;
823 cdenom = priv->rate_denominator;
825 /* avoid divide by 0 */
826 if (G_UNLIKELY (cdenom == 0))
829 /* The formula is (internal - cinternal) * cnum / cdenom + cexternal
831 * Since we do math on unsigned 64-bit ints we have to special case for
832 * internal < cinternal to get the sign right. this case is not very common,
835 if (G_LIKELY (internal >= cinternal)) {
836 ret = internal - cinternal;
837 ret = gst_util_uint64_scale (ret, cnum, cdenom);
840 ret = cinternal - internal;
841 ret = gst_util_uint64_scale (ret, cnum, cdenom);
843 if (G_LIKELY (cexternal > ret))
844 ret = cexternal - ret;
849 /* make sure the time is increasing */
850 priv->last_time = MAX (ret, priv->last_time);
852 return priv->last_time;
856 * gst_clock_unadjust_unlocked:
857 * @clock: a #GstClock to use
858 * @external: an external clock time
860 * Converts the given @external clock time to the internal time of @clock,
861 * using the rate and reference time set with gst_clock_set_calibration().
862 * This function should be called with the clock's OBJECT_LOCK held and
863 * is mainly used by clock subclasses.
865 * This function is the reverse of gst_clock_adjust_unlocked().
867 * Returns: the internal time of the clock corresponding to @external.
872 gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external)
874 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
875 GstClockPrivate *priv = clock->priv;
877 /* get calibration values for readability */
878 cinternal = priv->internal_calibration;
879 cexternal = priv->external_calibration;
880 cnum = priv->rate_numerator;
881 cdenom = priv->rate_denominator;
883 /* avoid divide by 0 */
884 if (G_UNLIKELY (cnum == 0))
887 /* The formula is (external - cexternal) * cdenom / cnum + cinternal */
888 if (G_LIKELY (external >= cexternal)) {
889 ret = external - cexternal;
890 ret = gst_util_uint64_scale (ret, cdenom, cnum);
893 ret = cexternal - external;
894 ret = gst_util_uint64_scale (ret, cdenom, cnum);
895 if (G_LIKELY (cinternal > ret))
896 ret = cinternal - ret;
904 * gst_clock_get_internal_time:
905 * @clock: a #GstClock to query
907 * Gets the current internal time of the given clock. The time is returned
908 * unadjusted for the offset and the rate.
910 * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
911 * given invalid input.
916 gst_clock_get_internal_time (GstClock * clock)
919 GstClockClass *cclass;
921 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
923 cclass = GST_CLOCK_GET_CLASS (clock);
925 if (G_UNLIKELY (cclass->get_internal_time == NULL))
928 ret = cclass->get_internal_time (clock);
930 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
931 GST_TIME_ARGS (ret));
938 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
939 "internal time not supported, return 0");
940 return G_GINT64_CONSTANT (0);
945 * gst_clock_get_time:
946 * @clock: a #GstClock to query
948 * Gets the current time of the given clock. The time is always
949 * monotonically increasing and adjusted according to the current
952 * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when
953 * given invalid input.
958 gst_clock_get_time (GstClock * clock)
963 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
966 /* reget the internal time when we retry to get the most current
968 ret = gst_clock_get_internal_time (clock);
970 seq = read_seqbegin (clock);
971 /* this will scale for rate and offset */
972 ret = gst_clock_adjust_unlocked (clock, ret);
973 } while (read_seqretry (clock, seq));
975 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "adjusted time %" GST_TIME_FORMAT,
976 GST_TIME_ARGS (ret));
982 * gst_clock_set_calibration:
983 * @clock: a #GstClock to calibrate
984 * @internal: a reference internal time
985 * @external: a reference external time
986 * @rate_num: the numerator of the rate of the clock relative to its
988 * @rate_denom: the denominator of the rate of the clock
990 * Adjusts the rate and time of @clock. A rate of 1/1 is the normal speed of
991 * the clock. Values bigger than 1/1 make the clock go faster.
993 * @internal and @external are calibration parameters that arrange that
994 * gst_clock_get_time() should have been @external at internal time @internal.
995 * This internal time should not be in the future; that is, it should be less
996 * than the value of gst_clock_get_internal_time() when this function is called.
998 * Subsequent calls to gst_clock_get_time() will return clock times computed as
1002 * time = (internal_time - internal) * rate_num / rate_denom + external
1005 * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
1006 * tries to do the integer arithmetic as precisely as possible.
1008 * Note that gst_clock_get_time() always returns increasing values so when you
1009 * move the clock backwards, gst_clock_get_time() will report the previous value
1010 * until the clock catches up.
1015 gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
1016 external, GstClockTime rate_num, GstClockTime rate_denom)
1018 GstClockPrivate *priv;
1020 g_return_if_fail (GST_IS_CLOCK (clock));
1021 g_return_if_fail (rate_num != GST_CLOCK_TIME_NONE);
1022 g_return_if_fail (rate_denom > 0 && rate_denom != GST_CLOCK_TIME_NONE);
1026 write_seqlock (clock);
1027 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1028 "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT " %"
1029 G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f", GST_TIME_ARGS (internal),
1030 GST_TIME_ARGS (external), rate_num, rate_denom,
1031 gst_guint64_to_gdouble (rate_num) / gst_guint64_to_gdouble (rate_denom));
1033 priv->internal_calibration = internal;
1034 priv->external_calibration = external;
1035 priv->rate_numerator = rate_num;
1036 priv->rate_denominator = rate_denom;
1037 write_sequnlock (clock);
1041 * gst_clock_get_calibration:
1042 * @clock: a #GstClock
1043 * @internal: (out) (allow-none): a location to store the internal time
1044 * @external: (out) (allow-none): a location to store the external time
1045 * @rate_num: (out) (allow-none): a location to store the rate numerator
1046 * @rate_denom: (out) (allow-none): a location to store the rate denominator
1048 * Gets the internal rate and reference time of @clock. See
1049 * gst_clock_set_calibration() for more information.
1051 * @internal, @external, @rate_num, and @rate_denom can be left %NULL if the
1052 * caller is not interested in the values.
1057 gst_clock_get_calibration (GstClock * clock, GstClockTime * internal,
1058 GstClockTime * external, GstClockTime * rate_num, GstClockTime * rate_denom)
1061 GstClockPrivate *priv;
1063 g_return_if_fail (GST_IS_CLOCK (clock));
1068 seq = read_seqbegin (clock);
1070 *rate_num = priv->rate_numerator;
1072 *rate_denom = priv->rate_denominator;
1074 *external = priv->external_calibration;
1076 *internal = priv->internal_calibration;
1077 } while (read_seqretry (clock, seq));
1080 /* will be called repeatedly to sample the master and slave clock
1081 * to recalibrate the clock */
1083 gst_clock_slave_callback (GstClock * master, GstClockTime time,
1084 GstClockID id, GstClock * clock)
1086 GstClockTime stime, mtime;
1089 stime = gst_clock_get_internal_time (clock);
1090 mtime = gst_clock_get_time (master);
1092 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1093 "master %" GST_TIME_FORMAT ", slave %" GST_TIME_FORMAT,
1094 GST_TIME_ARGS (mtime), GST_TIME_ARGS (stime));
1096 gst_clock_add_observation (clock, stime, mtime, &r_squared);
1098 /* FIXME, we can use the r_squared value to adjust the timeout
1099 * value of the clockid */
1105 * gst_clock_set_master:
1106 * @clock: a #GstClock
1107 * @master: (allow-none): a master #GstClock
1109 * Set @master as the master clock for @clock. @clock will be automatically
1110 * calibrated so that gst_clock_get_time() reports the same time as the
1113 * A clock provider that slaves its clock to a master can get the current
1114 * calibration values with gst_clock_get_calibration().
1116 * @master can be %NULL in which case @clock will not be slaved anymore. It will
1117 * however keep reporting its time adjusted with the last configured rate
1120 * Returns: %TRUE if the clock is capable of being slaved to a master clock.
1121 * Trying to set a master on a clock without the
1122 * #GST_CLOCK_FLAG_CAN_SET_MASTER flag will make this function return %FALSE.
1127 gst_clock_set_master (GstClock * clock, GstClock * master)
1129 GstClock **master_p;
1130 GstClockPrivate *priv;
1132 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1133 g_return_val_if_fail (master != clock, FALSE);
1135 GST_OBJECT_LOCK (clock);
1136 /* we always allow setting the master to NULL */
1137 if (master && !GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER))
1139 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1140 "slaving %p to master clock %p", clock, master);
1141 GST_OBJECT_UNLOCK (clock);
1145 GST_CLOCK_SLAVE_LOCK (clock);
1146 if (priv->clockid) {
1147 gst_clock_id_unschedule (priv->clockid);
1148 gst_clock_id_unref (priv->clockid);
1149 priv->clockid = NULL;
1152 priv->filling = TRUE;
1153 priv->time_index = 0;
1154 /* use the master periodic id to schedule sampling and
1155 * clock calibration. */
1156 priv->clockid = gst_clock_new_periodic_id (master,
1157 gst_clock_get_time (master), priv->timeout);
1158 gst_clock_id_wait_async (priv->clockid,
1159 (GstClockCallback) gst_clock_slave_callback,
1160 gst_object_ref (clock), (GDestroyNotify) gst_object_unref);
1162 GST_CLOCK_SLAVE_UNLOCK (clock);
1164 GST_OBJECT_LOCK (clock);
1165 master_p = &priv->master;
1166 gst_object_replace ((GstObject **) master_p, (GstObject *) master);
1167 GST_OBJECT_UNLOCK (clock);
1174 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1175 "cannot be slaved to a master clock");
1176 GST_OBJECT_UNLOCK (clock);
1182 * gst_clock_get_master:
1183 * @clock: a #GstClock
1185 * Get the master clock that @clock is slaved to or %NULL when the clock is
1186 * not slaved to any master clock.
1188 * Returns: (transfer full): a master #GstClock or %NULL when this clock is
1189 * not slaved to a master clock. Unref after usage.
1194 gst_clock_get_master (GstClock * clock)
1196 GstClock *result = NULL;
1197 GstClockPrivate *priv;
1199 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
1203 GST_OBJECT_LOCK (clock);
1205 result = gst_object_ref (priv->master);
1206 GST_OBJECT_UNLOCK (clock);
1211 /* http://mathworld.wolfram.com/LeastSquaresFitting.html
1215 do_linear_regression (GstClock * clock, GstClockTime * m_num,
1216 GstClockTime * m_denom, GstClockTime * b, GstClockTime * xbase,
1217 gdouble * r_squared)
1219 GstClockTime *newx, *newy;
1220 GstClockTime xmin, ymin, xbar, ybar, xbar4, ybar4;
1221 GstClockTimeDiff sxx, sxy, syy;
1222 GstClockTime *x, *y;
1225 GstClockPrivate *priv;
1227 xbar = ybar = sxx = syy = sxy = 0;
1232 y = priv->times + 2;
1233 n = priv->filling ? priv->time_index : priv->window_size;
1235 #ifdef DEBUGGING_ENABLED
1236 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "doing regression on:");
1237 for (i = j = 0; i < n; i++, j += 4)
1238 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1239 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, x[j], y[j]);
1242 xmin = ymin = G_MAXUINT64;
1243 for (i = j = 0; i < n; i++, j += 4) {
1244 xmin = MIN (xmin, x[j]);
1245 ymin = MIN (ymin, y[j]);
1248 #ifdef DEBUGGING_ENABLED
1249 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min x: %" G_GUINT64_FORMAT,
1251 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min y: %" G_GUINT64_FORMAT,
1255 newx = priv->times + 1;
1256 newy = priv->times + 3;
1258 /* strip off unnecessary bits of precision */
1259 for (i = j = 0; i < n; i++, j += 4) {
1260 newx[j] = x[j] - xmin;
1261 newy[j] = y[j] - ymin;
1264 #ifdef DEBUGGING_ENABLED
1265 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "reduced numbers:");
1266 for (i = j = 0; i < n; i++, j += 4)
1267 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1268 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, newx[j], newy[j]);
1271 /* have to do this precisely otherwise the results are pretty much useless.
1272 * should guarantee that none of these accumulators can overflow */
1274 /* quantities on the order of 1e10 -> 30 bits; window size a max of 2^10, so
1275 this addition could end up around 2^40 or so -- ample headroom */
1276 for (i = j = 0; i < n; i++, j += 4) {
1283 #ifdef DEBUGGING_ENABLED
1284 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbar = %" G_GUINT64_FORMAT,
1286 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " ybar = %" G_GUINT64_FORMAT,
1290 /* multiplying directly would give quantities on the order of 1e20 -> 60 bits;
1291 times the window size that's 70 which is too much. Instead we (1) subtract
1292 off the xbar*ybar in the loop instead of after, to avoid accumulation; (2)
1293 shift off 4 bits from each multiplicand, giving an expected ceiling of 52
1294 bits, which should be enough. Need to check the incoming range and domain
1295 to ensure this is an appropriate loss of precision though. */
1298 for (i = j = 0; i < n; i++, j += 4) {
1299 GstClockTime newx4, newy4;
1301 newx4 = newx[j] >> 4;
1302 newy4 = newy[j] >> 4;
1304 sxx += newx4 * newx4 - xbar4 * xbar4;
1305 syy += newy4 * newy4 - ybar4 * ybar4;
1306 sxy += newx4 * newy4 - xbar4 * ybar4;
1309 if (G_UNLIKELY (sxx == 0))
1315 *b = (ybar + ymin) - gst_util_uint64_scale (xbar, *m_num, *m_denom);
1316 *r_squared = ((double) sxy * (double) sxy) / ((double) sxx * (double) syy);
1318 #ifdef DEBUGGING_ENABLED
1319 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " m = %g",
1320 ((double) *m_num) / *m_denom);
1321 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " b = %" G_GUINT64_FORMAT,
1323 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbase = %" G_GUINT64_FORMAT,
1325 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " r2 = %g", *r_squared);
1332 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "sxx == 0, regression failed");
1338 * gst_clock_add_observation:
1339 * @clock: a #GstClock
1340 * @slave: a time on the slave
1341 * @master: a time on the master
1342 * @r_squared: (out): a pointer to hold the result
1344 * The time @master of the master clock and the time @slave of the slave
1345 * clock are added to the list of observations. If enough observations
1346 * are available, a linear regression algorithm is run on the
1347 * observations and @clock is recalibrated.
1349 * If this functions returns %TRUE, @r_squared will contain the
1350 * correlation coefficient of the interpolation. A value of 1.0
1351 * means a perfect regression was performed. This value can
1352 * be used to control the sampling frequency of the master and slave
1355 * Returns: %TRUE if enough observations were added to run the
1356 * regression algorithm.
1361 gst_clock_add_observation (GstClock * clock, GstClockTime slave,
1362 GstClockTime master, gdouble * r_squared)
1364 GstClockTime m_num, m_denom, b, xbase;
1365 GstClockPrivate *priv;
1367 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1368 g_return_val_if_fail (r_squared != NULL, FALSE);
1372 GST_CLOCK_SLAVE_LOCK (clock);
1374 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1375 "adding observation slave %" GST_TIME_FORMAT ", master %" GST_TIME_FORMAT,
1376 GST_TIME_ARGS (slave), GST_TIME_ARGS (master));
1378 priv->times[(4 * priv->time_index)] = slave;
1379 priv->times[(4 * priv->time_index) + 2] = master;
1382 if (G_UNLIKELY (priv->time_index == priv->window_size)) {
1383 priv->filling = FALSE;
1384 priv->time_index = 0;
1387 if (G_UNLIKELY (priv->filling && priv->time_index < priv->window_threshold))
1390 if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared))
1393 GST_CLOCK_SLAVE_UNLOCK (clock);
1395 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1396 "adjusting clock to m=%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT ", b=%"
1397 G_GUINT64_FORMAT " (rsquared=%g)", m_num, m_denom, b, *r_squared);
1399 /* if we have a valid regression, adjust the clock */
1400 gst_clock_set_calibration (clock, xbase, b, m_num, m_denom);
1406 GST_CLOCK_SLAVE_UNLOCK (clock);
1411 /* no valid regression has been done, ignore the result then */
1412 GST_CLOCK_SLAVE_UNLOCK (clock);
1418 * gst_clock_set_timeout:
1419 * @clock: a #GstClock
1420 * @timeout: a timeout
1422 * Set the amount of time, in nanoseconds, to sample master and slave
1426 gst_clock_set_timeout (GstClock * clock, GstClockTime timeout)
1428 g_return_if_fail (GST_IS_CLOCK (clock));
1430 GST_CLOCK_SLAVE_LOCK (clock);
1431 clock->priv->timeout = timeout;
1432 GST_CLOCK_SLAVE_UNLOCK (clock);
1436 * gst_clock_get_timeout:
1437 * @clock: a #GstClock
1439 * Get the amount of time that master and slave clocks are sampled.
1441 * Returns: the interval between samples.
1444 gst_clock_get_timeout (GstClock * clock)
1446 GstClockTime result;
1448 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
1450 GST_CLOCK_SLAVE_LOCK (clock);
1451 result = clock->priv->timeout;
1452 GST_CLOCK_SLAVE_UNLOCK (clock);
1458 gst_clock_set_property (GObject * object, guint prop_id,
1459 const GValue * value, GParamSpec * pspec)
1462 GstClockPrivate *priv;
1464 clock = GST_CLOCK (object);
1468 case PROP_WINDOW_SIZE:
1469 GST_CLOCK_SLAVE_LOCK (clock);
1470 priv->window_size = g_value_get_int (value);
1471 priv->window_threshold = MIN (priv->window_threshold, priv->window_size);
1472 priv->times = g_renew (GstClockTime, priv->times, 4 * priv->window_size);
1473 /* restart calibration */
1474 priv->filling = TRUE;
1475 priv->time_index = 0;
1476 GST_CLOCK_SLAVE_UNLOCK (clock);
1478 case PROP_WINDOW_THRESHOLD:
1479 GST_CLOCK_SLAVE_LOCK (clock);
1480 priv->window_threshold = MIN (g_value_get_int (value), priv->window_size);
1481 GST_CLOCK_SLAVE_UNLOCK (clock);
1484 gst_clock_set_timeout (clock, g_value_get_uint64 (value));
1487 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1493 gst_clock_get_property (GObject * object, guint prop_id,
1494 GValue * value, GParamSpec * pspec)
1497 GstClockPrivate *priv;
1499 clock = GST_CLOCK (object);
1503 case PROP_WINDOW_SIZE:
1504 GST_CLOCK_SLAVE_LOCK (clock);
1505 g_value_set_int (value, priv->window_size);
1506 GST_CLOCK_SLAVE_UNLOCK (clock);
1508 case PROP_WINDOW_THRESHOLD:
1509 GST_CLOCK_SLAVE_LOCK (clock);
1510 g_value_set_int (value, priv->window_threshold);
1511 GST_CLOCK_SLAVE_UNLOCK (clock);
1514 g_value_set_uint64 (value, gst_clock_get_timeout (clock));
1517 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);