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 GstObjectClass *parent_class = NULL;
182 /* static guint gst_clock_signals[LAST_SIGNAL] = { 0 }; */
185 gst_clock_entry_new (GstClock * clock, GstClockTime time,
186 GstClockTime interval, GstClockEntryType type)
188 GstClockEntry *entry;
190 entry = g_slice_new (GstClockEntry);
191 #ifndef GST_DISABLE_TRACE
192 gst_alloc_trace_new (_gst_clock_entry_trace, entry);
194 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
195 "created entry %p, time %" GST_TIME_FORMAT, entry, GST_TIME_ARGS (time));
198 entry->clock = clock;
201 entry->interval = interval;
202 entry->status = GST_CLOCK_OK;
204 entry->user_data = NULL;
205 entry->destroy_data = NULL;
206 entry->unscheduled = FALSE;
207 entry->woken_up = FALSE;
209 return (GstClockID) entry;
212 /* WARNING : Does not modify the refcount
213 * WARNING : Do not use if a pending clock operation is happening on that entry */
215 gst_clock_entry_reinit (GstClock * clock, GstClockEntry * entry,
216 GstClockTime time, GstClockTime interval, GstClockEntryType type)
218 g_return_val_if_fail (entry->status != GST_CLOCK_BUSY, FALSE);
219 g_return_val_if_fail (entry->clock == clock, FALSE);
223 entry->interval = interval;
224 entry->status = GST_CLOCK_OK;
225 entry->unscheduled = FALSE;
226 entry->woken_up = FALSE;
232 * gst_clock_single_shot_id_reinit:
233 * @clock: a #GstClock
235 * @time: The requested time.
237 * Reinitializes the provided single shot @id to the provided time. Does not
238 * modify the reference count.
240 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
241 * @time, else %FALSE.
246 gst_clock_single_shot_id_reinit (GstClock * clock, GstClockID id,
249 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, time,
250 GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
254 * gst_clock_periodic_id_reinit:
255 * @clock: a #GstClock
257 * @start_time: the requested start time
258 * @interval: the requested interval
260 * Reinitializes the provided periodic @id to the provided start time and
261 * interval. Does not modify the reference count.
263 * Returns: %TRUE if the GstClockID could be reinitialized to the provided
264 * @time, else %FALSE.
270 gst_clock_periodic_id_reinit (GstClock * clock, GstClockID id,
271 GstClockTime start_time, GstClockTime interval)
273 return gst_clock_entry_reinit (clock, (GstClockEntry *) id, start_time,
274 interval, GST_CLOCK_ENTRY_PERIODIC);
279 * @id: The #GstClockID to ref
281 * Increase the refcount of given @id.
283 * Returns: (transfer full): The same #GstClockID with increased refcount.
288 gst_clock_id_ref (GstClockID id)
290 g_return_val_if_fail (id != NULL, NULL);
292 g_atomic_int_inc (&((GstClockEntry *) id)->refcount);
298 _gst_clock_id_free (GstClockID id)
300 GstClockEntry *entry;
301 g_return_if_fail (id != NULL);
303 GST_CAT_DEBUG (GST_CAT_CLOCK, "freed entry %p", id);
304 entry = (GstClockEntry *) id;
305 if (entry->destroy_data)
306 entry->destroy_data (entry->user_data);
308 #ifndef GST_DISABLE_TRACE
309 gst_alloc_trace_free (_gst_clock_entry_trace, id);
311 g_slice_free (GstClockEntry, id);
315 * gst_clock_id_unref:
316 * @id: (transfer full): The #GstClockID to unref
318 * Unref given @id. When the refcount reaches 0 the
319 * #GstClockID will be freed.
324 gst_clock_id_unref (GstClockID id)
328 g_return_if_fail (id != NULL);
330 zero = g_atomic_int_dec_and_test (&((GstClockEntry *) id)->refcount);
331 /* if we ended up with the refcount at zero, free the id */
333 _gst_clock_id_free (id);
338 * gst_clock_new_single_shot_id:
339 * @clock: The #GstClockID to get a single shot notification from
340 * @time: the requested time
342 * Get a #GstClockID from @clock to trigger a single shot
343 * notification at the requested time. The single shot id should be
344 * unreffed after usage.
346 * Free-function: gst_clock_id_unref
348 * Returns: (transfer full): a #GstClockID that can be used to request the
354 gst_clock_new_single_shot_id (GstClock * clock, GstClockTime time)
356 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
358 return gst_clock_entry_new (clock,
359 time, GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
363 * gst_clock_new_periodic_id:
364 * @clock: The #GstClockID to get a periodic notification id from
365 * @start_time: the requested start time
366 * @interval: the requested interval
368 * Get an ID from @clock to trigger a periodic notification.
369 * The periodic notifications will start at time @start_time and
370 * will then be fired with the given @interval. @id should be unreffed
373 * Free-function: gst_clock_id_unref
375 * Returns: (transfer full): a #GstClockID that can be used to request the
381 gst_clock_new_periodic_id (GstClock * clock, GstClockTime start_time,
382 GstClockTime interval)
384 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
385 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (start_time), NULL);
386 g_return_val_if_fail (interval != 0, NULL);
387 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), NULL);
389 return gst_clock_entry_new (clock,
390 start_time, interval, GST_CLOCK_ENTRY_PERIODIC);
394 * gst_clock_id_compare_func
395 * @id1: A #GstClockID
396 * @id2: A #GstClockID to compare with
398 * Compares the two #GstClockID instances. This function can be used
399 * as a GCompareFunc when sorting ids.
401 * Returns: negative value if a < b; zero if a = b; positive value if a > b
406 gst_clock_id_compare_func (gconstpointer id1, gconstpointer id2)
408 GstClockEntry *entry1, *entry2;
410 entry1 = (GstClockEntry *) id1;
411 entry2 = (GstClockEntry *) id2;
413 if (GST_CLOCK_ENTRY_TIME (entry1) > GST_CLOCK_ENTRY_TIME (entry2)) {
416 if (GST_CLOCK_ENTRY_TIME (entry1) < GST_CLOCK_ENTRY_TIME (entry2)) {
423 * gst_clock_id_get_time
424 * @id: The #GstClockID to query
426 * Get the time of the clock ID
428 * Returns: the time of the given clock id.
433 gst_clock_id_get_time (GstClockID id)
435 g_return_val_if_fail (id != NULL, GST_CLOCK_TIME_NONE);
437 return GST_CLOCK_ENTRY_TIME ((GstClockEntry *) id);
442 * @id: The #GstClockID to wait on
443 * @jitter: (out) (allow-none): a pointer that will contain the jitter,
446 * Perform a blocking wait on @id.
447 * @id should have been created with gst_clock_new_single_shot_id()
448 * or gst_clock_new_periodic_id() and should not have been unscheduled
449 * with a call to gst_clock_id_unschedule().
451 * If the @jitter argument is not %NULL and this function returns #GST_CLOCK_OK
452 * or #GST_CLOCK_EARLY, it will contain the difference
453 * against the clock and the time of @id when this method was
455 * Positive values indicate how late @id was relative to the clock
456 * (in which case this function will return #GST_CLOCK_EARLY).
457 * Negative values indicate how much time was spent waiting on the clock
458 * before this function returned.
460 * Returns: the result of the blocking wait. #GST_CLOCK_EARLY will be returned
461 * if the current clock time is past the time of @id, #GST_CLOCK_OK if
462 * @id was scheduled in time. #GST_CLOCK_UNSCHEDULED if @id was
463 * unscheduled with gst_clock_id_unschedule().
468 gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
470 GstClockEntry *entry;
473 GstClockTime requested;
474 GstClockClass *cclass;
476 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
478 entry = (GstClockEntry *) id;
479 requested = GST_CLOCK_ENTRY_TIME (entry);
481 clock = GST_CLOCK_ENTRY_CLOCK (entry);
483 /* can't sync on invalid times */
484 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
487 cclass = GST_CLOCK_GET_CLASS (clock);
489 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);
491 /* if we have a wait_jitter function, use that */
492 if (G_LIKELY (cclass->wait_jitter)) {
493 res = cclass->wait_jitter (clock, entry, jitter);
495 /* check if we have a simple _wait function otherwise. The function without
496 * the jitter arg is less optimal as we need to do an additional _get_time()
497 * which is not atomic with the _wait() and a typical _wait() function does
498 * yet another _get_time() anyway. */
499 if (G_UNLIKELY (cclass->wait == NULL))
503 GstClockTime now = gst_clock_get_time (clock);
505 /* jitter is the diff against the clock when this entry is scheduled. Negative
506 * values mean that the entry was in time, a positive value means that the
507 * entry was too late. */
508 *jitter = GST_CLOCK_DIFF (requested, now);
510 res = cclass->wait (clock, entry);
513 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
514 "done waiting entry %p, res: %d", id, res);
516 if (entry->type == GST_CLOCK_ENTRY_PERIODIC)
517 entry->time = requested + entry->interval;
519 if (G_UNLIKELY (clock->stats))
520 gst_clock_update_stats (clock);
527 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
528 "invalid time requested, returning _BADTIME");
529 return GST_CLOCK_BADTIME;
533 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
534 return GST_CLOCK_UNSUPPORTED;
539 * gst_clock_id_wait_async_full:
540 * @id: a #GstClockID to wait on
541 * @func: The callback function
542 * @user_data: User data passed in the callback
543 * @destroy_data: #GDestroyNotify for user_data
545 * Register a callback on the given #GstClockID @id with the given
546 * function and user_data. When passing a #GstClockID with an invalid
547 * time to this function, the callback will be called immediately
548 * with a time set to GST_CLOCK_TIME_NONE. The callback will
549 * be called when the time of @id has been reached.
551 * The callback @func can be invoked from any thread, either provided by the
552 * core or from a streaming thread. The application should be prepared for this.
554 * Returns: the result of the non blocking wait.
561 gst_clock_id_wait_async_full (GstClockID id,
562 GstClockCallback func, gpointer user_data, GDestroyNotify destroy_data)
564 GstClockEntry *entry;
567 GstClockClass *cclass;
568 GstClockTime requested;
570 g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
571 g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
573 entry = (GstClockEntry *) id;
574 requested = GST_CLOCK_ENTRY_TIME (entry);
575 clock = GST_CLOCK_ENTRY_CLOCK (entry);
577 /* can't sync on invalid times */
578 if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
581 cclass = GST_CLOCK_GET_CLASS (clock);
583 if (G_UNLIKELY (cclass->wait_async == NULL))
587 entry->user_data = user_data;
588 entry->destroy_data = destroy_data;
590 res = cclass->wait_async (clock, entry);
597 (func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
598 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
599 "invalid time requested, returning _BADTIME");
600 return GST_CLOCK_BADTIME;
604 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
605 return GST_CLOCK_UNSUPPORTED;
610 * gst_clock_id_wait_async:
611 * @id: a #GstClockID to wait on
612 * @func: The callback function
613 * @user_data: User data passed in the callback
615 * Register a callback on the given #GstClockID @id with the given
616 * function and user_data. When passing a #GstClockID with an invalid
617 * time to this function, the callback will be called immediately
618 * with a time set to GST_CLOCK_TIME_NONE. The callback will
619 * be called when the time of @id has been reached.
621 * The callback @func can be invoked from any thread, either provided by the
622 * core or from a streaming thread. The application should be prepared for this.
624 * Returns: the result of the non blocking wait.
629 gst_clock_id_wait_async (GstClockID id,
630 GstClockCallback func, gpointer user_data)
632 return gst_clock_id_wait_async_full (id, func, user_data, NULL);
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 G_DEFINE_TYPE (GstClock, gst_clock, GST_TYPE_OBJECT);
671 gst_clock_class_init (GstClockClass * klass)
673 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
675 parent_class = g_type_class_peek_parent (klass);
677 #ifndef GST_DISABLE_TRACE
678 _gst_clock_entry_trace =
679 gst_alloc_trace_register (GST_CLOCK_ENTRY_TRACE_NAME);
682 gobject_class->dispose = gst_clock_dispose;
683 gobject_class->finalize = gst_clock_finalize;
684 gobject_class->set_property = gst_clock_set_property;
685 gobject_class->get_property = gst_clock_get_property;
687 g_object_class_install_property (gobject_class, PROP_STATS,
688 g_param_spec_boolean ("stats", "Stats",
689 "Enable clock stats (unimplemented)", DEFAULT_STATS,
690 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
691 g_object_class_install_property (gobject_class, PROP_WINDOW_SIZE,
692 g_param_spec_int ("window-size", "Window size",
693 "The size of the window used to calculate rate and offset", 2, 1024,
694 DEFAULT_WINDOW_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
695 g_object_class_install_property (gobject_class, PROP_WINDOW_THRESHOLD,
696 g_param_spec_int ("window-threshold", "Window threshold",
697 "The threshold to start calculating rate and offset", 2, 1024,
698 DEFAULT_WINDOW_THRESHOLD,
699 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
700 g_object_class_install_property (gobject_class, PROP_TIMEOUT,
701 g_param_spec_uint64 ("timeout", "Timeout",
702 "The amount of time, in nanoseconds, to sample master and slave clocks",
703 0, G_MAXUINT64, DEFAULT_TIMEOUT,
704 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
706 g_type_class_add_private (klass, sizeof (GstClockPrivate));
710 gst_clock_init (GstClock * clock)
712 clock->last_time = 0;
713 clock->entries = NULL;
714 clock->entries_changed = g_cond_new ();
715 clock->stats = FALSE;
718 G_TYPE_INSTANCE_GET_PRIVATE (clock, GST_TYPE_CLOCK, GstClockPrivate);
720 clock->internal_calibration = 0;
721 clock->external_calibration = 0;
722 clock->rate_numerator = 1;
723 clock->rate_denominator = 1;
725 clock->slave_lock = g_mutex_new ();
726 clock->window_size = DEFAULT_WINDOW_SIZE;
727 clock->window_threshold = DEFAULT_WINDOW_THRESHOLD;
728 clock->filling = TRUE;
729 clock->time_index = 0;
730 clock->timeout = DEFAULT_TIMEOUT;
731 clock->times = g_new0 (GstClockTime, 4 * clock->window_size);
735 gst_clock_dispose (GObject * object)
737 GstClock *clock = GST_CLOCK (object);
740 GST_OBJECT_LOCK (clock);
741 master_p = &clock->master;
742 gst_object_replace ((GstObject **) master_p, NULL);
743 GST_OBJECT_UNLOCK (clock);
745 G_OBJECT_CLASS (parent_class)->dispose (object);
749 gst_clock_finalize (GObject * object)
751 GstClock *clock = GST_CLOCK (object);
753 GST_CLOCK_SLAVE_LOCK (clock);
754 if (clock->clockid) {
755 gst_clock_id_unschedule (clock->clockid);
756 gst_clock_id_unref (clock->clockid);
757 clock->clockid = NULL;
759 g_free (clock->times);
761 GST_CLOCK_SLAVE_UNLOCK (clock);
763 g_cond_free (clock->entries_changed);
764 g_mutex_free (clock->slave_lock);
766 G_OBJECT_CLASS (parent_class)->finalize (object);
770 * gst_clock_set_resolution
771 * @clock: a #GstClock
772 * @resolution: The resolution to set
774 * Set the accuracy of the clock. Some clocks have the possibility to operate
775 * with different accuracy at the expense of more resource usage. There is
776 * normally no need to change the default resolution of a clock. The resolution
777 * of a clock can only be changed if the clock has the
778 * #GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set.
780 * Returns: the new resolution of the clock.
783 gst_clock_set_resolution (GstClock * clock, GstClockTime resolution)
785 GstClockClass *cclass;
787 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
788 g_return_val_if_fail (resolution != 0, 0);
790 cclass = GST_CLOCK_GET_CLASS (clock);
792 if (cclass->change_resolution)
794 cclass->change_resolution (clock, clock->resolution, resolution);
796 return clock->resolution;
800 * gst_clock_get_resolution
801 * @clock: a #GstClock
803 * Get the accuracy of the clock. The accuracy of the clock is the granularity
804 * of the values returned by gst_clock_get_time().
806 * Returns: the resolution of the clock in units of #GstClockTime.
811 gst_clock_get_resolution (GstClock * clock)
813 GstClockClass *cclass;
815 g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
817 cclass = GST_CLOCK_GET_CLASS (clock);
819 if (cclass->get_resolution)
820 return cclass->get_resolution (clock);
826 * gst_clock_adjust_unlocked
827 * @clock: a #GstClock to use
828 * @internal: a clock time
830 * Converts the given @internal clock time to the external time, adjusting for the
831 * rate and reference time set with gst_clock_set_calibration() and making sure
832 * that the returned time is increasing. This function should be called with the
833 * clock's OBJECT_LOCK held and is mainly used by clock subclasses.
835 * This function is the reverse of gst_clock_unadjust_unlocked().
837 * Returns: the converted time of the clock.
840 gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
842 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
844 /* get calibration values for readability */
845 cinternal = clock->internal_calibration;
846 cexternal = clock->external_calibration;
847 cnum = clock->rate_numerator;
848 cdenom = clock->rate_denominator;
850 /* avoid divide by 0 */
851 if (G_UNLIKELY (cdenom == 0))
854 /* The formula is (internal - cinternal) * cnum / cdenom + cexternal
856 * Since we do math on unsigned 64-bit ints we have to special case for
857 * internal < cinternal to get the sign right. this case is not very common,
860 if (G_LIKELY (internal >= cinternal)) {
861 ret = internal - cinternal;
862 ret = gst_util_uint64_scale (ret, cnum, cdenom);
865 ret = cinternal - internal;
866 ret = gst_util_uint64_scale (ret, cnum, cdenom);
868 if (G_LIKELY (cexternal > ret))
869 ret = cexternal - ret;
874 /* make sure the time is increasing */
875 clock->last_time = MAX (ret, clock->last_time);
877 return clock->last_time;
881 * gst_clock_unadjust_unlocked
882 * @clock: a #GstClock to use
883 * @external: an external clock time
885 * Converts the given @external clock time to the internal time of @clock,
886 * using the rate and reference time set with gst_clock_set_calibration().
887 * This function should be called with the clock's OBJECT_LOCK held and
888 * is mainly used by clock subclasses.
890 * This function is the reverse of gst_clock_adjust_unlocked().
892 * Returns: the internal time of the clock corresponding to @external.
897 gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external)
899 GstClockTime ret, cinternal, cexternal, cnum, cdenom;
901 /* get calibration values for readability */
902 cinternal = clock->internal_calibration;
903 cexternal = clock->external_calibration;
904 cnum = clock->rate_numerator;
905 cdenom = clock->rate_denominator;
907 /* avoid divide by 0 */
908 if (G_UNLIKELY (cnum == 0))
911 /* The formula is (external - cexternal) * cdenom / cnum + cinternal */
912 if (G_LIKELY (external >= cexternal)) {
913 ret = external - cexternal;
914 ret = gst_util_uint64_scale (ret, cdenom, cnum);
917 ret = cexternal - external;
918 ret = gst_util_uint64_scale (ret, cdenom, cnum);
919 if (G_LIKELY (cinternal > ret))
920 ret = cinternal - ret;
928 * gst_clock_get_internal_time
929 * @clock: a #GstClock to query
931 * Gets the current internal time of the given clock. The time is returned
932 * unadjusted for the offset and the rate.
934 * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
935 * given invalid input.
940 gst_clock_get_internal_time (GstClock * clock)
943 GstClockClass *cclass;
945 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
947 cclass = GST_CLOCK_GET_CLASS (clock);
949 if (G_UNLIKELY (cclass->get_internal_time == NULL))
952 ret = cclass->get_internal_time (clock);
954 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
955 GST_TIME_ARGS (ret));
962 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
963 "internal time not supported, return 0");
964 return G_GINT64_CONSTANT (0);
970 * @clock: a #GstClock to query
972 * Gets the current time of the given clock. The time is always
973 * monotonically increasing and adjusted according to the current
976 * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when
977 * given invalid input.
982 gst_clock_get_time (GstClock * clock)
987 g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
990 /* reget the internal time when we retry to get the most current
992 ret = gst_clock_get_internal_time (clock);
994 seq = read_seqbegin (clock);
995 /* this will scale for rate and offset */
996 ret = gst_clock_adjust_unlocked (clock, ret);
997 } while (read_seqretry (clock, seq));
999 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "adjusted time %" GST_TIME_FORMAT,
1000 GST_TIME_ARGS (ret));
1006 * gst_clock_set_calibration
1007 * @clock: a #GstClock to calibrate
1008 * @internal: a reference internal time
1009 * @external: a reference external time
1010 * @rate_num: the numerator of the rate of the clock relative to its
1012 * @rate_denom: the denominator of the rate of the clock
1014 * Adjusts the rate and time of @clock. A rate of 1/1 is the normal speed of
1015 * the clock. Values bigger than 1/1 make the clock go faster.
1017 * @internal and @external are calibration parameters that arrange that
1018 * gst_clock_get_time() should have been @external at internal time @internal.
1019 * This internal time should not be in the future; that is, it should be less
1020 * than the value of gst_clock_get_internal_time() when this function is called.
1022 * Subsequent calls to gst_clock_get_time() will return clock times computed as
1026 * time = (internal_time - internal) * rate_num / rate_denom + external
1029 * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
1030 * tries to do the integer arithmetic as precisely as possible.
1032 * Note that gst_clock_get_time() always returns increasing values so when you
1033 * move the clock backwards, gst_clock_get_time() will report the previous value
1034 * until the clock catches up.
1039 gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
1040 external, GstClockTime rate_num, GstClockTime rate_denom)
1042 g_return_if_fail (GST_IS_CLOCK (clock));
1043 g_return_if_fail (rate_num != GST_CLOCK_TIME_NONE);
1044 g_return_if_fail (rate_denom > 0 && rate_denom != GST_CLOCK_TIME_NONE);
1046 write_seqlock (clock);
1047 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1048 "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT " %"
1049 G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f", GST_TIME_ARGS (internal),
1050 GST_TIME_ARGS (external), rate_num, rate_denom,
1051 gst_guint64_to_gdouble (rate_num) / gst_guint64_to_gdouble (rate_denom));
1053 clock->internal_calibration = internal;
1054 clock->external_calibration = external;
1055 clock->rate_numerator = rate_num;
1056 clock->rate_denominator = rate_denom;
1057 write_sequnlock (clock);
1061 * gst_clock_get_calibration
1062 * @clock: a #GstClock
1063 * @internal: (out) (allow-none): a location to store the internal time
1064 * @external: (out) (allow-none): a location to store the external time
1065 * @rate_num: (out) (allow-none): a location to store the rate numerator
1066 * @rate_denom: (out) (allow-none): a location to store the rate denominator
1068 * Gets the internal rate and reference time of @clock. See
1069 * gst_clock_set_calibration() for more information.
1071 * @internal, @external, @rate_num, and @rate_denom can be left %NULL if the
1072 * caller is not interested in the values.
1077 gst_clock_get_calibration (GstClock * clock, GstClockTime * internal,
1078 GstClockTime * external, GstClockTime * rate_num, GstClockTime * rate_denom)
1082 g_return_if_fail (GST_IS_CLOCK (clock));
1085 seq = read_seqbegin (clock);
1087 *rate_num = clock->rate_numerator;
1089 *rate_denom = clock->rate_denominator;
1091 *external = clock->external_calibration;
1093 *internal = clock->internal_calibration;
1094 } while (read_seqretry (clock, seq));
1097 /* will be called repeatedly to sample the master and slave clock
1098 * to recalibrate the clock */
1100 gst_clock_slave_callback (GstClock * master, GstClockTime time,
1101 GstClockID id, GstClock * clock)
1103 GstClockTime stime, mtime;
1106 stime = gst_clock_get_internal_time (clock);
1107 mtime = gst_clock_get_time (master);
1109 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1110 "master %" GST_TIME_FORMAT ", slave %" GST_TIME_FORMAT,
1111 GST_TIME_ARGS (mtime), GST_TIME_ARGS (stime));
1113 gst_clock_add_observation (clock, stime, mtime, &r_squared);
1115 /* FIXME, we can use the r_squared value to adjust the timeout
1116 * value of the clockid */
1122 * gst_clock_set_master
1123 * @clock: a #GstClock
1124 * @master: (allow-none): a master #GstClock
1126 * Set @master as the master clock for @clock. @clock will be automatically
1127 * calibrated so that gst_clock_get_time() reports the same time as the
1130 * A clock provider that slaves its clock to a master can get the current
1131 * calibration values with gst_clock_get_calibration().
1133 * @master can be %NULL in which case @clock will not be slaved anymore. It will
1134 * however keep reporting its time adjusted with the last configured rate
1137 * Returns: %TRUE if the clock is capable of being slaved to a master clock.
1138 * Trying to set a master on a clock without the
1139 * #GST_CLOCK_FLAG_CAN_SET_MASTER flag will make this function return %FALSE.
1144 gst_clock_set_master (GstClock * clock, GstClock * master)
1146 GstClock **master_p;
1148 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1149 g_return_val_if_fail (master != clock, FALSE);
1151 GST_OBJECT_LOCK (clock);
1152 /* we always allow setting the master to NULL */
1153 if (master && !GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER))
1155 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1156 "slaving %p to master clock %p", clock, master);
1157 GST_OBJECT_UNLOCK (clock);
1159 GST_CLOCK_SLAVE_LOCK (clock);
1160 if (clock->clockid) {
1161 gst_clock_id_unschedule (clock->clockid);
1162 gst_clock_id_unref (clock->clockid);
1163 clock->clockid = NULL;
1166 clock->filling = TRUE;
1167 clock->time_index = 0;
1168 /* use the master periodic id to schedule sampling and
1169 * clock calibration. */
1170 clock->clockid = gst_clock_new_periodic_id (master,
1171 gst_clock_get_time (master), clock->timeout);
1172 gst_clock_id_wait_async_full (clock->clockid,
1173 (GstClockCallback) gst_clock_slave_callback,
1174 gst_object_ref (clock), (GDestroyNotify) gst_object_unref);
1176 GST_CLOCK_SLAVE_UNLOCK (clock);
1178 GST_OBJECT_LOCK (clock);
1179 master_p = &clock->master;
1180 gst_object_replace ((GstObject **) master_p, (GstObject *) master);
1181 GST_OBJECT_UNLOCK (clock);
1188 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1189 "cannot be slaved to a master clock");
1190 GST_OBJECT_UNLOCK (clock);
1196 * gst_clock_get_master:
1197 * @clock: a #GstClock
1199 * Get the master clock that @clock is slaved to or %NULL when the clock is
1200 * not slaved to any master clock.
1202 * Returns: (transfer full): a master #GstClock or %NULL when this clock is
1203 * not slaved to a master clock. Unref after usage.
1208 gst_clock_get_master (GstClock * clock)
1210 GstClock *result = NULL;
1212 g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
1214 GST_OBJECT_LOCK (clock);
1216 result = gst_object_ref (clock->master);
1217 GST_OBJECT_UNLOCK (clock);
1222 /* http://mathworld.wolfram.com/LeastSquaresFitting.html
1226 do_linear_regression (GstClock * clock, GstClockTime * m_num,
1227 GstClockTime * m_denom, GstClockTime * b, GstClockTime * xbase,
1228 gdouble * r_squared)
1230 GstClockTime *newx, *newy;
1231 GstClockTime xmin, ymin, xbar, ybar, xbar4, ybar4;
1232 GstClockTimeDiff sxx, sxy, syy;
1233 GstClockTime *x, *y;
1237 xbar = ybar = sxx = syy = sxy = 0;
1240 y = clock->times + 2;
1241 n = clock->filling ? clock->time_index : clock->window_size;
1243 #ifdef DEBUGGING_ENABLED
1244 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "doing regression on:");
1245 for (i = j = 0; i < n; i++, j += 4)
1246 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1247 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, x[j], y[j]);
1250 xmin = ymin = G_MAXUINT64;
1251 for (i = j = 0; i < n; i++, j += 4) {
1252 xmin = MIN (xmin, x[j]);
1253 ymin = MIN (ymin, y[j]);
1256 #ifdef DEBUGGING_ENABLED
1257 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min x: %" G_GUINT64_FORMAT,
1259 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min y: %" G_GUINT64_FORMAT,
1263 newx = clock->times + 1;
1264 newy = clock->times + 3;
1266 /* strip off unnecessary bits of precision */
1267 for (i = j = 0; i < n; i++, j += 4) {
1268 newx[j] = x[j] - xmin;
1269 newy[j] = y[j] - ymin;
1272 #ifdef DEBUGGING_ENABLED
1273 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "reduced numbers:");
1274 for (i = j = 0; i < n; i++, j += 4)
1275 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1276 " %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT, newx[j], newy[j]);
1279 /* have to do this precisely otherwise the results are pretty much useless.
1280 * should guarantee that none of these accumulators can overflow */
1282 /* quantities on the order of 1e10 -> 30 bits; window size a max of 2^10, so
1283 this addition could end up around 2^40 or so -- ample headroom */
1284 for (i = j = 0; i < n; i++, j += 4) {
1291 #ifdef DEBUGGING_ENABLED
1292 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbar = %" G_GUINT64_FORMAT,
1294 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " ybar = %" G_GUINT64_FORMAT,
1298 /* multiplying directly would give quantities on the order of 1e20 -> 60 bits;
1299 times the window size that's 70 which is too much. Instead we (1) subtract
1300 off the xbar*ybar in the loop instead of after, to avoid accumulation; (2)
1301 shift off 4 bits from each multiplicand, giving an expected ceiling of 52
1302 bits, which should be enough. Need to check the incoming range and domain
1303 to ensure this is an appropriate loss of precision though. */
1306 for (i = j = 0; i < n; i++, j += 4) {
1307 GstClockTime newx4, newy4;
1309 newx4 = newx[j] >> 4;
1310 newy4 = newy[j] >> 4;
1312 sxx += newx4 * newx4 - xbar4 * xbar4;
1313 syy += newy4 * newy4 - ybar4 * ybar4;
1314 sxy += newx4 * newy4 - xbar4 * ybar4;
1317 if (G_UNLIKELY (sxx == 0))
1323 *b = (ybar + ymin) - gst_util_uint64_scale (xbar, *m_num, *m_denom);
1324 *r_squared = ((double) sxy * (double) sxy) / ((double) sxx * (double) syy);
1326 #ifdef DEBUGGING_ENABLED
1327 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " m = %g",
1328 ((double) *m_num) / *m_denom);
1329 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " b = %" G_GUINT64_FORMAT,
1331 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " xbase = %" G_GUINT64_FORMAT,
1333 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, " r2 = %g", *r_squared);
1340 GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "sxx == 0, regression failed");
1346 * gst_clock_add_observation
1347 * @clock: a #GstClock
1348 * @slave: a time on the slave
1349 * @master: a time on the master
1350 * @r_squared: (out): a pointer to hold the result
1352 * The time @master of the master clock and the time @slave of the slave
1353 * clock are added to the list of observations. If enough observations
1354 * are available, a linear regression algorithm is run on the
1355 * observations and @clock is recalibrated.
1357 * If this functions returns %TRUE, @r_squared will contain the
1358 * correlation coefficient of the interpolation. A value of 1.0
1359 * means a perfect regression was performed. This value can
1360 * be used to control the sampling frequency of the master and slave
1363 * Returns: %TRUE if enough observations were added to run the
1364 * regression algorithm.
1369 gst_clock_add_observation (GstClock * clock, GstClockTime slave,
1370 GstClockTime master, gdouble * r_squared)
1372 GstClockTime m_num, m_denom, b, xbase;
1374 g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1375 g_return_val_if_fail (r_squared != NULL, FALSE);
1377 GST_CLOCK_SLAVE_LOCK (clock);
1379 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1380 "adding observation slave %" GST_TIME_FORMAT ", master %" GST_TIME_FORMAT,
1381 GST_TIME_ARGS (slave), GST_TIME_ARGS (master));
1383 clock->times[(4 * clock->time_index)] = slave;
1384 clock->times[(4 * clock->time_index) + 2] = master;
1386 clock->time_index++;
1387 if (G_UNLIKELY (clock->time_index == clock->window_size)) {
1388 clock->filling = FALSE;
1389 clock->time_index = 0;
1392 if (G_UNLIKELY (clock->filling
1393 && clock->time_index < clock->window_threshold))
1396 if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared))
1399 GST_CLOCK_SLAVE_UNLOCK (clock);
1401 GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1402 "adjusting clock to m=%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT ", b=%"
1403 G_GUINT64_FORMAT " (rsquared=%g)", m_num, m_denom, b, *r_squared);
1405 /* if we have a valid regression, adjust the clock */
1406 gst_clock_set_calibration (clock, xbase, b, m_num, m_denom);
1412 GST_CLOCK_SLAVE_UNLOCK (clock);
1417 /* no valid regression has been done, ignore the result then */
1418 GST_CLOCK_SLAVE_UNLOCK (clock);
1424 gst_clock_update_stats (GstClock * clock)
1429 gst_clock_set_property (GObject * object, guint prop_id,
1430 const GValue * value, GParamSpec * pspec)
1434 clock = GST_CLOCK (object);
1438 GST_OBJECT_LOCK (clock);
1439 clock->stats = g_value_get_boolean (value);
1440 GST_OBJECT_UNLOCK (clock);
1442 case PROP_WINDOW_SIZE:
1443 GST_CLOCK_SLAVE_LOCK (clock);
1444 clock->window_size = g_value_get_int (value);
1445 clock->window_threshold =
1446 MIN (clock->window_threshold, clock->window_size);
1448 g_renew (GstClockTime, clock->times, 4 * clock->window_size);
1449 /* restart calibration */
1450 clock->filling = TRUE;
1451 clock->time_index = 0;
1452 GST_CLOCK_SLAVE_UNLOCK (clock);
1454 case PROP_WINDOW_THRESHOLD:
1455 GST_CLOCK_SLAVE_LOCK (clock);
1456 clock->window_threshold =
1457 MIN (g_value_get_int (value), clock->window_size);
1458 GST_CLOCK_SLAVE_UNLOCK (clock);
1461 GST_CLOCK_SLAVE_LOCK (clock);
1462 clock->timeout = g_value_get_uint64 (value);
1463 GST_CLOCK_SLAVE_UNLOCK (clock);
1466 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1472 gst_clock_get_property (GObject * object, guint prop_id,
1473 GValue * value, GParamSpec * pspec)
1477 clock = GST_CLOCK (object);
1481 GST_OBJECT_LOCK (clock);
1482 g_value_set_boolean (value, clock->stats);
1483 GST_OBJECT_UNLOCK (clock);
1485 case PROP_WINDOW_SIZE:
1486 GST_CLOCK_SLAVE_LOCK (clock);
1487 g_value_set_int (value, clock->window_size);
1488 GST_CLOCK_SLAVE_UNLOCK (clock);
1490 case PROP_WINDOW_THRESHOLD:
1491 GST_CLOCK_SLAVE_LOCK (clock);
1492 g_value_set_int (value, clock->window_threshold);
1493 GST_CLOCK_SLAVE_UNLOCK (clock);
1496 GST_CLOCK_SLAVE_LOCK (clock);
1497 g_value_set_uint64 (value, clock->timeout);
1498 GST_CLOCK_SLAVE_UNLOCK (clock);
1501 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);