955fe7d2a605ee4efa401af935b50dd705ef327a
[platform/upstream/gstreamer.git] / gst / gstclock.c
1 /* GStreamer
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>
5  *
6  * gstclock.c: Clock subsystem for maintaining time sync
7  *
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.
12  *
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.
17  *
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.
22  */
23
24 /**
25  * SECTION:gstclock
26  * @short_description: Abstract class for global clocks
27  * @see_also: #GstSystemClock
28  *
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.
32  *
33  * The #GstClock returns a monotonically increasing time with the method
34  * gst_clock_get_time(). Its accuracy and base time depends on the specific
35  * clock implementation but time is always expessed 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  *
39  * The pipeline uses the clock to calculate the stream time.  Usually all
40  * renderers synchronize to the global clock using the buffer timestamps, the
41  * newsegment events and the element's base time.
42  *
43  * The time of the clock in itself is not very useful for an application.
44  *
45  * A clock implementation can support periodic and single shot clock
46  * notifications both synchronous and asynchronous.
47  *
48  * One first needs to create a #GstClockID for the periodic or single shot
49  * notification using gst_clock_new_single_shot_id() or
50  * gst_clock_new_periodic_id().
51  *
52  * To perform a blocking wait for the specific time of the #GstClockID use the
53  * gst_clock_id_wait(). To receive a callback when the specific time is reached
54  * in the clock use gst_clock_id_wait_async(). Both these calls can be
55  * interrupted with the gst_clock_id_unschedule() call. If the blocking wait is
56  * unscheduled a return value of GST_CLOCK_UNSCHEDULED is returned.
57  *
58  * Periodic callbacks scheduled async will be repeadedly called automatically
59  * until it is unscheduled. To schedule an async periodic callback,
60  * gst_clock_id_wait() should be called repeadedly.
61  *
62  * The async callbacks can happen from any thread, either provided by the core
63  * or from a streaming thread. The application should be prepared for this.
64  *
65  * A #GstClockID that has been unscheduled cannot be used again for any wait
66  * operation.
67  *
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 once.
71  *
72  * None of the wait operations unref the #GstClockID, the owner is responsible
73  * for unreffing the ids itself. This holds for both periodic and single shot
74  * notifications. The reason being that the owner of the #GstClockID has to
75  * keep a handle to the #GstClockID to unblock the wait on FLUSHING events or
76  * state changes and if we unref it automatically, the handle might be invalid.
77  *
78  * These clock operations do not operate on the stream time, so the callbacks
79  * will also occur when not in PLAYING state as if the clock just keeps on
80  * running. Some clocks however do not progress when the element that provided
81  * the clock is not PLAYING.
82  *
83  * When a clock has the GST_CLOCK_FLAG_CAN_SET_MASTER flag set, it can be
84  * slaved to another #GstClock with the gst_clock_set_master(). The clock will
85  * then automatically be synchronized to this master clock by repeadedly
86  * sampling the master clock and the slave clock and recalibrating the slave
87  * clock with gst_clock_set_calibration(). This feature is mostly usefull for
88  * plugins that have an internal clock but must operate with another clock
89  * selected by the #GstPipeline.  They can track the offset and rate difference
90  * of their internal clock relative to the master clock by using the
91  * gst_clock_get_calibration() function.
92  *
93  * Last reviewed on 2005-10-28 (0.9.4)
94  */
95
96 #include <time.h>
97
98 #include "gst_private.h"
99
100 #include "gstclock.h"
101 #include "gstinfo.h"
102 #include "gstutils.h"
103
104 #ifndef GST_DISABLE_TRACE
105 /* #define GST_WITH_ALLOC_TRACE */
106 #include "gsttrace.h"
107 static GstAllocTrace *_gst_clock_entry_trace;
108 #endif
109
110 /* #define DEBUGGING_ENABLED */
111
112 #define DEFAULT_STATS                   FALSE
113 #define DEFAULT_WINDOW_SIZE             32
114 #define DEFAULT_WINDOW_THRESHOLD        4
115 #define DEFAULT_TIMEOUT                 GST_SECOND / 10
116
117 enum
118 {
119   PROP_0,
120   PROP_STATS,
121   PROP_WINDOW_SIZE,
122   PROP_WINDOW_THRESHOLD,
123   PROP_TIMEOUT
124 };
125
126 static void gst_clock_class_init (GstClockClass * klass);
127 static void gst_clock_init (GstClock * clock);
128 static void gst_clock_finalize (GObject * object);
129
130 static void gst_clock_set_property (GObject * object, guint prop_id,
131     const GValue * value, GParamSpec * pspec);
132 static void gst_clock_get_property (GObject * object, guint prop_id,
133     GValue * value, GParamSpec * pspec);
134 static void gst_clock_update_stats (GstClock * clock);
135
136
137 static GstObjectClass *parent_class = NULL;
138
139 /* static guint gst_clock_signals[LAST_SIGNAL] = { 0 }; */
140
141 static GstClockID
142 gst_clock_entry_new (GstClock * clock, GstClockTime time,
143     GstClockTime interval, GstClockEntryType type)
144 {
145   GstClockEntry *entry;
146
147   entry = g_malloc0 (sizeof (GstClockEntry));
148 #ifndef GST_DISABLE_TRACE
149   gst_alloc_trace_new (_gst_clock_entry_trace, entry);
150 #endif
151   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
152       "created entry %p, time %" GST_TIME_FORMAT, entry, GST_TIME_ARGS (time));
153
154   gst_atomic_int_set (&entry->refcount, 1);
155   entry->clock = clock;
156   entry->time = time;
157   entry->interval = interval;
158   entry->type = type;
159   entry->status = GST_CLOCK_BUSY;
160
161   return (GstClockID) entry;
162 }
163
164 /**
165  * gst_clock_id_ref:
166  * @id: The clockid to ref
167  *
168  * Increase the refcount of the given clockid.
169  *
170  * Returns: The same #GstClockID with increased refcount.
171  *
172  * MT safe.
173  */
174 GstClockID
175 gst_clock_id_ref (GstClockID id)
176 {
177   g_return_val_if_fail (id != NULL, NULL);
178
179   g_atomic_int_inc (&((GstClockEntry *) id)->refcount);
180
181   return id;
182 }
183
184 static void
185 _gst_clock_id_free (GstClockID id)
186 {
187   g_return_if_fail (id != NULL);
188
189   GST_CAT_DEBUG (GST_CAT_CLOCK, "freed entry %p", id);
190
191 #ifndef GST_DISABLE_TRACE
192   gst_alloc_trace_free (_gst_clock_entry_trace, id);
193 #endif
194   g_free (id);
195 }
196
197 /**
198  * gst_clock_id_unref:
199  * @id: The clockid to unref
200  *
201  * Unref the given clockid. When the refcount reaches 0 the
202  * #GstClockID will be freed.
203  *
204  * MT safe.
205  */
206 void
207 gst_clock_id_unref (GstClockID id)
208 {
209   gint zero;
210
211   g_return_if_fail (id != NULL);
212
213   zero = g_atomic_int_dec_and_test (&((GstClockEntry *) id)->refcount);
214   /* if we ended up with the refcount at zero, free the id */
215   if (zero) {
216     _gst_clock_id_free (id);
217   }
218 }
219
220 /**
221  * gst_clock_new_single_shot_id
222  * @clock: The clockid to get a single shot notification from
223  * @time: the requested time
224  *
225  * Get an ID from the given clock to trigger a single shot
226  * notification at the requested time. The single shot id should be
227  * unreffed after usage.
228  *
229  * Returns: An id that can be used to request the time notification.
230  *
231  * MT safe.
232  */
233 GstClockID
234 gst_clock_new_single_shot_id (GstClock * clock, GstClockTime time)
235 {
236   g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
237
238   return gst_clock_entry_new (clock,
239       time, GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
240 }
241
242 /**
243  * gst_clock_new_periodic_id
244  * @clock: The clockid to get a periodic notification id from
245  * @start_time: the requested start time
246  * @interval: the requested interval
247  *
248  * Get an ID from the given clock to trigger a periodic notification.
249  * The periodeic notifications will be start at time start_time and
250  * will then be fired with the given interval. The id should be unreffed
251  * after usage.
252  *
253  * Returns: An id that can be used to request the time notification.
254  *
255  * MT safe.
256  */
257 GstClockID
258 gst_clock_new_periodic_id (GstClock * clock, GstClockTime start_time,
259     GstClockTime interval)
260 {
261   g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
262   g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (start_time), NULL);
263   g_return_val_if_fail (interval != 0, NULL);
264
265   return gst_clock_entry_new (clock,
266       start_time, interval, GST_CLOCK_ENTRY_PERIODIC);
267 }
268
269 /**
270  * gst_clock_id_compare_func
271  * @id1: A clockid
272  * @id2: A clockid to compare with
273  *
274  * Compares the two GstClockID instances. This function can be used
275  * as a GCompareFunc when sorting ids.
276  *
277  * Returns: negative value if a < b; zero if a = b; positive value if a > b
278  *
279  * MT safe.
280  */
281 gint
282 gst_clock_id_compare_func (gconstpointer id1, gconstpointer id2)
283 {
284   GstClockEntry *entry1, *entry2;
285
286   entry1 = (GstClockEntry *) id1;
287   entry2 = (GstClockEntry *) id2;
288
289   if (GST_CLOCK_ENTRY_TIME (entry1) > GST_CLOCK_ENTRY_TIME (entry2)) {
290     return 1;
291   }
292   if (GST_CLOCK_ENTRY_TIME (entry1) < GST_CLOCK_ENTRY_TIME (entry2)) {
293     return -1;
294   }
295
296   return entry1 - entry2;
297 }
298
299 /**
300  * gst_clock_id_get_time
301  * @id: The clockid to query
302  *
303  * Get the time of the clock ID
304  *
305  * Returns: the time of the given clock id.
306  *
307  * MT safe.
308  */
309 GstClockTime
310 gst_clock_id_get_time (GstClockID id)
311 {
312   g_return_val_if_fail (id != NULL, GST_CLOCK_TIME_NONE);
313
314   return GST_CLOCK_ENTRY_TIME ((GstClockEntry *) id);
315 }
316
317
318 /**
319  * gst_clock_id_wait
320  * @id: The clockid to wait on
321  * @jitter: A pointer that will contain the jitter
322  *
323  * Perform a blocking wait on the given ID. The jitter arg can be
324  * NULL.
325  *
326  * Returns: the result of the blocking wait.
327  *
328  * MT safe.
329  */
330 GstClockReturn
331 gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
332 {
333   GstClockEntry *entry;
334   GstClock *clock;
335   GstClockReturn res;
336   GstClockTime requested;
337   GstClockClass *cclass;
338
339   g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
340
341   entry = (GstClockEntry *) id;
342   requested = GST_CLOCK_ENTRY_TIME (entry);
343
344   clock = GST_CLOCK_ENTRY_CLOCK (entry);
345
346   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
347     goto invalid_time;
348
349   if (G_UNLIKELY (entry->status == GST_CLOCK_UNSCHEDULED))
350     goto unscheduled;
351
352   cclass = GST_CLOCK_GET_CLASS (clock);
353
354   if (G_LIKELY (cclass->wait)) {
355
356     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p",
357         id);
358     res = cclass->wait (clock, entry);
359     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
360         "done waiting entry %p, res: %d", id, res);
361
362     if (jitter) {
363       GstClockTime now = gst_clock_get_time (clock);
364
365       *jitter = now - requested;
366     }
367     if (entry->type == GST_CLOCK_ENTRY_PERIODIC) {
368       entry->time += entry->interval;
369     }
370
371     if (clock->stats) {
372       gst_clock_update_stats (clock);
373     }
374   } else {
375     res = GST_CLOCK_UNSUPPORTED;
376   }
377   return res;
378
379   /* ERRORS */
380 invalid_time:
381   {
382     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
383         "invalid time requested, returning _BADTIME");
384     return GST_CLOCK_BADTIME;
385   }
386 unscheduled:
387   {
388     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
389         "entry was unscheduled return _UNSCHEDULED");
390     return GST_CLOCK_UNSCHEDULED;
391   }
392 }
393
394 /**
395  * gst_clock_id_wait_async:
396  * @id: a #GstClockID to wait on
397  * @func: The callback function
398  * @user_data: User data passed in the calback
399  *
400  * Register a callback on the given clockid with the given
401  * function and user_data. When passing an id with an invalid
402  * time to this function, the callback will be called immediatly
403  * with  a time set to GST_CLOCK_TIME_NONE. The callback will
404  * be called when the time of the id has been reached.
405  *
406  * Returns: the result of the non blocking wait.
407  *
408  * MT safe.
409  */
410 GstClockReturn
411 gst_clock_id_wait_async (GstClockID id,
412     GstClockCallback func, gpointer user_data)
413 {
414   GstClockEntry *entry;
415   GstClock *clock;
416   GstClockReturn res;
417   GstClockClass *cclass;
418   GstClockTime requested;
419
420   g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
421   g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
422
423   entry = (GstClockEntry *) id;
424   requested = GST_CLOCK_ENTRY_TIME (entry);
425   clock = GST_CLOCK_ENTRY_CLOCK (entry);
426
427   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
428     goto invalid_time;
429
430   if (G_UNLIKELY (entry->status == GST_CLOCK_UNSCHEDULED))
431     goto unscheduled;
432
433   cclass = GST_CLOCK_GET_CLASS (clock);
434
435   if (cclass->wait_async) {
436     entry->func = func;
437     entry->user_data = user_data;
438
439     res = cclass->wait_async (clock, entry);
440   } else {
441     res = GST_CLOCK_UNSUPPORTED;
442   }
443   return res;
444
445   /* ERRORS */
446 invalid_time:
447   {
448     (func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
449     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
450         "invalid time requested, returning _BADTIME");
451     return GST_CLOCK_BADTIME;
452   }
453 unscheduled:
454   {
455     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
456         "entry was unscheduled return _UNSCHEDULED");
457     return GST_CLOCK_UNSCHEDULED;
458   }
459 }
460
461 /**
462  * gst_clock_id_unschedule:
463  * @id: The id to unschedule
464  *
465  * Cancel an outstanding request with the given ID. This can either
466  * be an outstanding async notification or a pending sync notification.
467  * After this call, the @id cannot be used anymore to receive sync or
468  * async notifications, you need to create a new GstClockID.
469  *
470  * MT safe.
471  */
472 void
473 gst_clock_id_unschedule (GstClockID id)
474 {
475   GstClockEntry *entry;
476   GstClock *clock;
477   GstClockClass *cclass;
478
479   g_return_if_fail (id != NULL);
480
481   entry = (GstClockEntry *) id;
482   clock = entry->clock;
483
484   cclass = GST_CLOCK_GET_CLASS (clock);
485
486   if (cclass->unschedule)
487     cclass->unschedule (clock, entry);
488 }
489
490
491 /**
492  * GstClock abstract base class implementation
493  */
494 GType
495 gst_clock_get_type (void)
496 {
497   static GType clock_type = 0;
498
499   if (!clock_type) {
500     static const GTypeInfo clock_info = {
501       sizeof (GstClockClass),
502       NULL,
503       NULL,
504       (GClassInitFunc) gst_clock_class_init,
505       NULL,
506       NULL,
507       sizeof (GstClock),
508       0,
509       (GInstanceInitFunc) gst_clock_init,
510       NULL
511     };
512
513     clock_type = g_type_register_static (GST_TYPE_OBJECT, "GstClock",
514         &clock_info, G_TYPE_FLAG_ABSTRACT);
515   }
516   return clock_type;
517 }
518
519 static void
520 gst_clock_class_init (GstClockClass * klass)
521 {
522   GObjectClass *gobject_class;
523   GstObjectClass *gstobject_class;
524
525   gobject_class = (GObjectClass *) klass;
526   gstobject_class = (GstObjectClass *) klass;
527
528   parent_class = g_type_class_ref (GST_TYPE_OBJECT);
529
530   if (!g_thread_supported ())
531     g_thread_init (NULL);
532
533 #ifndef GST_DISABLE_TRACE
534   _gst_clock_entry_trace =
535       gst_alloc_trace_register (GST_CLOCK_ENTRY_TRACE_NAME);
536 #endif
537
538   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_clock_finalize);
539   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_clock_set_property);
540   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_clock_get_property);
541
542   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_STATS,
543       g_param_spec_boolean ("stats", "Stats", "Enable clock stats",
544           DEFAULT_STATS, G_PARAM_READWRITE));
545   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_WINDOW_SIZE,
546       g_param_spec_int ("window-size", "Window size",
547           "The size of the window used to calculate rate and offset", 2, 1024,
548           DEFAULT_WINDOW_SIZE, G_PARAM_READWRITE));
549   g_object_class_install_property (G_OBJECT_CLASS (klass),
550       PROP_WINDOW_THRESHOLD, g_param_spec_int ("window-threshold",
551           "Window threshold",
552           "The threshold to start calculating rate and offset", 2, 1024,
553           DEFAULT_WINDOW_THRESHOLD, G_PARAM_READWRITE));
554   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TIMEOUT,
555       g_param_spec_uint64 ("timeout", "Timeout",
556           "The amount of time, in nanoseconds, to sample master and slave clocks",
557           0, G_MAXUINT64, DEFAULT_TIMEOUT, G_PARAM_READWRITE));
558 }
559
560 static void
561 gst_clock_init (GstClock * clock)
562 {
563   clock->last_time = 0;
564   clock->entries = NULL;
565   clock->entries_changed = g_cond_new ();
566   clock->stats = FALSE;
567
568   clock->internal_calibration = 0;
569   clock->external_calibration = 0;
570   clock->rate_numerator = 1;
571   clock->rate_denominator = 1;
572
573   clock->slave_lock = g_mutex_new ();
574   clock->filling = TRUE;
575   clock->window_size = DEFAULT_WINDOW_SIZE;
576   clock->window_threshold = DEFAULT_WINDOW_THRESHOLD;
577   clock->time_index = 0;
578   clock->timeout = DEFAULT_TIMEOUT;
579   clock->times = g_new0 (GstClockTime, 4 * clock->window_size);
580 }
581
582 static void
583 gst_clock_finalize (GObject * object)
584 {
585   GstClock *clock = GST_CLOCK (object);
586
587   GST_CLOCK_SLAVE_LOCK (clock);
588   if (clock->clockid) {
589     gst_clock_id_unschedule (clock->clockid);
590     gst_clock_id_unref (clock->clockid);
591     clock->clockid = NULL;
592   }
593   g_free (clock->times);
594   clock->times = NULL;
595   GST_CLOCK_SLAVE_UNLOCK (clock);
596
597   g_cond_free (clock->entries_changed);
598   g_mutex_free (clock->slave_lock);
599
600   G_OBJECT_CLASS (parent_class)->finalize (object);
601 }
602
603 /**
604  * gst_clock_set_resolution
605  * @clock: a #GstClock
606  * @resolution: The resolution to set
607  *
608  * Set the accuracy of the clock.
609  *
610  * Returns: the new resolution of the clock.
611  */
612 GstClockTime
613 gst_clock_set_resolution (GstClock * clock, GstClockTime resolution)
614 {
615   GstClockClass *cclass;
616
617   g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
618   g_return_val_if_fail (resolution != 0, 0);
619
620   cclass = GST_CLOCK_GET_CLASS (clock);
621
622   if (cclass->change_resolution)
623     clock->resolution =
624         cclass->change_resolution (clock, clock->resolution, resolution);
625
626   return clock->resolution;
627 }
628
629 /**
630  * gst_clock_get_resolution
631  * @clock: a #GstClock
632  *
633  * Get the accuracy of the clock.
634  *
635  * Returns: the resolution of the clock in units of #GstClockTime.
636  *
637  * MT safe.
638  */
639 GstClockTime
640 gst_clock_get_resolution (GstClock * clock)
641 {
642   GstClockClass *cclass;
643
644   g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
645
646   cclass = GST_CLOCK_GET_CLASS (clock);
647
648   if (cclass->get_resolution)
649     return cclass->get_resolution (clock);
650
651   return 1;
652 }
653
654 /**
655  * gst_clock_adjust_unlocked
656  * @clock: a #GstClock to use
657  * @internal: a clock time
658  *
659  * Converts the given @internal clock time to the real time, adjusting for the
660  * rate and reference time set with gst_clock_set_calibration() and making sure
661  * that the returned time is increasing. This function should be called with the
662  * clock's OBJECT_LOCK held and is mainly used by clock subclasses.
663  *
664  * Returns: the converted time of the clock.
665  *
666  * MT safe.
667  */
668 GstClockTime
669 gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
670 {
671   GstClockTime ret;
672
673   ret = gst_util_uint64_scale (internal - clock->internal_calibration,
674       clock->rate_numerator, clock->rate_denominator);
675   ret += clock->external_calibration;
676
677   /* make sure the time is increasing */
678   clock->last_time = MAX (ret, clock->last_time);
679
680   return clock->last_time;
681 }
682
683 /**
684  * gst_clock_get_internal_time
685  * @clock: a #GstClock to query
686  *
687  * Gets the current internal time of the given clock. The time is returned
688  * unadjusted for the offset and the rate.
689  *
690  * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
691  * giving wrong input.
692  *
693  * MT safe.
694  */
695 GstClockTime
696 gst_clock_get_internal_time (GstClock * clock)
697 {
698   GstClockTime ret;
699   GstClockClass *cclass;
700
701   g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
702
703   cclass = GST_CLOCK_GET_CLASS (clock);
704
705   if (cclass->get_internal_time) {
706     ret = cclass->get_internal_time (clock);
707   } else {
708     ret = G_GINT64_CONSTANT (0);
709   }
710   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
711       GST_TIME_ARGS (ret));
712
713   return ret;
714 }
715
716 /**
717  * gst_clock_get_time
718  * @clock: a #GstClock to query
719  *
720  * Gets the current time of the given clock. The time is always
721  * monotonically increasing and adjusted according to the current
722  * offset and rate.
723  *
724  * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when
725  * giving wrong input.
726  *
727  * MT safe.
728  */
729 GstClockTime
730 gst_clock_get_time (GstClock * clock)
731 {
732   GstClockTime ret;
733
734   g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
735
736   ret = gst_clock_get_internal_time (clock);
737
738   GST_OBJECT_LOCK (clock);
739   /* this will scale for rate and offset */
740   ret = gst_clock_adjust_unlocked (clock, ret);
741   GST_OBJECT_UNLOCK (clock);
742
743   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "adjusted time %" GST_TIME_FORMAT,
744       GST_TIME_ARGS (ret));
745
746   return ret;
747 }
748
749 /**
750  * gst_clock_set_calibration
751  * @clock: a #GstClock to calibrate
752  * @internal: a reference internal time
753  * @external: a reference external time
754  * @rate_num: the numerator of the rate of the clock relative to its
755  *            internal time 
756  * @rate_denom: the denominator of the rate of the clock
757  *
758  * Adjusts the rate and time of @clock. A rate of 1/1 is the normal speed of
759  * the clock. Values bigger than 1/1 make the clock go faster.
760  *
761  * @internal and @external are calibration parameters that arrange that
762  * gst_clock_get_time() should have been @external at internal time @internal.
763  * This internal time should not be in the future; that is, it should be less
764  * than the value of gst_clock_get_internal_time() when this function is called.
765  *
766  * Subsequent calls to gst_clock_get_time() will return clock times computed as
767  * follows:
768  *
769  * <programlisting>
770  *   time = (internal_time - @internal) * @rate_num / @rate_denom + @external
771  * </programlisting>
772  *
773  * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
774  * tries to do the integer arithmetic as precisely as possible.
775  *
776  * Note that gst_clock_get_time() always returns increasing values so when you
777  * move the clock backwards, gst_clock_get_time() will report the previous value
778  * until the clock catches up.
779  *
780  * MT safe.
781  */
782 void
783 gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
784     external, GstClockTime rate_num, GstClockTime rate_denom)
785 {
786   g_return_if_fail (GST_IS_CLOCK (clock));
787   g_return_if_fail (rate_num > 0);
788   g_return_if_fail (rate_denom > 0);
789   g_return_if_fail (internal <= gst_clock_get_internal_time (clock));
790
791   GST_OBJECT_LOCK (clock);
792   clock->internal_calibration = internal;
793   clock->external_calibration = external;
794   clock->rate_numerator = rate_num;
795   clock->rate_denominator = rate_denom;
796   GST_OBJECT_UNLOCK (clock);
797 }
798
799 /**
800  * gst_clock_get_calibration
801  * @clock: a #GstClock 
802  * @internal: a location to store the internal time
803  * @external: a location to store the external time
804  * @rate_num: a location to store the rate numerator
805  * @rate_denom: a location to store the rate denominator
806  *
807  * Gets the internal rate and reference time of @clock. See
808  * gst_clock_set_calibration() for more information.
809  *
810  * @internal, @external, @rate_num, and @rate_denom can be left NULL if the
811  * caller is not interested in the values.
812  *
813  * MT safe.
814  */
815 void
816 gst_clock_get_calibration (GstClock * clock, GstClockTime * internal,
817     GstClockTime * external, GstClockTime * rate_num, GstClockTime * rate_denom)
818 {
819   g_return_if_fail (GST_IS_CLOCK (clock));
820
821   GST_OBJECT_LOCK (clock);
822   if (rate_num)
823     *rate_num = clock->rate_numerator;
824   if (rate_denom)
825     *rate_denom = clock->rate_denominator;
826   if (external)
827     *external = clock->external_calibration;
828   if (internal)
829     *internal = clock->internal_calibration;
830   GST_OBJECT_UNLOCK (clock);
831 }
832
833 /* will be called repeadedly to sample the master and slave clock
834  * to recalibrate the clock */
835 static gboolean
836 gst_clock_slave_callback (GstClock * master, GstClockTime time,
837     GstClockID id, GstClock * clock)
838 {
839   GstClockTime stime, mtime;
840   gdouble r_squared;
841
842   stime = gst_clock_get_internal_time (clock);
843   mtime = gst_clock_get_time (master);
844
845   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
846       "master %" GST_TIME_FORMAT ", slave %" GST_TIME_FORMAT,
847       GST_TIME_ARGS (mtime), GST_TIME_ARGS (stime));
848
849   gst_clock_add_observation (clock, stime, mtime, &r_squared);
850
851   /* FIXME, we can use the r_squared value to adjust the timeout
852    * value of the clockid */
853
854   return TRUE;
855 }
856
857 /**
858  * gst_clock_set_master
859  * @clock: a #GstClock 
860  * @master: a master #GstClock 
861  *
862  * Set @master as the master clock for @clock. @clock will be automatically
863  * calibrated so that gst_clock_get_time() reports the same time as the
864  * master clock.  
865  * 
866  * A clock provider that slaves its clock to a master can get the current
867  * calibration values with gst_clock_get_calibration().
868  *
869  * Returns: TRUE if the clock is capable of being slaved to a master clock.
870  *
871  * MT safe.
872  */
873 gboolean
874 gst_clock_set_master (GstClock * clock, GstClock * master)
875 {
876   g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
877
878   GST_OBJECT_LOCK (clock);
879   /* we always allow setting the master to NULL */
880   if (master && !GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER))
881     goto not_supported;
882
883   GST_DEBUG_OBJECT (clock, "slaving to master clock %p", master);
884   gst_object_replace ((GstObject **) & clock->master, (GstObject *) master);
885   GST_OBJECT_UNLOCK (clock);
886
887   GST_CLOCK_SLAVE_LOCK (clock);
888   if (clock->clockid) {
889     gst_clock_id_unschedule (clock->clockid);
890     gst_clock_id_unref (clock->clockid);
891     clock->clockid = NULL;
892   }
893   if (master) {
894     clock->filling = TRUE;
895     clock->time_index = 0;
896     /* use the master periodic id to schedule sampling and
897      * clock calibration. */
898     clock->clockid = gst_clock_new_periodic_id (master,
899         gst_clock_get_time (master), clock->timeout);
900     gst_clock_id_wait_async (clock->clockid,
901         (GstClockCallback) gst_clock_slave_callback, clock);
902   }
903   GST_CLOCK_SLAVE_UNLOCK (clock);
904
905   return TRUE;
906
907 not_supported:
908   {
909     GST_DEBUG_OBJECT (clock, "cannot be slaved to a master clock");
910     GST_OBJECT_UNLOCK (clock);
911     return FALSE;
912   }
913 }
914
915 /**
916  * gst_clock_get_master
917  * @clock: a #GstClock 
918  *
919  * Get the master clock that @clock is slaved to or NULL when the clock is
920  * not slaved to any master clock.
921  *
922  * Returns: a master #GstClock or NULL when this clock is not slaved to a master
923  * clock. Unref after usage.
924  *
925  * MT safe.
926  */
927 GstClock *
928 gst_clock_get_master (GstClock * clock)
929 {
930   GstClock *result = NULL;
931
932   g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
933
934   GST_OBJECT_LOCK (clock);
935   if (clock->master)
936     result = gst_object_ref (clock->master);
937   GST_OBJECT_UNLOCK (clock);
938
939   return result;
940 }
941
942 /* http://mathworld.wolfram.com/LeastSquaresFitting.html
943  * with SLAVE_LOCK
944  */
945 static gboolean
946 do_linear_regression (GstClock * clock, GstClockTime * m_num,
947     GstClockTime * m_denom, GstClockTime * b, GstClockTime * xbase,
948     gdouble * r_squared)
949 {
950   GstClockTime *newx, *newy;
951   GstClockTime xmin, ymin, xbar, ybar, xbar4, ybar4;
952   GstClockTimeDiff sxx, sxy, syy;
953   GstClockTime *x, *y;
954   gint i, j;
955   guint n;
956
957   xbar = ybar = sxx = syy = sxy = 0;
958
959   x = clock->times;
960   y = clock->times + 2;
961   n = clock->filling ? clock->time_index : clock->window_size;
962
963 #ifdef DEBUGGING_ENABLED
964   GST_DEBUG ("doing regression on:");
965   for (i = j = 0; i < n; i++, j += 4)
966     GST_DEBUG ("  %" G_GUINT64_FORMAT "  %" G_GUINT64_FORMAT, x[j], y[j]);
967 #endif
968
969   xmin = ymin = G_MAXUINT64;
970   for (i = j = 0; i < n; i++, j += 4) {
971     xmin = MIN (xmin, x[j]);
972     ymin = MIN (ymin, y[j]);
973   }
974
975 #ifdef DEBUGGING_ENABLED
976   GST_DEBUG ("min x: %" G_GUINT64_FORMAT, xmin);
977   GST_DEBUG ("min y: %" G_GUINT64_FORMAT, ymin);
978 #endif
979
980   newx = clock->times + 1;
981   newy = clock->times + 3;
982
983   /* strip off unnecessary bits of precision */
984   for (i = j = 0; i < n; i++, j += 4) {
985     newx[j] = x[j] - xmin;
986     newy[j] = y[j] - ymin;
987   }
988
989 #ifdef DEBUGGING_ENABLED
990   GST_DEBUG ("reduced numbers:");
991   for (i = j = 0; i < n; i++, j += 4)
992     GST_DEBUG ("  %" G_GUINT64_FORMAT "  %" G_GUINT64_FORMAT, newx[j], newy[j]);
993 #endif
994
995   /* have to do this precisely otherwise the results are pretty much useless.
996    * should guarantee that none of these accumulators can overflow */
997
998   /* quantities on the order of 1e10 -> 30 bits; window size a max of 2^10, so
999      this addition could end up around 2^40 or so -- ample headroom */
1000   for (i = j = 0; i < n; i++, j += 4) {
1001     xbar += newx[j];
1002     ybar += newy[j];
1003   }
1004   xbar /= n;
1005   ybar /= n;
1006
1007 #ifdef DEBUGGING_ENABLED
1008   GST_DEBUG ("  xbar  = %" G_GUINT64_FORMAT, xbar);
1009   GST_DEBUG ("  ybar  = %" G_GUINT64_FORMAT, ybar);
1010 #endif
1011
1012   /* multiplying directly would give quantities on the order of 1e20 -> 60 bits;
1013      times the window size that's 70 which is too much. Instead we (1) subtract
1014      off the xbar*ybar in the loop instead of after, to avoid accumulation; (2)
1015      shift off 4 bits from each multiplicand, giving an expected ceiling of 52
1016      bits, which should be enough. Need to check the incoming range and domain
1017      to ensure this is an appropriate loss of precision though. */
1018   xbar4 = xbar >> 4;
1019   ybar4 = ybar >> 4;
1020   for (i = j = 0; i < n; i++, j += 4) {
1021     GstClockTime newx4, newy4;
1022
1023     newx4 = newx[j] >> 4;
1024     newy4 = newy[j] >> 4;
1025
1026     sxx += newx4 * newx4 - xbar4 * xbar4;
1027     syy += newy4 * newy4 - ybar4 * ybar4;
1028     sxy += newx4 * newy4 - xbar4 * ybar4;
1029   }
1030
1031   if (sxx == 0)
1032     goto invalid;
1033
1034   *m_num = sxy;
1035   *m_denom = sxx;
1036   *xbase = xmin;
1037   *b = (ybar + ymin) - gst_util_uint64_scale (xbar, *m_num, *m_denom);
1038   *r_squared = ((double) sxy * (double) sxy) / ((double) sxx * (double) syy);
1039
1040 #ifdef DEBUGGING_ENABLED
1041   GST_DEBUG ("  m      = %g", ((double) *m_num) / *m_denom);
1042   GST_DEBUG ("  b      = %" G_GUINT64_FORMAT, *b);
1043   GST_DEBUG ("  xbase  = %" G_GUINT64_FORMAT, *xbase);
1044   GST_DEBUG ("  r2     = %g", *r_squared);
1045 #endif
1046
1047   return TRUE;
1048
1049 invalid:
1050   {
1051     return FALSE;
1052   }
1053 }
1054
1055 /**
1056  * gst_clock_add_observation
1057  * @clock: a #GstClock 
1058  * @slave: a time on the slave
1059  * @master: a time on the master
1060  * @r_squared: a pointer to hold the result
1061  *
1062  * The time @master of the master clock and the time @slave of the slave
1063  * clock are added to the list of observations. If enough observations
1064  * are available, a linear regression algorithm is run on the
1065  * observations and @clock is recalibrated.
1066  *
1067  * Returns: TRUE if enough observations were added to run the 
1068  * regression algorithm.
1069  *
1070  * MT safe.
1071  */
1072 gboolean
1073 gst_clock_add_observation (GstClock * clock, GstClockTime slave,
1074     GstClockTime master, gdouble * r_squared)
1075 {
1076   GstClockTime m_num, m_denom, b, xbase;
1077
1078   g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1079   g_return_val_if_fail (r_squared != NULL, FALSE);
1080
1081   GST_CLOCK_SLAVE_LOCK (clock);
1082
1083   clock->times[(4 * clock->time_index)] = slave;
1084   clock->times[(4 * clock->time_index) + 2] = master;
1085
1086   clock->time_index++;
1087   if (clock->time_index == clock->window_size) {
1088     clock->filling = FALSE;
1089     clock->time_index = 0;
1090   }
1091
1092   if (clock->filling && clock->time_index < clock->window_threshold)
1093     goto filling;
1094
1095   if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared))
1096     goto invalid;
1097
1098   GST_CLOCK_SLAVE_UNLOCK (clock);
1099
1100   GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1101       "adjusting clock to m=%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT ", b=%"
1102       G_GUINT64_FORMAT " (rsquared=%g)", m_num, m_denom, b, *r_squared);
1103
1104   /* if we have a valid regression, adjust the clock */
1105   gst_clock_set_calibration (clock, xbase, b, m_num, m_denom);
1106
1107   return TRUE;
1108
1109 filling:
1110   {
1111     GST_CLOCK_SLAVE_UNLOCK (clock);
1112     return FALSE;
1113   }
1114 invalid:
1115   {
1116     /* no valid regression has been done, ignore the result then */
1117     GST_CLOCK_SLAVE_UNLOCK (clock);
1118     return TRUE;
1119   }
1120 }
1121
1122 static void
1123 gst_clock_update_stats (GstClock * clock)
1124 {
1125 }
1126
1127 static void
1128 gst_clock_set_property (GObject * object, guint prop_id,
1129     const GValue * value, GParamSpec * pspec)
1130 {
1131   GstClock *clock;
1132
1133   clock = GST_CLOCK (object);
1134
1135   switch (prop_id) {
1136     case PROP_STATS:
1137       GST_OBJECT_LOCK (clock);
1138       clock->stats = g_value_get_boolean (value);
1139       GST_OBJECT_UNLOCK (clock);
1140       g_object_notify (object, "stats");
1141       break;
1142     case PROP_WINDOW_SIZE:
1143       GST_CLOCK_SLAVE_LOCK (clock);
1144       clock->window_size = g_value_get_int (value);
1145       clock->window_threshold =
1146           MIN (clock->window_threshold, clock->window_size);
1147       clock->times =
1148           g_renew (GstClockTime, clock->times, 4 * clock->window_size);
1149       GST_CLOCK_SLAVE_UNLOCK (clock);
1150       break;
1151     case PROP_WINDOW_THRESHOLD:
1152       GST_CLOCK_SLAVE_LOCK (clock);
1153       clock->window_threshold =
1154           MIN (g_value_get_int (value), clock->window_size);
1155       GST_CLOCK_SLAVE_UNLOCK (clock);
1156       break;
1157     case PROP_TIMEOUT:
1158       GST_CLOCK_SLAVE_LOCK (clock);
1159       clock->timeout = g_value_get_uint64 (value);
1160       GST_CLOCK_SLAVE_UNLOCK (clock);
1161       break;
1162     default:
1163       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1164       break;
1165   }
1166 }
1167
1168 static void
1169 gst_clock_get_property (GObject * object, guint prop_id,
1170     GValue * value, GParamSpec * pspec)
1171 {
1172   GstClock *clock;
1173
1174   clock = GST_CLOCK (object);
1175
1176   switch (prop_id) {
1177     case PROP_STATS:
1178       GST_OBJECT_LOCK (clock);
1179       g_value_set_boolean (value, clock->stats);
1180       GST_OBJECT_UNLOCK (clock);
1181       break;
1182     case PROP_WINDOW_SIZE:
1183       GST_CLOCK_SLAVE_LOCK (clock);
1184       g_value_set_int (value, clock->window_size);
1185       GST_CLOCK_SLAVE_UNLOCK (clock);
1186       break;
1187     case PROP_WINDOW_THRESHOLD:
1188       GST_CLOCK_SLAVE_LOCK (clock);
1189       g_value_set_int (value, clock->window_threshold);
1190       GST_CLOCK_SLAVE_UNLOCK (clock);
1191       break;
1192     case PROP_TIMEOUT:
1193       GST_CLOCK_SLAVE_LOCK (clock);
1194       g_value_set_uint64 (value, clock->timeout);
1195       GST_CLOCK_SLAVE_UNLOCK (clock);
1196       break;
1197     default:
1198       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1199       break;
1200   }
1201 }