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"
113 #ifndef GST_DISABLE_TRACE
114 /* #define GST_WITH_ALLOC_TRACE */
115 #include "gsttrace.h"
116 static GstAllocTrace *_gst_clock_entry_trace;
119 /* #define DEBUGGING_ENABLED */
121 #define DEFAULT_STATS FALSE
122 #define DEFAULT_WINDOW_SIZE 32
123 #define DEFAULT_WINDOW_THRESHOLD 4
124 #define DEFAULT_TIMEOUT GST_SECOND / 10
131 PROP_WINDOW_THRESHOLD,
135 struct _GstClockPrivate
142 #define read_seqbegin(clock) \
143 g_atomic_int_get (&clock->ABI.priv->post_count);
145 static inline gboolean
146 read_seqretry (GstClock * clock, gint seq)
148 /* no retry if the seqnum did not change */
149 if (G_LIKELY (seq == g_atomic_int_get (&clock->ABI.priv->pre_count)))
152 /* wait for the writer to finish and retry */
153 GST_OBJECT_LOCK (clock);
154 GST_OBJECT_UNLOCK (clock);
158 #define write_seqlock(clock) \
160 GST_OBJECT_LOCK (clock); \
161 g_atomic_int_inc (&clock->ABI.priv->pre_count); \
164 #define write_sequnlock(clock) \
166 g_atomic_int_inc (&clock->ABI.priv->post_count); \
167 GST_OBJECT_UNLOCK (clock); \
170 static void gst_clock_dispose (GObject * object);
171 static void gst_clock_finalize (GObject * object);
173 static void gst_clock_set_property (GObject * object, guint prop_id,
174 const GValue * value, GParamSpec * pspec);
175 static void gst_clock_get_property (GObject * object, guint prop_id,
176 GValue * value, GParamSpec * pspec);
177 static void gst_clock_update_stats (GstClock * clock);
180 /* static guint gst_clock_signals[LAST_SIGNAL] = { 0 }; */
183 gst_clock_entry_new (GstClock * clock, GstClockTime time,
184 GstClockTime interval, GstClockEntryType type)
186 GstClockEntry *entry;
188 entry = g_slice_new (GstClockEntry);
189 #ifndef GST_DISABLE_TRACE
190 gst_alloc_trace_new (_gst_clock_entry_trace, entry);
192 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
193 "created entry %p, time %" GST_TIME_FORMAT, entry, GST_TIME_ARGS (time));
196 entry->clock = clock;
199 entry->interval = interval;
200 entry->status = GST_CLOCK_OK;
202 entry->user_data = NULL;
203 entry->destroy_data = NULL;
204 entry->unscheduled = FALSE;
205 entry->woken_up = FALSE;
207 return (GstClockID) entry;
210 /* WARNING : Does not modify the refcount
211 * WARNING : Do not use if a pending clock operation is happening on that entry */
213 gst_clock_entry_reinit (GstClock * clock, GstClockEntry * entry,
214 GstClockTime time, GstClockTime interval, GstClockEntryType type)
216 g_return_val_if_fail (entry->status != GST_CLOCK_BUSY, FALSE);
217 g_return_val_if_fail (entry->clock == clock, FALSE);
221 entry->interval = interval;
222 entry->status = GST_CLOCK_OK;
223 entry->unscheduled = FALSE;
224 entry->woken_up = FALSE;
230 * gst_clock_single_shot_id_reinit:
231 * @clock: a #GstClock
233 * @time: The requested time.
235 * Reinitializes the provided single shot @id to the provided time. Does not
236 * modify the reference count.
238 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
239 * @time, else %FALSE.
244 gst_clock_single_shot_id_reinit (GstClock * clock, GstClockID id,
247 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, time,
248 GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
252 * gst_clock_periodic_id_reinit:
253 * @clock: a #GstClock
255 * @start_time: the requested start time
256 * @interval: the requested interval
258 * Reinitializes the provided periodic @id to the provided start time and
259 * interval. Does not modify the reference count.
261 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
262 * @time, else %FALSE.
268 gst_clock_periodic_id_reinit (GstClock * clock, GstClockID id,
269 GstClockTime start_time, GstClockTime interval)
271 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, start_time,
272 interval, GST_CLOCK_ENTRY_PERIODIC);
277 * @id: The #GstClockID to ref
279 * Increase the refcount of given @id.
281 * Returns: (transfer full): The same #GstClockID with increased refcount.
286 gst_clock_id_ref (GstClockID id)
288 g_return_val_if_fail (id != NULL, NULL);
290 g_atomic_int_inc (&((GstClockEntry *) id)->refcount);
296 _gst_clock_id_free (GstClockID id)
298 GstClockEntry *entry;
299 g_return_if_fail (id != NULL);
301 GST_CAT_DEBUG (GST_CAT_CLOCK, "freed entry %p", id);
302 entry = (GstClockEntry *) id;
303 if (entry->destroy_data)
304 entry->destroy_data (entry->user_data);
306 #ifndef GST_DISABLE_TRACE
307 gst_alloc_trace_free (_gst_clock_entry_trace, id);
309 g_slice_free (GstClockEntry, id);
313 * gst_clock_id_unref:
314 * @id: (transfer full): The #GstClockID to unref
316 * Unref given @id. When the refcount reaches 0 the
317 * #GstClockID will be freed.
322 gst_clock_id_unref (GstClockID id)
326 g_return_if_fail (id != NULL);
328 zero = g_atomic_int_dec_and_test (&((GstClockEntry *) id)->refcount);
329 /* if we ended up with the refcount at zero, free the id */
331 _gst_clock_id_free (id);
336 * gst_clock_new_single_shot_id:
337 * @clock: The #GstClockID to get a single shot notification from
338 * @time: the requested time
340 * Get a #GstClockID from @clock to trigger a single shot
341 * notification at the requested time. The single shot id should be
342 * unreffed after usage.
344 * Free-function: gst_clock_id_unref
346 * Returns: (transfer full): a #GstClockID that can be used to request the
352 gst_clock_new_single_shot_id (GstClock * clock, GstClockTime time)
354 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
356 return gst_clock_entry_new (clock,
357 time, GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
361 * gst_clock_new_periodic_id:
362 * @clock: The #GstClockID to get a periodic notification id from
363 * @start_time: the requested start time
364 * @interval: the requested interval
366 * Get an ID from @clock to trigger a periodic notification.
367 * The periodic notifications will start at time @start_time and
368 * will then be fired with the given @interval. @id should be unreffed
371 * Free-function: gst_clock_id_unref
373 * Returns: (transfer full): a #GstClockID that can be used to request the
379 gst_clock_new_periodic_id (GstClock * clock, GstClockTime start_time,
380 GstClockTime interval)
382 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
383 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (start_time), NULL);
384 g_return_val_if_fail (interval != 0, NULL);
385 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), NULL);
387 return gst_clock_entry_new (clock,
388 start_time, interval, GST_CLOCK_ENTRY_PERIODIC);
392 * gst_clock_id_compare_func
393 * @id1: A #GstClockID
394 * @id2: A #GstClockID to compare with
396 * Compares the two #GstClockID instances. This function can be used
397 * as a GCompareFunc when sorting ids.
399 * Returns: negative value if a < b; zero if a = b; positive value if a > b
404 gst_clock_id_compare_func (gconstpointer id1, gconstpointer id2)
406 GstClockEntry *entry1, *entry2;
408 entry1 = (GstClockEntry *) id1;
409 entry2 = (GstClockEntry *) id2;
411 if (GST_CLOCK_ENTRY_TIME (entry1) > GST_CLOCK_ENTRY_TIME (entry2)) {
414 if (GST_CLOCK_ENTRY_TIME (entry1) < GST_CLOCK_ENTRY_TIME (entry2)) {
421 * gst_clock_id_get_time
422 * @id: The #GstClockID to query
424 * Get the time of the clock ID
426 * Returns: the time of the given clock id.
431 gst_clock_id_get_time (GstClockID id)
433 g_return_val_if_fail (id != NULL, GST_CLOCK_TIME_NONE);
435 return GST_CLOCK_ENTRY_TIME ((GstClockEntry *) id);
440 * @id: The #GstClockID to wait on
441 * @jitter: (out) (allow-none): a pointer that will contain the jitter,
444 * Perform a blocking wait on @id.
445 * @id should have been created with gst_clock_new_single_shot_id()
446 * or gst_clock_new_periodic_id() and should not have been unscheduled
447 * with a call to gst_clock_id_unschedule().
449 * If the @jitter argument is not %NULL and this function returns #GST_CLOCK_OK
450 * or #GST_CLOCK_EARLY, it will contain the difference
451 * against the clock and the time of @id when this method was
453 * Positive values indicate how late @id was relative to the clock
454 * (in which case this function will return #GST_CLOCK_EARLY).
455 * Negative values indicate how much time was spent waiting on the clock
456 * before this function returned.
458 * Returns: the result of the blocking wait. #GST_CLOCK_EARLY will be returned
459 * if the current clock time is past the time of @id, #GST_CLOCK_OK if
460 * @id was scheduled in time. #GST_CLOCK_UNSCHEDULED if @id was
461 * unscheduled with gst_clock_id_unschedule().
466 gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
468 GstClockEntry *entry;
471 GstClockTime requested;
472 GstClockClass *cclass;
474 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
476 entry = (GstClockEntry *) id;
477 requested = GST_CLOCK_ENTRY_TIME (entry);
479 clock = GST_CLOCK_ENTRY_CLOCK (entry);
481 /* can't sync on invalid times */
482 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
485 cclass = GST_CLOCK_GET_CLASS (clock);
487 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);
489 /* if we have a wait_jitter function, use that */
490 if (G_UNLIKELY (cclass->wait == NULL))
493 res = cclass->wait (clock, entry, jitter);
495 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
496 "done waiting entry %p, res: %d", id, res);
498 if (entry->type == GST_CLOCK_ENTRY_PERIODIC)
499 entry->time = requested + entry->interval;
501 if (G_UNLIKELY (clock->stats))
502 gst_clock_update_stats (clock);
509 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
510 "invalid time requested, returning _BADTIME");
511 return GST_CLOCK_BADTIME;
515 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
516 return GST_CLOCK_UNSUPPORTED;
521 * gst_clock_id_wait_async_full:
522 * @id: a #GstClockID to wait on
523 * @func: The callback function
524 * @user_data: User data passed in the callback
525 * @destroy_data: #GDestroyNotify for user_data
527 * Register a callback on the given #GstClockID @id with the given
528 * function and user_data. When passing a #GstClockID with an invalid
529 * time to this function, the callback will be called immediately
530 * with a time set to GST_CLOCK_TIME_NONE. The callback will
531 * be called when the time of @id has been reached.
533 * The callback @func can be invoked from any thread, either provided by the
534 * core or from a streaming thread. The application should be prepared for this.
536 * Returns: the result of the non blocking wait.
543 gst_clock_id_wait_async_full (GstClockID id,
544 GstClockCallback func, gpointer user_data, GDestroyNotify destroy_data)
546 GstClockEntry *entry;
549 GstClockClass *cclass;
550 GstClockTime requested;
552 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
553 g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
555 entry = (GstClockEntry *) id;
556 requested = GST_CLOCK_ENTRY_TIME (entry);
557 clock = GST_CLOCK_ENTRY_CLOCK (entry);
559 /* can't sync on invalid times */
560 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
563 cclass = GST_CLOCK_GET_CLASS (clock);
565 if (G_UNLIKELY (cclass->wait_async == NULL))
569 entry->user_data = user_data;
570 entry->destroy_data = destroy_data;
572 res = cclass->wait_async (clock, entry);
579 (func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
580 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
581 "invalid time requested, returning _BADTIME");
582 return GST_CLOCK_BADTIME;
586 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
587 return GST_CLOCK_UNSUPPORTED;
592 * gst_clock_id_wait_async:
593 * @id: a #GstClockID to wait on
594 * @func: The callback function
595 * @user_data: User data passed in the callback
597 * Register a callback on the given #GstClockID @id with the given
598 * function and user_data. When passing a #GstClockID with an invalid
599 * time to this function, the callback will be called immediately
600 * with a time set to GST_CLOCK_TIME_NONE. The callback will
601 * be called when the time of @id has been reached.
603 * The callback @func can be invoked from any thread, either provided by the
604 * core or from a streaming thread. The application should be prepared for this.
606 * Returns: the result of the non blocking wait.
611 gst_clock_id_wait_async (GstClockID id,
612 GstClockCallback func, gpointer user_data)
614 return gst_clock_id_wait_async_full (id, func, user_data, NULL);
618 * gst_clock_id_unschedule:
619 * @id: The id to unschedule
621 * Cancel an outstanding request with @id. This can either
622 * be an outstanding async notification or a pending sync notification.
623 * After this call, @id cannot be used anymore to receive sync or
624 * async notifications, you need to create a new #GstClockID.
629 gst_clock_id_unschedule (GstClockID id)
631 GstClockEntry *entry;
633 GstClockClass *cclass;
635 g_return_if_fail (id != NULL);
637 entry = (GstClockEntry *) id;
638 clock = entry->clock;
640 cclass = GST_CLOCK_GET_CLASS (clock);
642 if (G_LIKELY (cclass->unschedule))
643 cclass->unschedule (clock, entry);
648 * GstClock abstract base class implementation
650 #define gst_clock_parent_class parent_class
651 G_DEFINE_TYPE (GstClock, gst_clock, GST_TYPE_OBJECT);
654 gst_clock_class_init (GstClockClass * klass)
656 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
658 #ifndef GST_DISABLE_TRACE
659 _gst_clock_entry_trace =
660 gst_alloc_trace_register (GST_CLOCK_ENTRY_TRACE_NAME);
663 gobject_class->dispose = gst_clock_dispose;
664 gobject_class->finalize = gst_clock_finalize;
665 gobject_class->set_property = gst_clock_set_property;
666 gobject_class->get_property = gst_clock_get_property;
668 g_object_class_install_property (gobject_class, PROP_STATS,
669 g_param_spec_boolean ("stats", "Stats",
670 "Enable clock stats (unimplemented)", DEFAULT_STATS,
671 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
672 g_object_class_install_property (gobject_class, PROP_WINDOW_SIZE,
673 g_param_spec_int ("window-size", "Window size",
674 "The size of the window used to calculate rate and offset", 2, 1024,
675 DEFAULT_WINDOW_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
676 g_object_class_install_property (gobject_class, PROP_WINDOW_THRESHOLD,
677 g_param_spec_int ("window-threshold", "Window threshold",
678 "The threshold to start calculating rate and offset", 2, 1024,
679 DEFAULT_WINDOW_THRESHOLD,
680 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
681 g_object_class_install_property (gobject_class, PROP_TIMEOUT,
682 g_param_spec_uint64 ("timeout", "Timeout",
683 "The amount of time, in nanoseconds, to sample master and slave clocks",
684 0, G_MAXUINT64, DEFAULT_TIMEOUT,
685 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
687 g_type_class_add_private (klass, sizeof (GstClockPrivate));
691 gst_clock_init (GstClock * clock)
693 clock->last_time = 0;
694 clock->entries = NULL;
695 clock->entries_changed = g_cond_new ();
696 clock->stats = FALSE;
699 G_TYPE_INSTANCE_GET_PRIVATE (clock, GST_TYPE_CLOCK, GstClockPrivate);
701 clock->internal_calibration = 0;
702 clock->external_calibration = 0;
703 clock->rate_numerator = 1;
704 clock->rate_denominator = 1;
706 clock->slave_lock = g_mutex_new ();
707 clock->window_size = DEFAULT_WINDOW_SIZE;
708 clock->window_threshold = DEFAULT_WINDOW_THRESHOLD;
709 clock->filling = TRUE;
710 clock->time_index = 0;
711 clock->timeout = DEFAULT_TIMEOUT;
712 clock->times = g_new0 (GstClockTime, 4 * clock->window_size);
716 gst_clock_dispose (GObject * object)
718 GstClock *clock = GST_CLOCK (object);
721 GST_OBJECT_LOCK (clock);
722 master_p = &clock->master;
723 gst_object_replace ((GstObject **) master_p, NULL);
724 GST_OBJECT_UNLOCK (clock);
726 G_OBJECT_CLASS (parent_class)->dispose (object);
730 gst_clock_finalize (GObject * object)
732 GstClock *clock = GST_CLOCK (object);
734 GST_CLOCK_SLAVE_LOCK (clock);
735 if (clock->clockid) {
736 gst_clock_id_unschedule (clock->clockid);
737 gst_clock_id_unref (clock->clockid);
738 clock->clockid = NULL;
740 g_free (clock->times);
742 GST_CLOCK_SLAVE_UNLOCK (clock);
744 g_cond_free (clock->entries_changed);
745 g_mutex_free (clock->slave_lock);
747 G_OBJECT_CLASS (parent_class)->finalize (object);
751 * gst_clock_set_resolution
752 * @clock: a #GstClock
753 * @resolution: The resolution to set
755 * Set the accuracy of the clock. Some clocks have the possibility to operate
756 * with different accuracy at the expense of more resource usage. There is
757 * normally no need to change the default resolution of a clock. The resolution
758 * of a clock can only be changed if the clock has the
759 * #GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set.
761 * Returns: the new resolution of the clock.
764 gst_clock_set_resolution (GstClock * clock, GstClockTime resolution)
766 GstClockClass *cclass;
768 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
769 g_return_val_if_fail (resolution != 0, 0);
771 cclass = GST_CLOCK_GET_CLASS (clock);
773 if (cclass->change_resolution)
775 cclass->change_resolution (clock, clock->resolution, resolution);
777 return clock->resolution;
781 * gst_clock_get_resolution
782 * @clock: a #GstClock
784 * Get the accuracy of the clock. The accuracy of the clock is the granularity
785 * of the values returned by gst_clock_get_time().
787 * Returns: the resolution of the clock in units of #GstClockTime.
792 gst_clock_get_resolution (GstClock * clock)
794 GstClockClass *cclass;
796 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
798 cclass = GST_CLOCK_GET_CLASS (clock);
800 if (cclass->get_resolution)
801 return cclass->get_resolution (clock);
807 * gst_clock_adjust_unlocked
808 * @clock: a #GstClock to use
809 * @internal: a clock time
811 * Converts the given @internal clock time to the external time, adjusting for the
812 * rate and reference time set with gst_clock_set_calibration() and making sure
813 * that the returned time is increasing. This function should be called with the
814 * clock's OBJECT_LOCK held and is mainly used by clock subclasses.
816 * This function is the reverse of gst_clock_unadjust_unlocked().
818 * Returns: the converted time of the clock.
821 gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
823 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
825 /* get calibration values for readability */
826 cinternal = clock->internal_calibration;
827 cexternal = clock->external_calibration;
828 cnum = clock->rate_numerator;
829 cdenom = clock->rate_denominator;
831 /* avoid divide by 0 */
832 if (G_UNLIKELY (cdenom == 0))
835 /* The formula is (internal - cinternal) * cnum / cdenom + cexternal
837 * Since we do math on unsigned 64-bit ints we have to special case for
838 * internal < cinternal to get the sign right. this case is not very common,
841 if (G_LIKELY (internal >= cinternal)) {
842 ret = internal - cinternal;
843 ret = gst_util_uint64_scale (ret, cnum, cdenom);
846 ret = cinternal - internal;
847 ret = gst_util_uint64_scale (ret, cnum, cdenom);
849 if (G_LIKELY (cexternal > ret))
850 ret = cexternal - ret;
855 /* make sure the time is increasing */
856 clock->last_time = MAX (ret, clock->last_time);
858 return clock->last_time;
862 * gst_clock_unadjust_unlocked
863 * @clock: a #GstClock to use
864 * @external: an external clock time
866 * Converts the given @external clock time to the internal time of @clock,
867 * using the rate and reference time set with gst_clock_set_calibration().
868 * This function should be called with the clock's OBJECT_LOCK held and
869 * is mainly used by clock subclasses.
871 * This function is the reverse of gst_clock_adjust_unlocked().
873 * Returns: the internal time of the clock corresponding to @external.
878 gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external)
880 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
882 /* get calibration values for readability */
883 cinternal = clock->internal_calibration;
884 cexternal = clock->external_calibration;
885 cnum = clock->rate_numerator;
886 cdenom = clock->rate_denominator;
888 /* avoid divide by 0 */
889 if (G_UNLIKELY (cnum == 0))
892 /* The formula is (external - cexternal) * cdenom / cnum + cinternal */
893 if (G_LIKELY (external >= cexternal)) {
894 ret = external - cexternal;
895 ret = gst_util_uint64_scale (ret, cdenom, cnum);
898 ret = cexternal - external;
899 ret = gst_util_uint64_scale (ret, cdenom, cnum);
900 if (G_LIKELY (cinternal > ret))
901 ret = cinternal - ret;
909 * gst_clock_get_internal_time
910 * @clock: a #GstClock to query
912 * Gets the current internal time of the given clock. The time is returned
913 * unadjusted for the offset and the rate.
915 * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
916 * given invalid input.
921 gst_clock_get_internal_time (GstClock * clock)
924 GstClockClass *cclass;
926 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
928 cclass = GST_CLOCK_GET_CLASS (clock);
930 if (G_UNLIKELY (cclass->get_internal_time == NULL))
933 ret = cclass->get_internal_time (clock);
935 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
936 GST_TIME_ARGS (ret));
943 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
944 "internal time not supported, return 0");
945 return G_GINT64_CONSTANT (0);
951 * @clock: a #GstClock to query
953 * Gets the current time of the given clock. The time is always
954 * monotonically increasing and adjusted according to the current
957 * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when
958 * given invalid input.
963 gst_clock_get_time (GstClock * clock)
968 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
971 /* reget the internal time when we retry to get the most current
973 ret = gst_clock_get_internal_time (clock);
975 seq = read_seqbegin (clock);
976 /* this will scale for rate and offset */
977 ret = gst_clock_adjust_unlocked (clock, ret);
978 } while (read_seqretry (clock, seq));
980 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "adjusted time %" GST_TIME_FORMAT,
981 GST_TIME_ARGS (ret));
987 * gst_clock_set_calibration
988 * @clock: a #GstClock to calibrate
989 * @internal: a reference internal time
990 * @external: a reference external time
991 * @rate_num: the numerator of the rate of the clock relative to its
993 * @rate_denom: the denominator of the rate of the clock
995 * Adjusts the rate and time of @clock. A rate of 1/1 is the normal speed of
996 * the clock. Values bigger than 1/1 make the clock go faster.
998 * @internal and @external are calibration parameters that arrange that
999 * gst_clock_get_time() should have been @external at internal time @internal.
1000 * This internal time should not be in the future; that is, it should be less
1001 * than the value of gst_clock_get_internal_time() when this function is called.
1003 * Subsequent calls to gst_clock_get_time() will return clock times computed as
1007 * time = (internal_time - internal) * rate_num / rate_denom + external
1010 * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
1011 * tries to do the integer arithmetic as precisely as possible.
1013 * Note that gst_clock_get_time() always returns increasing values so when you
1014 * move the clock backwards, gst_clock_get_time() will report the previous value
1015 * until the clock catches up.
1020 gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
1021 external, GstClockTime rate_num, GstClockTime rate_denom)
1023 g_return_if_fail (GST_IS_CLOCK (clock));
1024 g_return_if_fail (rate_num != GST_CLOCK_TIME_NONE);
1025 g_return_if_fail (rate_denom > 0 && rate_denom != GST_CLOCK_TIME_NONE);
1027 write_seqlock (clock);
1028 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1029 "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT " %"
1030 G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f", GST_TIME_ARGS (internal),
1031 GST_TIME_ARGS (external), rate_num, rate_denom,
1032 gst_guint64_to_gdouble (rate_num) / gst_guint64_to_gdouble (rate_denom));
1034 clock->internal_calibration = internal;
1035 clock->external_calibration = external;
1036 clock->rate_numerator = rate_num;
1037 clock->rate_denominator = rate_denom;
1038 write_sequnlock (clock);
1042 * gst_clock_get_calibration
1043 * @clock: a #GstClock
1044 * @internal: (out) (allow-none): a location to store the internal time
1045 * @external: (out) (allow-none): a location to store the external time
1046 * @rate_num: (out) (allow-none): a location to store the rate numerator
1047 * @rate_denom: (out) (allow-none): a location to store the rate denominator
1049 * Gets the internal rate and reference time of @clock. See
1050 * gst_clock_set_calibration() for more information.
1052 * @internal, @external, @rate_num, and @rate_denom can be left %NULL if the
1053 * caller is not interested in the values.
1058 gst_clock_get_calibration (GstClock * clock, GstClockTime * internal,
1059 GstClockTime * external, GstClockTime * rate_num, GstClockTime * rate_denom)
1063 g_return_if_fail (GST_IS_CLOCK (clock));
1066 seq = read_seqbegin (clock);
1068 *rate_num = clock->rate_numerator;
1070 *rate_denom = clock->rate_denominator;
1072 *external = clock->external_calibration;
1074 *internal = clock->internal_calibration;
1075 } while (read_seqretry (clock, seq));
1078 /* will be called repeatedly to sample the master and slave clock
1079 * to recalibrate the clock */
1081 gst_clock_slave_callback (GstClock * master, GstClockTime time,
1082 GstClockID id, GstClock * clock)
1084 GstClockTime stime, mtime;
1087 stime = gst_clock_get_internal_time (clock);
1088 mtime = gst_clock_get_time (master);
1090 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1091 "master %" GST_TIME_FORMAT ", slave %" GST_TIME_FORMAT,
1092 GST_TIME_ARGS (mtime), GST_TIME_ARGS (stime));
1094 gst_clock_add_observation (clock, stime, mtime, &r_squared);
1096 /* FIXME, we can use the r_squared value to adjust the timeout
1097 * value of the clockid */
1103 * gst_clock_set_master
1104 * @clock: a #GstClock
1105 * @master: (allow-none): a master #GstClock
1107 * Set @master as the master clock for @clock. @clock will be automatically
1108 * calibrated so that gst_clock_get_time() reports the same time as the
1111 * A clock provider that slaves its clock to a master can get the current
1112 * calibration values with gst_clock_get_calibration().
1114 * @master can be %NULL in which case @clock will not be slaved anymore. It will
1115 * however keep reporting its time adjusted with the last configured rate
1118 * Returns: %TRUE if the clock is capable of being slaved to a master clock.
1119 * Trying to set a master on a clock without the
1120 * #GST_CLOCK_FLAG_CAN_SET_MASTER flag will make this function return %FALSE.
1125 gst_clock_set_master (GstClock * clock, GstClock * master)
1127 GstClock **master_p;
1129 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1130 g_return_val_if_fail (master != clock, FALSE);
1132 GST_OBJECT_LOCK (clock);
1133 /* we always allow setting the master to NULL */
1134 if (master && !GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER))
1136 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1137 "slaving %p to master clock %p", clock, master);
1138 GST_OBJECT_UNLOCK (clock);
1140 GST_CLOCK_SLAVE_LOCK (clock);
1141 if (clock->clockid) {
1142 gst_clock_id_unschedule (clock->clockid);
1143 gst_clock_id_unref (clock->clockid);
1144 clock->clockid = NULL;
1147 clock->filling = TRUE;
1148 clock->time_index = 0;
1149 /* use the master periodic id to schedule sampling and
1150 * clock calibration. */
1151 clock->clockid = gst_clock_new_periodic_id (master,
1152 gst_clock_get_time (master), clock->timeout);
1153 gst_clock_id_wait_async_full (clock->clockid,
1154 (GstClockCallback) gst_clock_slave_callback,
1155 gst_object_ref (clock), (GDestroyNotify) gst_object_unref);
1157 GST_CLOCK_SLAVE_UNLOCK (clock);
1159 GST_OBJECT_LOCK (clock);
1160 master_p = &clock->master;
1161 gst_object_replace ((GstObject **) master_p, (GstObject *) master);
1162 GST_OBJECT_UNLOCK (clock);
1169 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1170 "cannot be slaved to a master clock");
1171 GST_OBJECT_UNLOCK (clock);
1177 * gst_clock_get_master:
1178 * @clock: a #GstClock
1180 * Get the master clock that @clock is slaved to or %NULL when the clock is
1181 * not slaved to any master clock.
1183 * Returns: (transfer full): a master #GstClock or %NULL when this clock is
1184 * not slaved to a master clock. Unref after usage.
1189 gst_clock_get_master (GstClock * clock)
1191 GstClock *result = NULL;
1193 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
1195 GST_OBJECT_LOCK (clock);
1197 result = gst_object_ref (clock->master);
1198 GST_OBJECT_UNLOCK (clock);
1203 /* http://mathworld.wolfram.com/LeastSquaresFitting.html
1207 do_linear_regression (GstClock * clock, GstClockTime * m_num,
1208 GstClockTime * m_denom, GstClockTime * b, GstClockTime * xbase,
1209 gdouble * r_squared)
1211 GstClockTime *newx, *newy;
1212 GstClockTime xmin, ymin, xbar, ybar, xbar4, ybar4;
1213 GstClockTimeDiff sxx, sxy, syy;
1214 GstClockTime *x, *y;
1218 xbar = ybar = sxx = syy = sxy = 0;
1221 y = clock->times + 2;
1222 n = clock->filling ? clock->time_index : clock->window_size;
1224 #ifdef DEBUGGING_ENABLED
1225 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "doing regression on:");
1226 for (i = j = 0; i < n; i++, j += 4)
1227 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1228 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, x[j], y[j]);
1231 xmin = ymin = G_MAXUINT64;
1232 for (i = j = 0; i < n; i++, j += 4) {
1233 xmin = MIN (xmin, x[j]);
1234 ymin = MIN (ymin, y[j]);
1237 #ifdef DEBUGGING_ENABLED
1238 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min x: %" G_GUINT64_FORMAT,
1240 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min y: %" G_GUINT64_FORMAT,
1244 newx = clock->times + 1;
1245 newy = clock->times + 3;
1247 /* strip off unnecessary bits of precision */
1248 for (i = j = 0; i < n; i++, j += 4) {
1249 newx[j] = x[j] - xmin;
1250 newy[j] = y[j] - ymin;
1253 #ifdef DEBUGGING_ENABLED
1254 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "reduced numbers:");
1255 for (i = j = 0; i < n; i++, j += 4)
1256 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1257 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, newx[j], newy[j]);
1260 /* have to do this precisely otherwise the results are pretty much useless.
1261 * should guarantee that none of these accumulators can overflow */
1263 /* quantities on the order of 1e10 -> 30 bits; window size a max of 2^10, so
1264 this addition could end up around 2^40 or so -- ample headroom */
1265 for (i = j = 0; i < n; i++, j += 4) {
1272 #ifdef DEBUGGING_ENABLED
1273 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbar = %" G_GUINT64_FORMAT,
1275 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " ybar = %" G_GUINT64_FORMAT,
1279 /* multiplying directly would give quantities on the order of 1e20 -> 60 bits;
1280 times the window size that's 70 which is too much. Instead we (1) subtract
1281 off the xbar*ybar in the loop instead of after, to avoid accumulation; (2)
1282 shift off 4 bits from each multiplicand, giving an expected ceiling of 52
1283 bits, which should be enough. Need to check the incoming range and domain
1284 to ensure this is an appropriate loss of precision though. */
1287 for (i = j = 0; i < n; i++, j += 4) {
1288 GstClockTime newx4, newy4;
1290 newx4 = newx[j] >> 4;
1291 newy4 = newy[j] >> 4;
1293 sxx += newx4 * newx4 - xbar4 * xbar4;
1294 syy += newy4 * newy4 - ybar4 * ybar4;
1295 sxy += newx4 * newy4 - xbar4 * ybar4;
1298 if (G_UNLIKELY (sxx == 0))
1304 *b = (ybar + ymin) - gst_util_uint64_scale (xbar, *m_num, *m_denom);
1305 *r_squared = ((double) sxy * (double) sxy) / ((double) sxx * (double) syy);
1307 #ifdef DEBUGGING_ENABLED
1308 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " m = %g",
1309 ((double) *m_num) / *m_denom);
1310 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " b = %" G_GUINT64_FORMAT,
1312 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbase = %" G_GUINT64_FORMAT,
1314 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " r2 = %g", *r_squared);
1321 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "sxx == 0, regression failed");
1327 * gst_clock_add_observation
1328 * @clock: a #GstClock
1329 * @slave: a time on the slave
1330 * @master: a time on the master
1331 * @r_squared: (out): a pointer to hold the result
1333 * The time @master of the master clock and the time @slave of the slave
1334 * clock are added to the list of observations. If enough observations
1335 * are available, a linear regression algorithm is run on the
1336 * observations and @clock is recalibrated.
1338 * If this functions returns %TRUE, @r_squared will contain the
1339 * correlation coefficient of the interpolation. A value of 1.0
1340 * means a perfect regression was performed. This value can
1341 * be used to control the sampling frequency of the master and slave
1344 * Returns: %TRUE if enough observations were added to run the
1345 * regression algorithm.
1350 gst_clock_add_observation (GstClock * clock, GstClockTime slave,
1351 GstClockTime master, gdouble * r_squared)
1353 GstClockTime m_num, m_denom, b, xbase;
1355 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1356 g_return_val_if_fail (r_squared != NULL, FALSE);
1358 GST_CLOCK_SLAVE_LOCK (clock);
1360 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1361 "adding observation slave %" GST_TIME_FORMAT ", master %" GST_TIME_FORMAT,
1362 GST_TIME_ARGS (slave), GST_TIME_ARGS (master));
1364 clock->times[(4 * clock->time_index)] = slave;
1365 clock->times[(4 * clock->time_index) + 2] = master;
1367 clock->time_index++;
1368 if (G_UNLIKELY (clock->time_index == clock->window_size)) {
1369 clock->filling = FALSE;
1370 clock->time_index = 0;
1373 if (G_UNLIKELY (clock->filling
1374 && clock->time_index < clock->window_threshold))
1377 if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared))
1380 GST_CLOCK_SLAVE_UNLOCK (clock);
1382 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1383 "adjusting clock to m=%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT ", b=%"
1384 G_GUINT64_FORMAT " (rsquared=%g)", m_num, m_denom, b, *r_squared);
1386 /* if we have a valid regression, adjust the clock */
1387 gst_clock_set_calibration (clock, xbase, b, m_num, m_denom);
1393 GST_CLOCK_SLAVE_UNLOCK (clock);
1398 /* no valid regression has been done, ignore the result then */
1399 GST_CLOCK_SLAVE_UNLOCK (clock);
1405 gst_clock_update_stats (GstClock * clock)
1410 gst_clock_set_property (GObject * object, guint prop_id,
1411 const GValue * value, GParamSpec * pspec)
1415 clock = GST_CLOCK (object);
1419 GST_OBJECT_LOCK (clock);
1420 clock->stats = g_value_get_boolean (value);
1421 GST_OBJECT_UNLOCK (clock);
1423 case PROP_WINDOW_SIZE:
1424 GST_CLOCK_SLAVE_LOCK (clock);
1425 clock->window_size = g_value_get_int (value);
1426 clock->window_threshold =
1427 MIN (clock->window_threshold, clock->window_size);
1429 g_renew (GstClockTime, clock->times, 4 * clock->window_size);
1430 /* restart calibration */
1431 clock->filling = TRUE;
1432 clock->time_index = 0;
1433 GST_CLOCK_SLAVE_UNLOCK (clock);
1435 case PROP_WINDOW_THRESHOLD:
1436 GST_CLOCK_SLAVE_LOCK (clock);
1437 clock->window_threshold =
1438 MIN (g_value_get_int (value), clock->window_size);
1439 GST_CLOCK_SLAVE_UNLOCK (clock);
1442 GST_CLOCK_SLAVE_LOCK (clock);
1443 clock->timeout = g_value_get_uint64 (value);
1444 GST_CLOCK_SLAVE_UNLOCK (clock);
1447 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1453 gst_clock_get_property (GObject * object, guint prop_id,
1454 GValue * value, GParamSpec * pspec)
1458 clock = GST_CLOCK (object);
1462 GST_OBJECT_LOCK (clock);
1463 g_value_set_boolean (value, clock->stats);
1464 GST_OBJECT_UNLOCK (clock);
1466 case PROP_WINDOW_SIZE:
1467 GST_CLOCK_SLAVE_LOCK (clock);
1468 g_value_set_int (value, clock->window_size);
1469 GST_CLOCK_SLAVE_UNLOCK (clock);
1471 case PROP_WINDOW_THRESHOLD:
1472 GST_CLOCK_SLAVE_LOCK (clock);
1473 g_value_set_int (value, clock->window_threshold);
1474 GST_CLOCK_SLAVE_UNLOCK (clock);
1477 GST_CLOCK_SLAVE_LOCK (clock);
1478 g_value_set_uint64 (value, clock->timeout);
1479 GST_CLOCK_SLAVE_UNLOCK (clock);
1482 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);