2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
4 * 2004 Wim Taymans <wim@fluendo.com>
6 * gstclock.c: Clock subsystem for maintaining time sync
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
26 * @short_description: Abstract class for global clocks
27 * @see_also: #GstSystemClock, #GstPipeline
29 * GStreamer uses a global clock to synchronize the plugins in a pipeline.
30 * Different clock implementations are possible by implementing this abstract
31 * base class or, more conveniently, by subclassing #GstSystemClock.
33 * The #GstClock returns a monotonically increasing time with the method
34 * gst_clock_get_time(). Its accuracy and base time depend on the specific
35 * clock implementation but time is always expressed in nanoseconds. Since the
36 * baseline of the clock is undefined, the clock time returned is not
37 * meaningful in itself, what matters are the deltas between two clock times.
38 * The time returned by a clock is called the absolute time.
40 * The pipeline uses the clock to calculate the running time. Usually all
41 * renderers synchronize to the global clock using the buffer timestamps, the
42 * newsegment events and the element's base time, see #GstPipeline.
44 * A clock implementation can support periodic and single shot clock
45 * notifications both synchronous and asynchronous.
47 * One first needs to create a #GstClockID for the periodic or single shot
48 * notification using gst_clock_new_single_shot_id() or
49 * gst_clock_new_periodic_id().
51 * To perform a blocking wait for the specific time of the #GstClockID use the
52 * gst_clock_id_wait(). To receive a callback when the specific time is reached
53 * in the clock use gst_clock_id_wait_async(). Both these calls can be
54 * interrupted with the gst_clock_id_unschedule() call. If the blocking wait is
55 * unscheduled a return value of #GST_CLOCK_UNSCHEDULED is returned.
57 * Periodic callbacks scheduled async will be repeatedly called automatically
58 * until it is unscheduled. To schedule a sync periodic callback,
59 * gst_clock_id_wait() should be called repeatedly.
61 * The async callbacks can happen from any thread, either provided by the core
62 * or from a streaming thread. The application should be prepared for this.
64 * A #GstClockID that has been unscheduled cannot be used again for any wait
65 * operation, a new #GstClockID should be created and the old unscheduled one
66 * should be destroyed with gst_clock_id_unref().
68 * It is possible to perform a blocking wait on the same #GstClockID from
69 * multiple threads. However, registering the same #GstClockID for multiple
70 * async notifications is not possible, the callback will only be called for
71 * the thread registering the entry last.
73 * None of the wait operations unref the #GstClockID, the owner is responsible
74 * for unreffing the ids itself. This holds for both periodic and single shot
75 * notifications. The reason being that the owner of the #GstClockID has to
76 * keep a handle to the #GstClockID to unblock the wait on FLUSHING events or
77 * state changes and if the entry would be unreffed automatically, the handle
78 * might become invalid without any notification.
80 * These clock operations do not operate on the running time, so the callbacks
81 * will also occur when not in PLAYING state as if the clock just keeps on
82 * running. Some clocks however do not progress when the element that provided
83 * the clock is not PLAYING.
85 * When a clock has the #GST_CLOCK_FLAG_CAN_SET_MASTER flag set, it can be
86 * slaved to another #GstClock with the gst_clock_set_master(). The clock will
87 * then automatically be synchronized to this master clock by repeatedly
88 * sampling the master clock and the slave clock and recalibrating the slave
89 * clock with gst_clock_set_calibration(). This feature is mostly useful for
90 * plugins that have an internal clock but must operate with another clock
91 * selected by the #GstPipeline. They can track the offset and rate difference
92 * of their internal clock relative to the master clock by using the
93 * gst_clock_get_calibration() function.
95 * The master/slave synchronisation can be tuned with the #GstClock:timeout,
96 * #GstClock:window-size and #GstClock:window-threshold properties.
97 * The #GstClock:timeout property defines the interval to sample the master
98 * clock and run the calibration functions. #GstClock:window-size defines the
99 * number of samples to use when calibrating and #GstClock:window-threshold
100 * defines the minimum number of samples before the calibration is performed.
102 * Last reviewed on 2012-03-28 (0.11.3)
106 #include "gst_private.h"
109 #include "gstclock.h"
111 #include "gstutils.h"
112 #include "glib-compat-private.h"
114 #ifndef GST_DISABLE_TRACE
115 /* #define GST_WITH_ALLOC_TRACE */
116 #include "gsttrace.h"
117 static GstAllocTrace *_gst_clock_entry_trace;
120 /* #define DEBUGGING_ENABLED */
122 #define DEFAULT_WINDOW_SIZE 32
123 #define DEFAULT_WINDOW_THRESHOLD 4
124 #define DEFAULT_TIMEOUT GST_SECOND / 10
130 PROP_WINDOW_THRESHOLD,
134 #define GST_CLOCK_SLAVE_LOCK(clock) g_mutex_lock (&GST_CLOCK_CAST (clock)->priv->slave_lock)
135 #define GST_CLOCK_SLAVE_UNLOCK(clock) g_mutex_unlock (&GST_CLOCK_CAST (clock)->priv->slave_lock)
137 struct _GstClockPrivate
139 GMutex slave_lock; /* order: SLAVE_LOCK, OBJECT_LOCK */
142 GstClockTime internal_calibration;
143 GstClockTime external_calibration;
144 GstClockTime rate_numerator;
145 GstClockTime rate_denominator;
146 GstClockTime last_time;
149 GstClockTime resolution;
151 /* for master/slave clocks */
154 /* with SLAVE_LOCK */
157 gint window_threshold;
159 GstClockTime timeout;
168 #define read_seqbegin(clock) \
169 g_atomic_int_get (&clock->priv->post_count);
171 static inline gboolean
172 read_seqretry (GstClock * clock, gint seq)
174 /* no retry if the seqnum did not change */
175 if (G_LIKELY (seq == g_atomic_int_get (&clock->priv->pre_count)))
178 /* wait for the writer to finish and retry */
179 GST_OBJECT_LOCK (clock);
180 GST_OBJECT_UNLOCK (clock);
184 #define write_seqlock(clock) \
186 GST_OBJECT_LOCK (clock); \
187 g_atomic_int_inc (&clock->priv->pre_count); \
190 #define write_sequnlock(clock) \
192 g_atomic_int_inc (&clock->priv->post_count); \
193 GST_OBJECT_UNLOCK (clock); \
196 #ifndef GST_DISABLE_GST_DEBUG
198 gst_clock_return_get_name (GstClockReturn ret)
203 case GST_CLOCK_EARLY:
205 case GST_CLOCK_UNSCHEDULED:
206 return "unscheduled";
209 case GST_CLOCK_BADTIME:
211 case GST_CLOCK_ERROR:
213 case GST_CLOCK_UNSUPPORTED:
214 return "unsupported";
223 #endif /* GST_DISABLE_GST_DEBUG */
225 static void gst_clock_dispose (GObject * object);
226 static void gst_clock_finalize (GObject * object);
228 static void gst_clock_set_property (GObject * object, guint prop_id,
229 const GValue * value, GParamSpec * pspec);
230 static void gst_clock_get_property (GObject * object, guint prop_id,
231 GValue * value, GParamSpec * pspec);
233 /* static guint gst_clock_signals[LAST_SIGNAL] = { 0 }; */
236 gst_clock_entry_new (GstClock * clock, GstClockTime time,
237 GstClockTime interval, GstClockEntryType type)
239 GstClockEntry *entry;
241 entry = g_slice_new (GstClockEntry);
242 #ifndef GST_DISABLE_TRACE
243 _gst_alloc_trace_new (_gst_clock_entry_trace, entry);
245 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
246 "created entry %p, time %" GST_TIME_FORMAT, entry, GST_TIME_ARGS (time));
249 entry->clock = clock;
252 entry->interval = interval;
253 entry->status = GST_CLOCK_OK;
255 entry->user_data = NULL;
256 entry->destroy_data = NULL;
257 entry->unscheduled = FALSE;
258 entry->woken_up = FALSE;
260 return (GstClockID) entry;
263 /* WARNING : Does not modify the refcount
264 * WARNING : Do not use if a pending clock operation is happening on that entry */
266 gst_clock_entry_reinit (GstClock * clock, GstClockEntry * entry,
267 GstClockTime time, GstClockTime interval, GstClockEntryType type)
269 g_return_val_if_fail (entry->status != GST_CLOCK_BUSY, FALSE);
270 g_return_val_if_fail (entry->clock == clock, FALSE);
274 entry->interval = interval;
275 entry->status = GST_CLOCK_OK;
276 entry->unscheduled = FALSE;
277 entry->woken_up = FALSE;
283 * gst_clock_single_shot_id_reinit:
284 * @clock: a #GstClock
286 * @time: The requested time.
288 * Reinitializes the provided single shot @id to the provided time. Does not
289 * modify the reference count.
291 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
292 * @time, else %FALSE.
295 gst_clock_single_shot_id_reinit (GstClock * clock, GstClockID id,
298 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, time,
299 GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
303 * gst_clock_periodic_id_reinit:
304 * @clock: a #GstClock
306 * @start_time: the requested start time
307 * @interval: the requested interval
309 * Reinitializes the provided periodic @id to the provided start time and
310 * interval. Does not modify the reference count.
312 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
313 * @time, else %FALSE.
316 gst_clock_periodic_id_reinit (GstClock * clock, GstClockID id,
317 GstClockTime start_time, GstClockTime interval)
319 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, start_time,
320 interval, GST_CLOCK_ENTRY_PERIODIC);
325 * @id: The #GstClockID to ref
327 * Increase the refcount of given @id.
329 * Returns: (transfer full): The same #GstClockID with increased refcount.
334 gst_clock_id_ref (GstClockID id)
336 g_return_val_if_fail (id != NULL, NULL);
338 g_atomic_int_inc (&((GstClockEntry *) id)->refcount);
344 _gst_clock_id_free (GstClockID id)
346 GstClockEntry *entry;
347 g_return_if_fail (id != NULL);
349 GST_CAT_DEBUG (GST_CAT_CLOCK, "freed entry %p", id);
350 entry = (GstClockEntry *) id;
351 if (entry->destroy_data)
352 entry->destroy_data (entry->user_data);
354 #ifndef GST_DISABLE_TRACE
355 _gst_alloc_trace_free (_gst_clock_entry_trace, id);
357 g_slice_free (GstClockEntry, id);
361 * gst_clock_id_unref:
362 * @id: (transfer full): The #GstClockID to unref
364 * Unref given @id. When the refcount reaches 0 the
365 * #GstClockID will be freed.
370 gst_clock_id_unref (GstClockID id)
374 g_return_if_fail (id != NULL);
376 zero = g_atomic_int_dec_and_test (&((GstClockEntry *) id)->refcount);
377 /* if we ended up with the refcount at zero, free the id */
379 _gst_clock_id_free (id);
384 * gst_clock_new_single_shot_id:
385 * @clock: The #GstClockID to get a single shot notification from
386 * @time: the requested time
388 * Get a #GstClockID from @clock to trigger a single shot
389 * notification at the requested time. The single shot id should be
390 * unreffed after usage.
392 * Free-function: gst_clock_id_unref
394 * Returns: (transfer full): a #GstClockID that can be used to request the
400 gst_clock_new_single_shot_id (GstClock * clock, GstClockTime time)
402 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
404 return gst_clock_entry_new (clock,
405 time, GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
409 * gst_clock_new_periodic_id:
410 * @clock: The #GstClockID to get a periodic notification id from
411 * @start_time: the requested start time
412 * @interval: the requested interval
414 * Get an ID from @clock to trigger a periodic notification.
415 * The periodic notifications will start at time @start_time and
416 * will then be fired with the given @interval. @id should be unreffed
419 * Free-function: gst_clock_id_unref
421 * Returns: (transfer full): a #GstClockID that can be used to request the
427 gst_clock_new_periodic_id (GstClock * clock, GstClockTime start_time,
428 GstClockTime interval)
430 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
431 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (start_time), NULL);
432 g_return_val_if_fail (interval != 0, NULL);
433 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), NULL);
435 return gst_clock_entry_new (clock,
436 start_time, interval, GST_CLOCK_ENTRY_PERIODIC);
440 * gst_clock_id_compare_func:
441 * @id1: A #GstClockID
442 * @id2: A #GstClockID to compare with
444 * Compares the two #GstClockID instances. This function can be used
445 * as a GCompareFunc when sorting ids.
447 * Returns: negative value if a < b; zero if a = b; positive value if a > b
452 gst_clock_id_compare_func (gconstpointer id1, gconstpointer id2)
454 GstClockEntry *entry1, *entry2;
456 entry1 = (GstClockEntry *) id1;
457 entry2 = (GstClockEntry *) id2;
459 if (GST_CLOCK_ENTRY_TIME (entry1) > GST_CLOCK_ENTRY_TIME (entry2)) {
462 if (GST_CLOCK_ENTRY_TIME (entry1) < GST_CLOCK_ENTRY_TIME (entry2)) {
469 * gst_clock_id_get_time:
470 * @id: The #GstClockID to query
472 * Get the time of the clock ID
474 * Returns: the time of the given clock id.
479 gst_clock_id_get_time (GstClockID id)
481 g_return_val_if_fail (id != NULL, GST_CLOCK_TIME_NONE);
483 return GST_CLOCK_ENTRY_TIME ((GstClockEntry *) id);
488 * @id: The #GstClockID to wait on
489 * @jitter: (out) (allow-none): a pointer that will contain the jitter,
492 * Perform a blocking wait on @id.
493 * @id should have been created with gst_clock_new_single_shot_id()
494 * or gst_clock_new_periodic_id() and should not have been unscheduled
495 * with a call to gst_clock_id_unschedule().
497 * If the @jitter argument is not %NULL and this function returns #GST_CLOCK_OK
498 * or #GST_CLOCK_EARLY, it will contain the difference
499 * against the clock and the time of @id when this method was
501 * Positive values indicate how late @id was relative to the clock
502 * (in which case this function will return #GST_CLOCK_EARLY).
503 * Negative values indicate how much time was spent waiting on the clock
504 * before this function returned.
506 * Returns: the result of the blocking wait. #GST_CLOCK_EARLY will be returned
507 * if the current clock time is past the time of @id, #GST_CLOCK_OK if
508 * @id was scheduled in time. #GST_CLOCK_UNSCHEDULED if @id was
509 * unscheduled with gst_clock_id_unschedule().
514 gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
516 GstClockEntry *entry;
519 GstClockTime requested;
520 GstClockClass *cclass;
522 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
524 entry = (GstClockEntry *) id;
525 requested = GST_CLOCK_ENTRY_TIME (entry);
527 clock = GST_CLOCK_ENTRY_CLOCK (entry);
529 /* can't sync on invalid times */
530 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
533 cclass = GST_CLOCK_GET_CLASS (clock);
535 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);
537 /* if we have a wait_jitter function, use that */
538 if (G_UNLIKELY (cclass->wait == NULL))
541 res = cclass->wait (clock, entry, jitter);
543 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
544 "done waiting entry %p, res: %d (%s)", id, res,
545 gst_clock_return_get_name (res));
547 if (entry->type == GST_CLOCK_ENTRY_PERIODIC)
548 entry->time = requested + entry->interval;
555 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
556 "invalid time requested, returning _BADTIME");
557 return GST_CLOCK_BADTIME;
561 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
562 return GST_CLOCK_UNSUPPORTED;
567 * gst_clock_id_wait_async:
568 * @id: a #GstClockID to wait on
569 * @func: The callback function
570 * @user_data: User data passed in the callback
571 * @destroy_data: #GDestroyNotify for user_data
573 * Register a callback on the given #GstClockID @id with the given
574 * function and user_data. When passing a #GstClockID with an invalid
575 * time to this function, the callback will be called immediately
576 * with a time set to GST_CLOCK_TIME_NONE. The callback will
577 * be called when the time of @id has been reached.
579 * The callback @func can be invoked from any thread, either provided by the
580 * core or from a streaming thread. The application should be prepared for this.
582 * Returns: the result of the non blocking wait.
587 gst_clock_id_wait_async (GstClockID id,
588 GstClockCallback func, gpointer user_data, GDestroyNotify destroy_data)
590 GstClockEntry *entry;
593 GstClockClass *cclass;
594 GstClockTime requested;
596 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
597 g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
599 entry = (GstClockEntry *) id;
600 requested = GST_CLOCK_ENTRY_TIME (entry);
601 clock = GST_CLOCK_ENTRY_CLOCK (entry);
603 /* can't sync on invalid times */
604 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
607 cclass = GST_CLOCK_GET_CLASS (clock);
609 if (G_UNLIKELY (cclass->wait_async == NULL))
613 entry->user_data = user_data;
614 entry->destroy_data = destroy_data;
616 res = cclass->wait_async (clock, entry);
623 (func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
624 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
625 "invalid time requested, returning _BADTIME");
626 return GST_CLOCK_BADTIME;
630 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
631 return GST_CLOCK_UNSUPPORTED;
636 * gst_clock_id_unschedule:
637 * @id: The id to unschedule
639 * Cancel an outstanding request with @id. This can either
640 * be an outstanding async notification or a pending sync notification.
641 * After this call, @id cannot be used anymore to receive sync or
642 * async notifications, you need to create a new #GstClockID.
647 gst_clock_id_unschedule (GstClockID id)
649 GstClockEntry *entry;
651 GstClockClass *cclass;
653 g_return_if_fail (id != NULL);
655 entry = (GstClockEntry *) id;
656 clock = entry->clock;
658 cclass = GST_CLOCK_GET_CLASS (clock);
660 if (G_LIKELY (cclass->unschedule))
661 cclass->unschedule (clock, entry);
666 * GstClock abstract base class implementation
668 #define gst_clock_parent_class parent_class
669 G_DEFINE_ABSTRACT_TYPE (GstClock, gst_clock, GST_TYPE_OBJECT);
672 gst_clock_class_init (GstClockClass * klass)
674 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
676 #ifndef GST_DISABLE_TRACE
677 _gst_clock_entry_trace = _gst_alloc_trace_register ("GstClockEntry", -1);
680 gobject_class->dispose = gst_clock_dispose;
681 gobject_class->finalize = gst_clock_finalize;
682 gobject_class->set_property = gst_clock_set_property;
683 gobject_class->get_property = gst_clock_get_property;
685 g_object_class_install_property (gobject_class, PROP_WINDOW_SIZE,
686 g_param_spec_int ("window-size", "Window size",
687 "The size of the window used to calculate rate and offset", 2, 1024,
688 DEFAULT_WINDOW_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
689 g_object_class_install_property (gobject_class, PROP_WINDOW_THRESHOLD,
690 g_param_spec_int ("window-threshold", "Window threshold",
691 "The threshold to start calculating rate and offset", 2, 1024,
692 DEFAULT_WINDOW_THRESHOLD,
693 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
694 g_object_class_install_property (gobject_class, PROP_TIMEOUT,
695 g_param_spec_uint64 ("timeout", "Timeout",
696 "The amount of time, in nanoseconds, to sample master and slave clocks",
697 0, G_MAXUINT64, DEFAULT_TIMEOUT,
698 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
700 g_type_class_add_private (klass, sizeof (GstClockPrivate));
704 gst_clock_init (GstClock * clock)
706 GstClockPrivate *priv;
709 G_TYPE_INSTANCE_GET_PRIVATE (clock, GST_TYPE_CLOCK, GstClockPrivate);
713 priv->internal_calibration = 0;
714 priv->external_calibration = 0;
715 priv->rate_numerator = 1;
716 priv->rate_denominator = 1;
718 g_mutex_init (&priv->slave_lock);
719 priv->window_size = DEFAULT_WINDOW_SIZE;
720 priv->window_threshold = DEFAULT_WINDOW_THRESHOLD;
721 priv->filling = TRUE;
722 priv->time_index = 0;
723 priv->timeout = DEFAULT_TIMEOUT;
724 priv->times = g_new0 (GstClockTime, 4 * priv->window_size);
726 /* clear floating flag */
727 gst_object_ref_sink (clock);
731 gst_clock_dispose (GObject * object)
733 GstClock *clock = GST_CLOCK (object);
736 GST_OBJECT_LOCK (clock);
737 master_p = &clock->priv->master;
738 gst_object_replace ((GstObject **) master_p, NULL);
739 GST_OBJECT_UNLOCK (clock);
741 G_OBJECT_CLASS (parent_class)->dispose (object);
745 gst_clock_finalize (GObject * object)
747 GstClock *clock = GST_CLOCK (object);
749 GST_CLOCK_SLAVE_LOCK (clock);
750 if (clock->priv->clockid) {
751 gst_clock_id_unschedule (clock->priv->clockid);
752 gst_clock_id_unref (clock->priv->clockid);
753 clock->priv->clockid = NULL;
755 g_free (clock->priv->times);
756 clock->priv->times = NULL;
757 GST_CLOCK_SLAVE_UNLOCK (clock);
759 g_mutex_clear (&clock->priv->slave_lock);
761 G_OBJECT_CLASS (parent_class)->finalize (object);
765 * gst_clock_set_resolution:
766 * @clock: a #GstClock
767 * @resolution: The resolution to set
769 * Set the accuracy of the clock. Some clocks have the possibility to operate
770 * with different accuracy at the expense of more resource usage. There is
771 * normally no need to change the default resolution of a clock. The resolution
772 * of a clock can only be changed if the clock has the
773 * #GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set.
775 * Returns: the new resolution of the clock.
778 gst_clock_set_resolution (GstClock * clock, GstClockTime resolution)
780 GstClockPrivate *priv;
781 GstClockClass *cclass;
783 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
784 g_return_val_if_fail (resolution != 0, 0);
786 cclass = GST_CLOCK_GET_CLASS (clock);
789 if (cclass->change_resolution)
791 cclass->change_resolution (clock, priv->resolution, resolution);
793 return priv->resolution;
797 * gst_clock_get_resolution:
798 * @clock: a #GstClock
800 * Get the accuracy of the clock. The accuracy of the clock is the granularity
801 * of the values returned by gst_clock_get_time().
803 * Returns: the resolution of the clock in units of #GstClockTime.
808 gst_clock_get_resolution (GstClock * clock)
810 GstClockClass *cclass;
812 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
814 cclass = GST_CLOCK_GET_CLASS (clock);
816 if (cclass->get_resolution)
817 return cclass->get_resolution (clock);
823 * gst_clock_adjust_unlocked:
824 * @clock: a #GstClock to use
825 * @internal: a clock time
827 * Converts the given @internal clock time to the external time, adjusting for the
828 * rate and reference time set with gst_clock_set_calibration() and making sure
829 * that the returned time is increasing. This function should be called with the
830 * clock's OBJECT_LOCK held and is mainly used by clock subclasses.
832 * This function is the reverse of gst_clock_unadjust_unlocked().
834 * Returns: the converted time of the clock.
837 gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
839 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
840 GstClockPrivate *priv = clock->priv;
842 /* get calibration values for readability */
843 cinternal = priv->internal_calibration;
844 cexternal = priv->external_calibration;
845 cnum = priv->rate_numerator;
846 cdenom = priv->rate_denominator;
848 /* avoid divide by 0 */
849 if (G_UNLIKELY (cdenom == 0))
852 /* The formula is (internal - cinternal) * cnum / cdenom + cexternal
854 * Since we do math on unsigned 64-bit ints we have to special case for
855 * internal < cinternal to get the sign right. this case is not very common,
858 if (G_LIKELY (internal >= cinternal)) {
859 ret = internal - cinternal;
860 ret = gst_util_uint64_scale (ret, cnum, cdenom);
863 ret = cinternal - internal;
864 ret = gst_util_uint64_scale (ret, cnum, cdenom);
866 if (G_LIKELY (cexternal > ret))
867 ret = cexternal - ret;
872 /* make sure the time is increasing */
873 priv->last_time = MAX (ret, priv->last_time);
875 return priv->last_time;
879 * gst_clock_unadjust_unlocked:
880 * @clock: a #GstClock to use
881 * @external: an external clock time
883 * Converts the given @external clock time to the internal time of @clock,
884 * using the rate and reference time set with gst_clock_set_calibration().
885 * This function should be called with the clock's OBJECT_LOCK held and
886 * is mainly used by clock subclasses.
888 * This function is the reverse of gst_clock_adjust_unlocked().
890 * Returns: the internal time of the clock corresponding to @external.
893 gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external)
895 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
896 GstClockPrivate *priv = clock->priv;
898 /* get calibration values for readability */
899 cinternal = priv->internal_calibration;
900 cexternal = priv->external_calibration;
901 cnum = priv->rate_numerator;
902 cdenom = priv->rate_denominator;
904 /* avoid divide by 0 */
905 if (G_UNLIKELY (cnum == 0))
908 /* The formula is (external - cexternal) * cdenom / cnum + cinternal */
909 if (G_LIKELY (external >= cexternal)) {
910 ret = external - cexternal;
911 ret = gst_util_uint64_scale (ret, cdenom, cnum);
914 ret = cexternal - external;
915 ret = gst_util_uint64_scale (ret, cdenom, cnum);
916 if (G_LIKELY (cinternal > ret))
917 ret = cinternal - ret;
925 * gst_clock_get_internal_time:
926 * @clock: a #GstClock to query
928 * Gets the current internal time of the given clock. The time is returned
929 * unadjusted for the offset and the rate.
931 * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
932 * given invalid input.
937 gst_clock_get_internal_time (GstClock * clock)
940 GstClockClass *cclass;
942 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
944 cclass = GST_CLOCK_GET_CLASS (clock);
946 if (G_UNLIKELY (cclass->get_internal_time == NULL))
949 ret = cclass->get_internal_time (clock);
951 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
952 GST_TIME_ARGS (ret));
959 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
960 "internal time not supported, return 0");
961 return G_GINT64_CONSTANT (0);
966 * gst_clock_get_time:
967 * @clock: a #GstClock to query
969 * Gets the current time of the given clock. The time is always
970 * monotonically increasing and adjusted according to the current
973 * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when
974 * given invalid input.
979 gst_clock_get_time (GstClock * clock)
984 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
987 /* reget the internal time when we retry to get the most current
989 ret = gst_clock_get_internal_time (clock);
991 seq = read_seqbegin (clock);
992 /* this will scale for rate and offset */
993 ret = gst_clock_adjust_unlocked (clock, ret);
994 } while (read_seqretry (clock, seq));
996 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "adjusted time %" GST_TIME_FORMAT,
997 GST_TIME_ARGS (ret));
1003 * gst_clock_set_calibration:
1004 * @clock: a #GstClock to calibrate
1005 * @internal: a reference internal time
1006 * @external: a reference external time
1007 * @rate_num: the numerator of the rate of the clock relative to its
1009 * @rate_denom: the denominator of the rate of the clock
1011 * Adjusts the rate and time of @clock. A rate of 1/1 is the normal speed of
1012 * the clock. Values bigger than 1/1 make the clock go faster.
1014 * @internal and @external are calibration parameters that arrange that
1015 * gst_clock_get_time() should have been @external at internal time @internal.
1016 * This internal time should not be in the future; that is, it should be less
1017 * than the value of gst_clock_get_internal_time() when this function is called.
1019 * Subsequent calls to gst_clock_get_time() will return clock times computed as
1023 * time = (internal_time - internal) * rate_num / rate_denom + external
1026 * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
1027 * tries to do the integer arithmetic as precisely as possible.
1029 * Note that gst_clock_get_time() always returns increasing values so when you
1030 * move the clock backwards, gst_clock_get_time() will report the previous value
1031 * until the clock catches up.
1036 gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
1037 external, GstClockTime rate_num, GstClockTime rate_denom)
1039 GstClockPrivate *priv;
1041 g_return_if_fail (GST_IS_CLOCK (clock));
1042 g_return_if_fail (rate_num != GST_CLOCK_TIME_NONE);
1043 g_return_if_fail (rate_denom > 0 && rate_denom != GST_CLOCK_TIME_NONE);
1047 write_seqlock (clock);
1048 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1049 "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT " %"
1050 G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f", GST_TIME_ARGS (internal),
1051 GST_TIME_ARGS (external), rate_num, rate_denom,
1052 gst_guint64_to_gdouble (rate_num) / gst_guint64_to_gdouble (rate_denom));
1054 priv->internal_calibration = internal;
1055 priv->external_calibration = external;
1056 priv->rate_numerator = rate_num;
1057 priv->rate_denominator = rate_denom;
1058 write_sequnlock (clock);
1062 * gst_clock_get_calibration:
1063 * @clock: a #GstClock
1064 * @internal: (out) (allow-none): a location to store the internal time
1065 * @external: (out) (allow-none): a location to store the external time
1066 * @rate_num: (out) (allow-none): a location to store the rate numerator
1067 * @rate_denom: (out) (allow-none): a location to store the rate denominator
1069 * Gets the internal rate and reference time of @clock. See
1070 * gst_clock_set_calibration() for more information.
1072 * @internal, @external, @rate_num, and @rate_denom can be left %NULL if the
1073 * caller is not interested in the values.
1078 gst_clock_get_calibration (GstClock * clock, GstClockTime * internal,
1079 GstClockTime * external, GstClockTime * rate_num, GstClockTime * rate_denom)
1082 GstClockPrivate *priv;
1084 g_return_if_fail (GST_IS_CLOCK (clock));
1089 seq = read_seqbegin (clock);
1091 *rate_num = priv->rate_numerator;
1093 *rate_denom = priv->rate_denominator;
1095 *external = priv->external_calibration;
1097 *internal = priv->internal_calibration;
1098 } while (read_seqretry (clock, seq));
1101 /* will be called repeatedly to sample the master and slave clock
1102 * to recalibrate the clock */
1104 gst_clock_slave_callback (GstClock * master, GstClockTime time,
1105 GstClockID id, GstClock * clock)
1107 GstClockTime stime, mtime;
1110 stime = gst_clock_get_internal_time (clock);
1111 mtime = gst_clock_get_time (master);
1113 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1114 "master %" GST_TIME_FORMAT ", slave %" GST_TIME_FORMAT,
1115 GST_TIME_ARGS (mtime), GST_TIME_ARGS (stime));
1117 gst_clock_add_observation (clock, stime, mtime, &r_squared);
1119 /* FIXME, we can use the r_squared value to adjust the timeout
1120 * value of the clockid */
1126 * gst_clock_set_master:
1127 * @clock: a #GstClock
1128 * @master: (allow-none): a master #GstClock
1130 * Set @master as the master clock for @clock. @clock will be automatically
1131 * calibrated so that gst_clock_get_time() reports the same time as the
1134 * A clock provider that slaves its clock to a master can get the current
1135 * calibration values with gst_clock_get_calibration().
1137 * @master can be %NULL in which case @clock will not be slaved anymore. It will
1138 * however keep reporting its time adjusted with the last configured rate
1141 * Returns: %TRUE if the clock is capable of being slaved to a master clock.
1142 * Trying to set a master on a clock without the
1143 * #GST_CLOCK_FLAG_CAN_SET_MASTER flag will make this function return %FALSE.
1148 gst_clock_set_master (GstClock * clock, GstClock * master)
1150 GstClock **master_p;
1151 GstClockPrivate *priv;
1153 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1154 g_return_val_if_fail (master != clock, FALSE);
1156 GST_OBJECT_LOCK (clock);
1157 /* we always allow setting the master to NULL */
1158 if (master && !GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER))
1160 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1161 "slaving %p to master clock %p", clock, master);
1162 GST_OBJECT_UNLOCK (clock);
1166 GST_CLOCK_SLAVE_LOCK (clock);
1167 if (priv->clockid) {
1168 gst_clock_id_unschedule (priv->clockid);
1169 gst_clock_id_unref (priv->clockid);
1170 priv->clockid = NULL;
1173 priv->filling = TRUE;
1174 priv->time_index = 0;
1175 /* use the master periodic id to schedule sampling and
1176 * clock calibration. */
1177 priv->clockid = gst_clock_new_periodic_id (master,
1178 gst_clock_get_time (master), priv->timeout);
1179 gst_clock_id_wait_async (priv->clockid,
1180 (GstClockCallback) gst_clock_slave_callback,
1181 gst_object_ref (clock), (GDestroyNotify) gst_object_unref);
1183 GST_CLOCK_SLAVE_UNLOCK (clock);
1185 GST_OBJECT_LOCK (clock);
1186 master_p = &priv->master;
1187 gst_object_replace ((GstObject **) master_p, (GstObject *) master);
1188 GST_OBJECT_UNLOCK (clock);
1195 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1196 "cannot be slaved to a master clock");
1197 GST_OBJECT_UNLOCK (clock);
1203 * gst_clock_get_master:
1204 * @clock: a #GstClock
1206 * Get the master clock that @clock is slaved to or %NULL when the clock is
1207 * not slaved to any master clock.
1209 * Returns: (transfer full): a master #GstClock or %NULL when this clock is
1210 * not slaved to a master clock. Unref after usage.
1215 gst_clock_get_master (GstClock * clock)
1217 GstClock *result = NULL;
1218 GstClockPrivate *priv;
1220 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
1224 GST_OBJECT_LOCK (clock);
1226 result = gst_object_ref (priv->master);
1227 GST_OBJECT_UNLOCK (clock);
1232 /* http://mathworld.wolfram.com/LeastSquaresFitting.html
1236 do_linear_regression (GstClock * clock, GstClockTime * m_num,
1237 GstClockTime * m_denom, GstClockTime * b, GstClockTime * xbase,
1238 gdouble * r_squared)
1240 GstClockTime *newx, *newy;
1241 GstClockTime xmin, ymin, xbar, ybar, xbar4, ybar4;
1242 GstClockTimeDiff sxx, sxy, syy;
1243 GstClockTime *x, *y;
1246 GstClockPrivate *priv;
1248 xbar = ybar = sxx = syy = sxy = 0;
1253 y = priv->times + 2;
1254 n = priv->filling ? priv->time_index : priv->window_size;
1256 #ifdef DEBUGGING_ENABLED
1257 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "doing regression on:");
1258 for (i = j = 0; i < n; i++, j += 4)
1259 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1260 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, x[j], y[j]);
1263 xmin = ymin = G_MAXUINT64;
1264 for (i = j = 0; i < n; i++, j += 4) {
1265 xmin = MIN (xmin, x[j]);
1266 ymin = MIN (ymin, y[j]);
1269 #ifdef DEBUGGING_ENABLED
1270 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min x: %" G_GUINT64_FORMAT,
1272 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min y: %" G_GUINT64_FORMAT,
1276 newx = priv->times + 1;
1277 newy = priv->times + 3;
1279 /* strip off unnecessary bits of precision */
1280 for (i = j = 0; i < n; i++, j += 4) {
1281 newx[j] = x[j] - xmin;
1282 newy[j] = y[j] - ymin;
1285 #ifdef DEBUGGING_ENABLED
1286 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "reduced numbers:");
1287 for (i = j = 0; i < n; i++, j += 4)
1288 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1289 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, newx[j], newy[j]);
1292 /* have to do this precisely otherwise the results are pretty much useless.
1293 * should guarantee that none of these accumulators can overflow */
1295 /* quantities on the order of 1e10 -> 30 bits; window size a max of 2^10, so
1296 this addition could end up around 2^40 or so -- ample headroom */
1297 for (i = j = 0; i < n; i++, j += 4) {
1304 #ifdef DEBUGGING_ENABLED
1305 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbar = %" G_GUINT64_FORMAT,
1307 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " ybar = %" G_GUINT64_FORMAT,
1311 /* multiplying directly would give quantities on the order of 1e20 -> 60 bits;
1312 times the window size that's 70 which is too much. Instead we (1) subtract
1313 off the xbar*ybar in the loop instead of after, to avoid accumulation; (2)
1314 shift off 4 bits from each multiplicand, giving an expected ceiling of 52
1315 bits, which should be enough. Need to check the incoming range and domain
1316 to ensure this is an appropriate loss of precision though. */
1319 for (i = j = 0; i < n; i++, j += 4) {
1320 GstClockTime newx4, newy4;
1322 newx4 = newx[j] >> 4;
1323 newy4 = newy[j] >> 4;
1325 sxx += newx4 * newx4 - xbar4 * xbar4;
1326 syy += newy4 * newy4 - ybar4 * ybar4;
1327 sxy += newx4 * newy4 - xbar4 * ybar4;
1330 if (G_UNLIKELY (sxx == 0))
1336 *b = (ybar + ymin) - gst_util_uint64_scale (xbar, *m_num, *m_denom);
1337 *r_squared = ((double) sxy * (double) sxy) / ((double) sxx * (double) syy);
1339 #ifdef DEBUGGING_ENABLED
1340 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " m = %g",
1341 ((double) *m_num) / *m_denom);
1342 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " b = %" G_GUINT64_FORMAT,
1344 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbase = %" G_GUINT64_FORMAT,
1346 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " r2 = %g", *r_squared);
1353 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "sxx == 0, regression failed");
1359 * gst_clock_add_observation:
1360 * @clock: a #GstClock
1361 * @slave: a time on the slave
1362 * @master: a time on the master
1363 * @r_squared: (out): a pointer to hold the result
1365 * The time @master of the master clock and the time @slave of the slave
1366 * clock are added to the list of observations. If enough observations
1367 * are available, a linear regression algorithm is run on the
1368 * observations and @clock is recalibrated.
1370 * If this functions returns %TRUE, @r_squared will contain the
1371 * correlation coefficient of the interpolation. A value of 1.0
1372 * means a perfect regression was performed. This value can
1373 * be used to control the sampling frequency of the master and slave
1376 * Returns: %TRUE if enough observations were added to run the
1377 * regression algorithm.
1382 gst_clock_add_observation (GstClock * clock, GstClockTime slave,
1383 GstClockTime master, gdouble * r_squared)
1385 GstClockTime m_num, m_denom, b, xbase;
1386 GstClockPrivate *priv;
1388 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1389 g_return_val_if_fail (r_squared != NULL, FALSE);
1393 GST_CLOCK_SLAVE_LOCK (clock);
1395 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1396 "adding observation slave %" GST_TIME_FORMAT ", master %" GST_TIME_FORMAT,
1397 GST_TIME_ARGS (slave), GST_TIME_ARGS (master));
1399 priv->times[(4 * priv->time_index)] = slave;
1400 priv->times[(4 * priv->time_index) + 2] = master;
1403 if (G_UNLIKELY (priv->time_index == priv->window_size)) {
1404 priv->filling = FALSE;
1405 priv->time_index = 0;
1408 if (G_UNLIKELY (priv->filling && priv->time_index < priv->window_threshold))
1411 if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared))
1414 GST_CLOCK_SLAVE_UNLOCK (clock);
1416 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1417 "adjusting clock to m=%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT ", b=%"
1418 G_GUINT64_FORMAT " (rsquared=%g)", m_num, m_denom, b, *r_squared);
1420 /* if we have a valid regression, adjust the clock */
1421 gst_clock_set_calibration (clock, xbase, b, m_num, m_denom);
1427 GST_CLOCK_SLAVE_UNLOCK (clock);
1432 /* no valid regression has been done, ignore the result then */
1433 GST_CLOCK_SLAVE_UNLOCK (clock);
1439 * gst_clock_set_timeout:
1440 * @clock: a #GstClock
1441 * @timeout: a timeout
1443 * Set the amount of time, in nanoseconds, to sample master and slave
1447 gst_clock_set_timeout (GstClock * clock, GstClockTime timeout)
1449 g_return_if_fail (GST_IS_CLOCK (clock));
1451 GST_CLOCK_SLAVE_LOCK (clock);
1452 clock->priv->timeout = timeout;
1453 GST_CLOCK_SLAVE_UNLOCK (clock);
1457 * gst_clock_get_timeout:
1458 * @clock: a #GstClock
1460 * Get the amount of time that master and slave clocks are sampled.
1462 * Returns: the interval between samples.
1465 gst_clock_get_timeout (GstClock * clock)
1467 GstClockTime result;
1469 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
1471 GST_CLOCK_SLAVE_LOCK (clock);
1472 result = clock->priv->timeout;
1473 GST_CLOCK_SLAVE_UNLOCK (clock);
1479 gst_clock_set_property (GObject * object, guint prop_id,
1480 const GValue * value, GParamSpec * pspec)
1483 GstClockPrivate *priv;
1485 clock = GST_CLOCK (object);
1489 case PROP_WINDOW_SIZE:
1490 GST_CLOCK_SLAVE_LOCK (clock);
1491 priv->window_size = g_value_get_int (value);
1492 priv->window_threshold = MIN (priv->window_threshold, priv->window_size);
1493 priv->times = g_renew (GstClockTime, priv->times, 4 * priv->window_size);
1494 /* restart calibration */
1495 priv->filling = TRUE;
1496 priv->time_index = 0;
1497 GST_CLOCK_SLAVE_UNLOCK (clock);
1499 case PROP_WINDOW_THRESHOLD:
1500 GST_CLOCK_SLAVE_LOCK (clock);
1501 priv->window_threshold = MIN (g_value_get_int (value), priv->window_size);
1502 GST_CLOCK_SLAVE_UNLOCK (clock);
1505 gst_clock_set_timeout (clock, g_value_get_uint64 (value));
1508 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1514 gst_clock_get_property (GObject * object, guint prop_id,
1515 GValue * value, GParamSpec * pspec)
1518 GstClockPrivate *priv;
1520 clock = GST_CLOCK (object);
1524 case PROP_WINDOW_SIZE:
1525 GST_CLOCK_SLAVE_LOCK (clock);
1526 g_value_set_int (value, priv->window_size);
1527 GST_CLOCK_SLAVE_UNLOCK (clock);
1529 case PROP_WINDOW_THRESHOLD:
1530 GST_CLOCK_SLAVE_LOCK (clock);
1531 g_value_set_int (value, priv->window_threshold);
1532 GST_CLOCK_SLAVE_UNLOCK (clock);
1535 g_value_set_uint64 (value, gst_clock_get_timeout (clock));
1538 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);