Merge remote-tracking branch 'origin/master' into 0.11
[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, #GstPipeline
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 or, more conveniently, by subclassing #GstSystemClock.
32  *
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.
39  *
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.
43  *
44  * A clock implementation can support periodic and single shot clock
45  * notifications both synchronous and asynchronous.
46  *
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().
50  *
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.
56  *
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.
60  *
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.
63  *
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().
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 for
71  * the thread registering the entry last.
72  *
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.
79  *
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.
84  *
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. 
94  *
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.
101  *
102  * Last reviewed on 2009-05-21 (0.10.24)
103  */
104
105
106 #include "gst_private.h"
107 #include <time.h>
108
109 #include "gstclock.h"
110 #include "gstinfo.h"
111 #include "gstutils.h"
112
113 #ifndef GST_DISABLE_TRACE
114 /* #define GST_WITH_ALLOC_TRACE */
115 #include "gsttrace.h"
116 static GstAllocTrace *_gst_clock_entry_trace;
117 #endif
118
119 /* #define DEBUGGING_ENABLED */
120
121 #define DEFAULT_STATS                   FALSE
122 #define DEFAULT_WINDOW_SIZE             32
123 #define DEFAULT_WINDOW_THRESHOLD        4
124 #define DEFAULT_TIMEOUT                 GST_SECOND / 10
125
126 enum
127 {
128   PROP_0,
129   PROP_STATS,
130   PROP_WINDOW_SIZE,
131   PROP_WINDOW_THRESHOLD,
132   PROP_TIMEOUT
133 };
134
135 struct _GstClockPrivate
136 {
137   gint pre_count;
138   gint post_count;
139 };
140
141 /* seqlocks */
142 #define read_seqbegin(clock)                                   \
143   g_atomic_int_get (&clock->ABI.priv->post_count);
144
145 static inline gboolean
146 read_seqretry (GstClock * clock, gint seq)
147 {
148   /* no retry if the seqnum did not change */
149   if (G_LIKELY (seq == g_atomic_int_get (&clock->ABI.priv->pre_count)))
150     return FALSE;
151
152   /* wait for the writer to finish and retry */
153   GST_OBJECT_LOCK (clock);
154   GST_OBJECT_UNLOCK (clock);
155   return TRUE;
156 }
157
158 #define write_seqlock(clock)                      \
159 G_STMT_START {                                    \
160   GST_OBJECT_LOCK (clock);                        \
161   g_atomic_int_inc (&clock->ABI.priv->pre_count);     \
162 } G_STMT_END;
163
164 #define write_sequnlock(clock)                    \
165 G_STMT_START {                                    \
166   g_atomic_int_inc (&clock->ABI.priv->post_count);    \
167   GST_OBJECT_UNLOCK (clock);                      \
168 } G_STMT_END;
169
170 static void gst_clock_dispose (GObject * object);
171 static void gst_clock_finalize (GObject * object);
172
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);
178
179
180 /* static guint gst_clock_signals[LAST_SIGNAL] = { 0 }; */
181
182 static GstClockID
183 gst_clock_entry_new (GstClock * clock, GstClockTime time,
184     GstClockTime interval, GstClockEntryType type)
185 {
186   GstClockEntry *entry;
187
188   entry = g_slice_new (GstClockEntry);
189 #ifndef GST_DISABLE_TRACE
190   gst_alloc_trace_new (_gst_clock_entry_trace, entry);
191 #endif
192   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
193       "created entry %p, time %" GST_TIME_FORMAT, entry, GST_TIME_ARGS (time));
194
195   entry->refcount = 1;
196   entry->clock = clock;
197   entry->type = type;
198   entry->time = time;
199   entry->interval = interval;
200   entry->status = GST_CLOCK_OK;
201   entry->func = NULL;
202   entry->user_data = NULL;
203   entry->destroy_data = NULL;
204   entry->unscheduled = FALSE;
205   entry->woken_up = FALSE;
206
207   return (GstClockID) entry;
208 }
209
210 /* WARNING : Does not modify the refcount
211  * WARNING : Do not use if a pending clock operation is happening on that entry */
212 static gboolean
213 gst_clock_entry_reinit (GstClock * clock, GstClockEntry * entry,
214     GstClockTime time, GstClockTime interval, GstClockEntryType type)
215 {
216   g_return_val_if_fail (entry->status != GST_CLOCK_BUSY, FALSE);
217   g_return_val_if_fail (entry->clock == clock, FALSE);
218
219   entry->type = type;
220   entry->time = time;
221   entry->interval = interval;
222   entry->status = GST_CLOCK_OK;
223   entry->unscheduled = FALSE;
224   entry->woken_up = FALSE;
225
226   return TRUE;
227 }
228
229 /**
230  * gst_clock_single_shot_id_reinit:
231  * @clock: a #GstClock
232  * @id: a #GstClockID
233  * @time: The requested time.
234  *
235  * Reinitializes the provided single shot @id to the provided time. Does not
236  * modify the reference count.
237  *
238  * Returns: %TRUE if the GstClockID could be reinitialized to the provided
239  * @time, else %FALSE.
240  *
241  * Since: 0.10.32
242  */
243 gboolean
244 gst_clock_single_shot_id_reinit (GstClock * clock, GstClockID id,
245     GstClockTime time)
246 {
247   return gst_clock_entry_reinit (clock, (GstClockEntry *) id, time,
248       GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
249 }
250
251 /**
252  * gst_clock_periodic_id_reinit:
253  * @clock: a #GstClock
254  * @id: a #GstClockID
255  * @start_time: the requested start time
256  * @interval: the requested interval
257  *
258  * Reinitializes the provided periodic @id to the provided start time and
259  * interval. Does not modify the reference count.
260  *
261  * Returns: %TRUE if the GstClockID could be reinitialized to the provided
262  * @time, else %FALSE.
263  *
264  * Since: 0.10.33
265  *
266  */
267 gboolean
268 gst_clock_periodic_id_reinit (GstClock * clock, GstClockID id,
269     GstClockTime start_time, GstClockTime interval)
270 {
271   return gst_clock_entry_reinit (clock, (GstClockEntry *) id, start_time,
272       interval, GST_CLOCK_ENTRY_PERIODIC);
273 }
274
275 /**
276  * gst_clock_id_ref:
277  * @id: The #GstClockID to ref
278  *
279  * Increase the refcount of given @id.
280  *
281  * Returns: (transfer full): The same #GstClockID with increased refcount.
282  *
283  * MT safe.
284  */
285 GstClockID
286 gst_clock_id_ref (GstClockID id)
287 {
288   g_return_val_if_fail (id != NULL, NULL);
289
290   g_atomic_int_inc (&((GstClockEntry *) id)->refcount);
291
292   return id;
293 }
294
295 static void
296 _gst_clock_id_free (GstClockID id)
297 {
298   GstClockEntry *entry;
299   g_return_if_fail (id != NULL);
300
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);
305
306 #ifndef GST_DISABLE_TRACE
307   gst_alloc_trace_free (_gst_clock_entry_trace, id);
308 #endif
309   g_slice_free (GstClockEntry, id);
310 }
311
312 /**
313  * gst_clock_id_unref:
314  * @id: (transfer full): The #GstClockID to unref
315  *
316  * Unref given @id. When the refcount reaches 0 the
317  * #GstClockID will be freed.
318  *
319  * MT safe.
320  */
321 void
322 gst_clock_id_unref (GstClockID id)
323 {
324   gint zero;
325
326   g_return_if_fail (id != NULL);
327
328   zero = g_atomic_int_dec_and_test (&((GstClockEntry *) id)->refcount);
329   /* if we ended up with the refcount at zero, free the id */
330   if (zero) {
331     _gst_clock_id_free (id);
332   }
333 }
334
335 /**
336  * gst_clock_new_single_shot_id:
337  * @clock: The #GstClockID to get a single shot notification from
338  * @time: the requested time
339  *
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.
343  *
344  * Free-function: gst_clock_id_unref
345  *
346  * Returns: (transfer full): a #GstClockID that can be used to request the
347  *     time notification.
348  *
349  * MT safe.
350  */
351 GstClockID
352 gst_clock_new_single_shot_id (GstClock * clock, GstClockTime time)
353 {
354   g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
355
356   return gst_clock_entry_new (clock,
357       time, GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
358 }
359
360 /**
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
365  *
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
369  * after usage.
370  *
371  * Free-function: gst_clock_id_unref
372  *
373  * Returns: (transfer full): a #GstClockID that can be used to request the
374  *     time notification.
375  *
376  * MT safe.
377  */
378 GstClockID
379 gst_clock_new_periodic_id (GstClock * clock, GstClockTime start_time,
380     GstClockTime interval)
381 {
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);
386
387   return gst_clock_entry_new (clock,
388       start_time, interval, GST_CLOCK_ENTRY_PERIODIC);
389 }
390
391 /**
392  * gst_clock_id_compare_func
393  * @id1: A #GstClockID
394  * @id2: A #GstClockID to compare with
395  *
396  * Compares the two #GstClockID instances. This function can be used
397  * as a GCompareFunc when sorting ids.
398  *
399  * Returns: negative value if a < b; zero if a = b; positive value if a > b
400  *
401  * MT safe.
402  */
403 gint
404 gst_clock_id_compare_func (gconstpointer id1, gconstpointer id2)
405 {
406   GstClockEntry *entry1, *entry2;
407
408   entry1 = (GstClockEntry *) id1;
409   entry2 = (GstClockEntry *) id2;
410
411   if (GST_CLOCK_ENTRY_TIME (entry1) > GST_CLOCK_ENTRY_TIME (entry2)) {
412     return 1;
413   }
414   if (GST_CLOCK_ENTRY_TIME (entry1) < GST_CLOCK_ENTRY_TIME (entry2)) {
415     return -1;
416   }
417   return 0;
418 }
419
420 /**
421  * gst_clock_id_get_time
422  * @id: The #GstClockID to query
423  *
424  * Get the time of the clock ID
425  *
426  * Returns: the time of the given clock id.
427  *
428  * MT safe.
429  */
430 GstClockTime
431 gst_clock_id_get_time (GstClockID id)
432 {
433   g_return_val_if_fail (id != NULL, GST_CLOCK_TIME_NONE);
434
435   return GST_CLOCK_ENTRY_TIME ((GstClockEntry *) id);
436 }
437
438 /**
439  * gst_clock_id_wait
440  * @id: The #GstClockID to wait on
441  * @jitter: (out) (allow-none): a pointer that will contain the jitter,
442  *     can be %NULL.
443  *
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(). 
448  *
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
452  * called. 
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.
457  *
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().
462  *
463  * MT safe.
464  */
465 GstClockReturn
466 gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
467 {
468   GstClockEntry *entry;
469   GstClock *clock;
470   GstClockReturn res;
471   GstClockTime requested;
472   GstClockClass *cclass;
473
474   g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
475
476   entry = (GstClockEntry *) id;
477   requested = GST_CLOCK_ENTRY_TIME (entry);
478
479   clock = GST_CLOCK_ENTRY_CLOCK (entry);
480
481   /* can't sync on invalid times */
482   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
483     goto invalid_time;
484
485   cclass = GST_CLOCK_GET_CLASS (clock);
486
487   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);
488
489   /* if we have a wait_jitter function, use that */
490   if (G_UNLIKELY (cclass->wait == NULL))
491     goto not_supported;
492
493   res = cclass->wait (clock, entry, jitter);
494
495   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
496       "done waiting entry %p, res: %d", id, res);
497
498   if (entry->type == GST_CLOCK_ENTRY_PERIODIC)
499     entry->time = requested + entry->interval;
500
501   if (G_UNLIKELY (clock->stats))
502     gst_clock_update_stats (clock);
503
504   return res;
505
506   /* ERRORS */
507 invalid_time:
508   {
509     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
510         "invalid time requested, returning _BADTIME");
511     return GST_CLOCK_BADTIME;
512   }
513 not_supported:
514   {
515     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
516     return GST_CLOCK_UNSUPPORTED;
517   }
518 }
519
520 /**
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
526  *
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.
532  *
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.
535  *
536  * Returns: the result of the non blocking wait.
537  *
538  * MT safe.
539  *
540  * Since: 0.10.30
541  */
542 GstClockReturn
543 gst_clock_id_wait_async_full (GstClockID id,
544     GstClockCallback func, gpointer user_data, GDestroyNotify destroy_data)
545 {
546   GstClockEntry *entry;
547   GstClock *clock;
548   GstClockReturn res;
549   GstClockClass *cclass;
550   GstClockTime requested;
551
552   g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
553   g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
554
555   entry = (GstClockEntry *) id;
556   requested = GST_CLOCK_ENTRY_TIME (entry);
557   clock = GST_CLOCK_ENTRY_CLOCK (entry);
558
559   /* can't sync on invalid times */
560   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
561     goto invalid_time;
562
563   cclass = GST_CLOCK_GET_CLASS (clock);
564
565   if (G_UNLIKELY (cclass->wait_async == NULL))
566     goto not_supported;
567
568   entry->func = func;
569   entry->user_data = user_data;
570   entry->destroy_data = destroy_data;
571
572   res = cclass->wait_async (clock, entry);
573
574   return res;
575
576   /* ERRORS */
577 invalid_time:
578   {
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;
583   }
584 not_supported:
585   {
586     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
587     return GST_CLOCK_UNSUPPORTED;
588   }
589 }
590
591 /**
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
596  *
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.
602  *
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.
605  *
606  * Returns: the result of the non blocking wait.
607  *
608  * MT safe.
609  */
610 GstClockReturn
611 gst_clock_id_wait_async (GstClockID id,
612     GstClockCallback func, gpointer user_data)
613 {
614   return gst_clock_id_wait_async_full (id, func, user_data, NULL);
615 }
616
617 /**
618  * gst_clock_id_unschedule:
619  * @id: The id to unschedule
620  *
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.
625  *
626  * MT safe.
627  */
628 void
629 gst_clock_id_unschedule (GstClockID id)
630 {
631   GstClockEntry *entry;
632   GstClock *clock;
633   GstClockClass *cclass;
634
635   g_return_if_fail (id != NULL);
636
637   entry = (GstClockEntry *) id;
638   clock = entry->clock;
639
640   cclass = GST_CLOCK_GET_CLASS (clock);
641
642   if (G_LIKELY (cclass->unschedule))
643     cclass->unschedule (clock, entry);
644 }
645
646
647 /*
648  * GstClock abstract base class implementation
649  */
650 #define gst_clock_parent_class parent_class
651 G_DEFINE_TYPE (GstClock, gst_clock, GST_TYPE_OBJECT);
652
653 static void
654 gst_clock_class_init (GstClockClass * klass)
655 {
656   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
657
658 #ifndef GST_DISABLE_TRACE
659   _gst_clock_entry_trace =
660       gst_alloc_trace_register (GST_CLOCK_ENTRY_TRACE_NAME);
661 #endif
662
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;
667
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));
686
687   g_type_class_add_private (klass, sizeof (GstClockPrivate));
688 }
689
690 static void
691 gst_clock_init (GstClock * clock)
692 {
693   clock->last_time = 0;
694   clock->entries = NULL;
695   clock->entries_changed = g_cond_new ();
696   clock->stats = FALSE;
697
698   clock->ABI.priv =
699       G_TYPE_INSTANCE_GET_PRIVATE (clock, GST_TYPE_CLOCK, GstClockPrivate);
700
701   clock->internal_calibration = 0;
702   clock->external_calibration = 0;
703   clock->rate_numerator = 1;
704   clock->rate_denominator = 1;
705
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);
713 }
714
715 static void
716 gst_clock_dispose (GObject * object)
717 {
718   GstClock *clock = GST_CLOCK (object);
719   GstClock **master_p;
720
721   GST_OBJECT_LOCK (clock);
722   master_p = &clock->master;
723   gst_object_replace ((GstObject **) master_p, NULL);
724   GST_OBJECT_UNLOCK (clock);
725
726   G_OBJECT_CLASS (parent_class)->dispose (object);
727 }
728
729 static void
730 gst_clock_finalize (GObject * object)
731 {
732   GstClock *clock = GST_CLOCK (object);
733
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;
739   }
740   g_free (clock->times);
741   clock->times = NULL;
742   GST_CLOCK_SLAVE_UNLOCK (clock);
743
744   g_cond_free (clock->entries_changed);
745   g_mutex_free (clock->slave_lock);
746
747   G_OBJECT_CLASS (parent_class)->finalize (object);
748 }
749
750 /**
751  * gst_clock_set_resolution
752  * @clock: a #GstClock
753  * @resolution: The resolution to set
754  *
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.
760  *
761  * Returns: the new resolution of the clock.
762  */
763 GstClockTime
764 gst_clock_set_resolution (GstClock * clock, GstClockTime resolution)
765 {
766   GstClockClass *cclass;
767
768   g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
769   g_return_val_if_fail (resolution != 0, 0);
770
771   cclass = GST_CLOCK_GET_CLASS (clock);
772
773   if (cclass->change_resolution)
774     clock->resolution =
775         cclass->change_resolution (clock, clock->resolution, resolution);
776
777   return clock->resolution;
778 }
779
780 /**
781  * gst_clock_get_resolution
782  * @clock: a #GstClock
783  *
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().
786  *
787  * Returns: the resolution of the clock in units of #GstClockTime.
788  *
789  * MT safe.
790  */
791 GstClockTime
792 gst_clock_get_resolution (GstClock * clock)
793 {
794   GstClockClass *cclass;
795
796   g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
797
798   cclass = GST_CLOCK_GET_CLASS (clock);
799
800   if (cclass->get_resolution)
801     return cclass->get_resolution (clock);
802
803   return 1;
804 }
805
806 /**
807  * gst_clock_adjust_unlocked
808  * @clock: a #GstClock to use
809  * @internal: a clock time
810  *
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.
815  *
816  * This function is the reverse of gst_clock_unadjust_unlocked().
817  *
818  * Returns: the converted time of the clock.
819  */
820 GstClockTime
821 gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
822 {
823   GstClockTime ret, cinternal, cexternal, cnum, cdenom;
824
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;
830
831   /* avoid divide by 0 */
832   if (G_UNLIKELY (cdenom == 0))
833     cnum = cdenom = 1;
834
835   /* The formula is (internal - cinternal) * cnum / cdenom + cexternal
836    *
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,
839    * though.
840    */
841   if (G_LIKELY (internal >= cinternal)) {
842     ret = internal - cinternal;
843     ret = gst_util_uint64_scale (ret, cnum, cdenom);
844     ret += cexternal;
845   } else {
846     ret = cinternal - internal;
847     ret = gst_util_uint64_scale (ret, cnum, cdenom);
848     /* clamp to 0 */
849     if (G_LIKELY (cexternal > ret))
850       ret = cexternal - ret;
851     else
852       ret = 0;
853   }
854
855   /* make sure the time is increasing */
856   clock->last_time = MAX (ret, clock->last_time);
857
858   return clock->last_time;
859 }
860
861 /**
862  * gst_clock_unadjust_unlocked
863  * @clock: a #GstClock to use
864  * @external: an external clock time
865  *
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.
870  *
871  * This function is the reverse of gst_clock_adjust_unlocked().
872  *
873  * Returns: the internal time of the clock corresponding to @external.
874  *
875  * Since: 0.10.13
876  */
877 GstClockTime
878 gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external)
879 {
880   GstClockTime ret, cinternal, cexternal, cnum, cdenom;
881
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;
887
888   /* avoid divide by 0 */
889   if (G_UNLIKELY (cnum == 0))
890     cnum = cdenom = 1;
891
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);
896     ret += cinternal;
897   } else {
898     ret = cexternal - external;
899     ret = gst_util_uint64_scale (ret, cdenom, cnum);
900     if (G_LIKELY (cinternal > ret))
901       ret = cinternal - ret;
902     else
903       ret = 0;
904   }
905   return ret;
906 }
907
908 /**
909  * gst_clock_get_internal_time
910  * @clock: a #GstClock to query
911  *
912  * Gets the current internal time of the given clock. The time is returned
913  * unadjusted for the offset and the rate.
914  *
915  * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
916  * given invalid input.
917  *
918  * MT safe.
919  */
920 GstClockTime
921 gst_clock_get_internal_time (GstClock * clock)
922 {
923   GstClockTime ret;
924   GstClockClass *cclass;
925
926   g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
927
928   cclass = GST_CLOCK_GET_CLASS (clock);
929
930   if (G_UNLIKELY (cclass->get_internal_time == NULL))
931     goto not_supported;
932
933   ret = cclass->get_internal_time (clock);
934
935   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
936       GST_TIME_ARGS (ret));
937
938   return ret;
939
940   /* ERRORS */
941 not_supported:
942   {
943     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
944         "internal time not supported, return 0");
945     return G_GINT64_CONSTANT (0);
946   }
947 }
948
949 /**
950  * gst_clock_get_time
951  * @clock: a #GstClock to query
952  *
953  * Gets the current time of the given clock. The time is always
954  * monotonically increasing and adjusted according to the current
955  * offset and rate.
956  *
957  * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when
958  * given invalid input.
959  *
960  * MT safe.
961  */
962 GstClockTime
963 gst_clock_get_time (GstClock * clock)
964 {
965   GstClockTime ret;
966   gint seq;
967
968   g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
969
970   do {
971     /* reget the internal time when we retry to get the most current
972      * timevalue */
973     ret = gst_clock_get_internal_time (clock);
974
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));
979
980   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "adjusted time %" GST_TIME_FORMAT,
981       GST_TIME_ARGS (ret));
982
983   return ret;
984 }
985
986 /**
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
992  *            internal time 
993  * @rate_denom: the denominator of the rate of the clock
994  *
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.
997  *
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.
1002  *
1003  * Subsequent calls to gst_clock_get_time() will return clock times computed as
1004  * follows:
1005  *
1006  * <programlisting>
1007  *   time = (internal_time - internal) * rate_num / rate_denom + external
1008  * </programlisting>
1009  *
1010  * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
1011  * tries to do the integer arithmetic as precisely as possible.
1012  *
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.
1016  *
1017  * MT safe.
1018  */
1019 void
1020 gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
1021     external, GstClockTime rate_num, GstClockTime rate_denom)
1022 {
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);
1026
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));
1033
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);
1039 }
1040
1041 /**
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
1048  *
1049  * Gets the internal rate and reference time of @clock. See
1050  * gst_clock_set_calibration() for more information.
1051  *
1052  * @internal, @external, @rate_num, and @rate_denom can be left %NULL if the
1053  * caller is not interested in the values.
1054  *
1055  * MT safe.
1056  */
1057 void
1058 gst_clock_get_calibration (GstClock * clock, GstClockTime * internal,
1059     GstClockTime * external, GstClockTime * rate_num, GstClockTime * rate_denom)
1060 {
1061   gint seq;
1062
1063   g_return_if_fail (GST_IS_CLOCK (clock));
1064
1065   do {
1066     seq = read_seqbegin (clock);
1067     if (rate_num)
1068       *rate_num = clock->rate_numerator;
1069     if (rate_denom)
1070       *rate_denom = clock->rate_denominator;
1071     if (external)
1072       *external = clock->external_calibration;
1073     if (internal)
1074       *internal = clock->internal_calibration;
1075   } while (read_seqretry (clock, seq));
1076 }
1077
1078 /* will be called repeatedly to sample the master and slave clock
1079  * to recalibrate the clock  */
1080 static gboolean
1081 gst_clock_slave_callback (GstClock * master, GstClockTime time,
1082     GstClockID id, GstClock * clock)
1083 {
1084   GstClockTime stime, mtime;
1085   gdouble r_squared;
1086
1087   stime = gst_clock_get_internal_time (clock);
1088   mtime = gst_clock_get_time (master);
1089
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));
1093
1094   gst_clock_add_observation (clock, stime, mtime, &r_squared);
1095
1096   /* FIXME, we can use the r_squared value to adjust the timeout
1097    * value of the clockid */
1098
1099   return TRUE;
1100 }
1101
1102 /**
1103  * gst_clock_set_master
1104  * @clock: a #GstClock 
1105  * @master: (allow-none): a master #GstClock 
1106  *
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
1109  * master clock.  
1110  * 
1111  * A clock provider that slaves its clock to a master can get the current
1112  * calibration values with gst_clock_get_calibration().
1113  *
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 
1116  * and time offsets.
1117  *
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.
1121  *
1122  * MT safe.
1123  */
1124 gboolean
1125 gst_clock_set_master (GstClock * clock, GstClock * master)
1126 {
1127   GstClock **master_p;
1128
1129   g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1130   g_return_val_if_fail (master != clock, FALSE);
1131
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))
1135     goto not_supported;
1136   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1137       "slaving %p to master clock %p", clock, master);
1138   GST_OBJECT_UNLOCK (clock);
1139
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;
1145   }
1146   if (master) {
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);
1156   }
1157   GST_CLOCK_SLAVE_UNLOCK (clock);
1158
1159   GST_OBJECT_LOCK (clock);
1160   master_p = &clock->master;
1161   gst_object_replace ((GstObject **) master_p, (GstObject *) master);
1162   GST_OBJECT_UNLOCK (clock);
1163
1164   return TRUE;
1165
1166   /* ERRORS */
1167 not_supported:
1168   {
1169     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1170         "cannot be slaved to a master clock");
1171     GST_OBJECT_UNLOCK (clock);
1172     return FALSE;
1173   }
1174 }
1175
1176 /**
1177  * gst_clock_get_master:
1178  * @clock: a #GstClock 
1179  *
1180  * Get the master clock that @clock is slaved to or %NULL when the clock is
1181  * not slaved to any master clock.
1182  *
1183  * Returns: (transfer full): a master #GstClock or %NULL when this clock is
1184  *     not slaved to a master clock. Unref after usage.
1185  *
1186  * MT safe.
1187  */
1188 GstClock *
1189 gst_clock_get_master (GstClock * clock)
1190 {
1191   GstClock *result = NULL;
1192
1193   g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
1194
1195   GST_OBJECT_LOCK (clock);
1196   if (clock->master)
1197     result = gst_object_ref (clock->master);
1198   GST_OBJECT_UNLOCK (clock);
1199
1200   return result;
1201 }
1202
1203 /* http://mathworld.wolfram.com/LeastSquaresFitting.html
1204  * with SLAVE_LOCK
1205  */
1206 static gboolean
1207 do_linear_regression (GstClock * clock, GstClockTime * m_num,
1208     GstClockTime * m_denom, GstClockTime * b, GstClockTime * xbase,
1209     gdouble * r_squared)
1210 {
1211   GstClockTime *newx, *newy;
1212   GstClockTime xmin, ymin, xbar, ybar, xbar4, ybar4;
1213   GstClockTimeDiff sxx, sxy, syy;
1214   GstClockTime *x, *y;
1215   gint i, j;
1216   guint n;
1217
1218   xbar = ybar = sxx = syy = sxy = 0;
1219
1220   x = clock->times;
1221   y = clock->times + 2;
1222   n = clock->filling ? clock->time_index : clock->window_size;
1223
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]);
1229 #endif
1230
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]);
1235   }
1236
1237 #ifdef DEBUGGING_ENABLED
1238   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min x: %" G_GUINT64_FORMAT,
1239       xmin);
1240   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min y: %" G_GUINT64_FORMAT,
1241       ymin);
1242 #endif
1243
1244   newx = clock->times + 1;
1245   newy = clock->times + 3;
1246
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;
1251   }
1252
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]);
1258 #endif
1259
1260   /* have to do this precisely otherwise the results are pretty much useless.
1261    * should guarantee that none of these accumulators can overflow */
1262
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) {
1266     xbar += newx[j];
1267     ybar += newy[j];
1268   }
1269   xbar /= n;
1270   ybar /= n;
1271
1272 #ifdef DEBUGGING_ENABLED
1273   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  xbar  = %" G_GUINT64_FORMAT,
1274       xbar);
1275   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  ybar  = %" G_GUINT64_FORMAT,
1276       ybar);
1277 #endif
1278
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. */
1285   xbar4 = xbar >> 4;
1286   ybar4 = ybar >> 4;
1287   for (i = j = 0; i < n; i++, j += 4) {
1288     GstClockTime newx4, newy4;
1289
1290     newx4 = newx[j] >> 4;
1291     newy4 = newy[j] >> 4;
1292
1293     sxx += newx4 * newx4 - xbar4 * xbar4;
1294     syy += newy4 * newy4 - ybar4 * ybar4;
1295     sxy += newx4 * newy4 - xbar4 * ybar4;
1296   }
1297
1298   if (G_UNLIKELY (sxx == 0))
1299     goto invalid;
1300
1301   *m_num = sxy;
1302   *m_denom = sxx;
1303   *xbase = xmin;
1304   *b = (ybar + ymin) - gst_util_uint64_scale (xbar, *m_num, *m_denom);
1305   *r_squared = ((double) sxy * (double) sxy) / ((double) sxx * (double) syy);
1306
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,
1311       *b);
1312   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  xbase  = %" G_GUINT64_FORMAT,
1313       *xbase);
1314   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  r2     = %g", *r_squared);
1315 #endif
1316
1317   return TRUE;
1318
1319 invalid:
1320   {
1321     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "sxx == 0, regression failed");
1322     return FALSE;
1323   }
1324 }
1325
1326 /**
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
1332  *
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.
1337  *
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
1342  * clocks.
1343  *
1344  * Returns: %TRUE if enough observations were added to run the 
1345  * regression algorithm.
1346  *
1347  * MT safe.
1348  */
1349 gboolean
1350 gst_clock_add_observation (GstClock * clock, GstClockTime slave,
1351     GstClockTime master, gdouble * r_squared)
1352 {
1353   GstClockTime m_num, m_denom, b, xbase;
1354
1355   g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1356   g_return_val_if_fail (r_squared != NULL, FALSE);
1357
1358   GST_CLOCK_SLAVE_LOCK (clock);
1359
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));
1363
1364   clock->times[(4 * clock->time_index)] = slave;
1365   clock->times[(4 * clock->time_index) + 2] = master;
1366
1367   clock->time_index++;
1368   if (G_UNLIKELY (clock->time_index == clock->window_size)) {
1369     clock->filling = FALSE;
1370     clock->time_index = 0;
1371   }
1372
1373   if (G_UNLIKELY (clock->filling
1374           && clock->time_index < clock->window_threshold))
1375     goto filling;
1376
1377   if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared))
1378     goto invalid;
1379
1380   GST_CLOCK_SLAVE_UNLOCK (clock);
1381
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);
1385
1386   /* if we have a valid regression, adjust the clock */
1387   gst_clock_set_calibration (clock, xbase, b, m_num, m_denom);
1388
1389   return TRUE;
1390
1391 filling:
1392   {
1393     GST_CLOCK_SLAVE_UNLOCK (clock);
1394     return FALSE;
1395   }
1396 invalid:
1397   {
1398     /* no valid regression has been done, ignore the result then */
1399     GST_CLOCK_SLAVE_UNLOCK (clock);
1400     return TRUE;
1401   }
1402 }
1403
1404 static void
1405 gst_clock_update_stats (GstClock * clock)
1406 {
1407 }
1408
1409 static void
1410 gst_clock_set_property (GObject * object, guint prop_id,
1411     const GValue * value, GParamSpec * pspec)
1412 {
1413   GstClock *clock;
1414
1415   clock = GST_CLOCK (object);
1416
1417   switch (prop_id) {
1418     case PROP_STATS:
1419       GST_OBJECT_LOCK (clock);
1420       clock->stats = g_value_get_boolean (value);
1421       GST_OBJECT_UNLOCK (clock);
1422       break;
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);
1428       clock->times =
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);
1434       break;
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);
1440       break;
1441     case PROP_TIMEOUT:
1442       GST_CLOCK_SLAVE_LOCK (clock);
1443       clock->timeout = g_value_get_uint64 (value);
1444       GST_CLOCK_SLAVE_UNLOCK (clock);
1445       break;
1446     default:
1447       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1448       break;
1449   }
1450 }
1451
1452 static void
1453 gst_clock_get_property (GObject * object, guint prop_id,
1454     GValue * value, GParamSpec * pspec)
1455 {
1456   GstClock *clock;
1457
1458   clock = GST_CLOCK (object);
1459
1460   switch (prop_id) {
1461     case PROP_STATS:
1462       GST_OBJECT_LOCK (clock);
1463       g_value_set_boolean (value, clock->stats);
1464       GST_OBJECT_UNLOCK (clock);
1465       break;
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);
1470       break;
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);
1475       break;
1476     case PROP_TIMEOUT:
1477       GST_CLOCK_SLAVE_LOCK (clock);
1478       g_value_set_uint64 (value, clock->timeout);
1479       GST_CLOCK_SLAVE_UNLOCK (clock);
1480       break;
1481     default:
1482       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1483       break;
1484   }
1485 }