clock: remove _full version
[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 2012-03-28 (0.11.3)
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 #include "glib-compat-private.h"
113
114 #ifndef GST_DISABLE_TRACE
115 /* #define GST_WITH_ALLOC_TRACE */
116 #include "gsttrace.h"
117 static GstAllocTrace *_gst_clock_entry_trace;
118 #endif
119
120 /* #define DEBUGGING_ENABLED */
121
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_WINDOW_SIZE,
130   PROP_WINDOW_THRESHOLD,
131   PROP_TIMEOUT
132 };
133
134 #define GST_CLOCK_SLAVE_LOCK(clock)     g_mutex_lock (&GST_CLOCK_CAST (clock)->priv->slave_lock)
135 #define GST_CLOCK_SLAVE_UNLOCK(clock)   g_mutex_unlock (&GST_CLOCK_CAST (clock)->priv->slave_lock)
136
137 struct _GstClockPrivate
138 {
139   GMutex slave_lock;            /* order: SLAVE_LOCK, OBJECT_LOCK */
140
141   /* with LOCK */
142   GstClockTime internal_calibration;
143   GstClockTime external_calibration;
144   GstClockTime rate_numerator;
145   GstClockTime rate_denominator;
146   GstClockTime last_time;
147
148   /* with LOCK */
149   GstClockTime resolution;
150
151   /* for master/slave clocks */
152   GstClock *master;
153
154   /* with SLAVE_LOCK */
155   gboolean filling;
156   gint window_size;
157   gint window_threshold;
158   gint time_index;
159   GstClockTime timeout;
160   GstClockTime *times;
161   GstClockID clockid;
162
163   gint pre_count;
164   gint post_count;
165 };
166
167 /* seqlocks */
168 #define read_seqbegin(clock)                                   \
169   g_atomic_int_get (&clock->priv->post_count);
170
171 static inline gboolean
172 read_seqretry (GstClock * clock, gint seq)
173 {
174   /* no retry if the seqnum did not change */
175   if (G_LIKELY (seq == g_atomic_int_get (&clock->priv->pre_count)))
176     return FALSE;
177
178   /* wait for the writer to finish and retry */
179   GST_OBJECT_LOCK (clock);
180   GST_OBJECT_UNLOCK (clock);
181   return TRUE;
182 }
183
184 #define write_seqlock(clock)                      \
185 G_STMT_START {                                    \
186   GST_OBJECT_LOCK (clock);                        \
187   g_atomic_int_inc (&clock->priv->pre_count);     \
188 } G_STMT_END;
189
190 #define write_sequnlock(clock)                    \
191 G_STMT_START {                                    \
192   g_atomic_int_inc (&clock->priv->post_count);    \
193   GST_OBJECT_UNLOCK (clock);                      \
194 } G_STMT_END;
195
196 static void gst_clock_dispose (GObject * object);
197 static void gst_clock_finalize (GObject * object);
198
199 static void gst_clock_set_property (GObject * object, guint prop_id,
200     const GValue * value, GParamSpec * pspec);
201 static void gst_clock_get_property (GObject * object, guint prop_id,
202     GValue * value, GParamSpec * pspec);
203
204 /* static guint gst_clock_signals[LAST_SIGNAL] = { 0 }; */
205
206 static GstClockID
207 gst_clock_entry_new (GstClock * clock, GstClockTime time,
208     GstClockTime interval, GstClockEntryType type)
209 {
210   GstClockEntry *entry;
211
212   entry = g_slice_new (GstClockEntry);
213 #ifndef GST_DISABLE_TRACE
214   _gst_alloc_trace_new (_gst_clock_entry_trace, entry);
215 #endif
216   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
217       "created entry %p, time %" GST_TIME_FORMAT, entry, GST_TIME_ARGS (time));
218
219   entry->refcount = 1;
220   entry->clock = clock;
221   entry->type = type;
222   entry->time = time;
223   entry->interval = interval;
224   entry->status = GST_CLOCK_OK;
225   entry->func = NULL;
226   entry->user_data = NULL;
227   entry->destroy_data = NULL;
228   entry->unscheduled = FALSE;
229   entry->woken_up = FALSE;
230
231   return (GstClockID) entry;
232 }
233
234 /* WARNING : Does not modify the refcount
235  * WARNING : Do not use if a pending clock operation is happening on that entry */
236 static gboolean
237 gst_clock_entry_reinit (GstClock * clock, GstClockEntry * entry,
238     GstClockTime time, GstClockTime interval, GstClockEntryType type)
239 {
240   g_return_val_if_fail (entry->status != GST_CLOCK_BUSY, FALSE);
241   g_return_val_if_fail (entry->clock == clock, FALSE);
242
243   entry->type = type;
244   entry->time = time;
245   entry->interval = interval;
246   entry->status = GST_CLOCK_OK;
247   entry->unscheduled = FALSE;
248   entry->woken_up = FALSE;
249
250   return TRUE;
251 }
252
253 /**
254  * gst_clock_single_shot_id_reinit:
255  * @clock: a #GstClock
256  * @id: a #GstClockID
257  * @time: The requested time.
258  *
259  * Reinitializes the provided single shot @id to the provided time. Does not
260  * modify the reference count.
261  *
262  * Returns: %TRUE if the GstClockID could be reinitialized to the provided
263  * @time, else %FALSE.
264  *
265  * Since: 0.10.32
266  */
267 gboolean
268 gst_clock_single_shot_id_reinit (GstClock * clock, GstClockID id,
269     GstClockTime time)
270 {
271   return gst_clock_entry_reinit (clock, (GstClockEntry *) id, time,
272       GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
273 }
274
275 /**
276  * gst_clock_periodic_id_reinit:
277  * @clock: a #GstClock
278  * @id: a #GstClockID
279  * @start_time: the requested start time
280  * @interval: the requested interval
281  *
282  * Reinitializes the provided periodic @id to the provided start time and
283  * interval. Does not modify the reference count.
284  *
285  * Returns: %TRUE if the GstClockID could be reinitialized to the provided
286  * @time, else %FALSE.
287  *
288  * Since: 0.10.33
289  *
290  */
291 gboolean
292 gst_clock_periodic_id_reinit (GstClock * clock, GstClockID id,
293     GstClockTime start_time, GstClockTime interval)
294 {
295   return gst_clock_entry_reinit (clock, (GstClockEntry *) id, start_time,
296       interval, GST_CLOCK_ENTRY_PERIODIC);
297 }
298
299 /**
300  * gst_clock_id_ref:
301  * @id: The #GstClockID to ref
302  *
303  * Increase the refcount of given @id.
304  *
305  * Returns: (transfer full): The same #GstClockID with increased refcount.
306  *
307  * MT safe.
308  */
309 GstClockID
310 gst_clock_id_ref (GstClockID id)
311 {
312   g_return_val_if_fail (id != NULL, NULL);
313
314   g_atomic_int_inc (&((GstClockEntry *) id)->refcount);
315
316   return id;
317 }
318
319 static void
320 _gst_clock_id_free (GstClockID id)
321 {
322   GstClockEntry *entry;
323   g_return_if_fail (id != NULL);
324
325   GST_CAT_DEBUG (GST_CAT_CLOCK, "freed entry %p", id);
326   entry = (GstClockEntry *) id;
327   if (entry->destroy_data)
328     entry->destroy_data (entry->user_data);
329
330 #ifndef GST_DISABLE_TRACE
331   _gst_alloc_trace_free (_gst_clock_entry_trace, id);
332 #endif
333   g_slice_free (GstClockEntry, id);
334 }
335
336 /**
337  * gst_clock_id_unref:
338  * @id: (transfer full): The #GstClockID to unref
339  *
340  * Unref given @id. When the refcount reaches 0 the
341  * #GstClockID will be freed.
342  *
343  * MT safe.
344  */
345 void
346 gst_clock_id_unref (GstClockID id)
347 {
348   gint zero;
349
350   g_return_if_fail (id != NULL);
351
352   zero = g_atomic_int_dec_and_test (&((GstClockEntry *) id)->refcount);
353   /* if we ended up with the refcount at zero, free the id */
354   if (zero) {
355     _gst_clock_id_free (id);
356   }
357 }
358
359 /**
360  * gst_clock_new_single_shot_id:
361  * @clock: The #GstClockID to get a single shot notification from
362  * @time: the requested time
363  *
364  * Get a #GstClockID from @clock to trigger a single shot
365  * notification at the requested time. The single shot id should be
366  * unreffed after usage.
367  *
368  * Free-function: gst_clock_id_unref
369  *
370  * Returns: (transfer full): a #GstClockID that can be used to request the
371  *     time notification.
372  *
373  * MT safe.
374  */
375 GstClockID
376 gst_clock_new_single_shot_id (GstClock * clock, GstClockTime time)
377 {
378   g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
379
380   return gst_clock_entry_new (clock,
381       time, GST_CLOCK_TIME_NONE, GST_CLOCK_ENTRY_SINGLE);
382 }
383
384 /**
385  * gst_clock_new_periodic_id:
386  * @clock: The #GstClockID to get a periodic notification id from
387  * @start_time: the requested start time
388  * @interval: the requested interval
389  *
390  * Get an ID from @clock to trigger a periodic notification.
391  * The periodic notifications will start at time @start_time and
392  * will then be fired with the given @interval. @id should be unreffed
393  * after usage.
394  *
395  * Free-function: gst_clock_id_unref
396  *
397  * Returns: (transfer full): a #GstClockID that can be used to request the
398  *     time notification.
399  *
400  * MT safe.
401  */
402 GstClockID
403 gst_clock_new_periodic_id (GstClock * clock, GstClockTime start_time,
404     GstClockTime interval)
405 {
406   g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
407   g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (start_time), NULL);
408   g_return_val_if_fail (interval != 0, NULL);
409   g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), NULL);
410
411   return gst_clock_entry_new (clock,
412       start_time, interval, GST_CLOCK_ENTRY_PERIODIC);
413 }
414
415 /**
416  * gst_clock_id_compare_func:
417  * @id1: A #GstClockID
418  * @id2: A #GstClockID to compare with
419  *
420  * Compares the two #GstClockID instances. This function can be used
421  * as a GCompareFunc when sorting ids.
422  *
423  * Returns: negative value if a < b; zero if a = b; positive value if a > b
424  *
425  * MT safe.
426  */
427 gint
428 gst_clock_id_compare_func (gconstpointer id1, gconstpointer id2)
429 {
430   GstClockEntry *entry1, *entry2;
431
432   entry1 = (GstClockEntry *) id1;
433   entry2 = (GstClockEntry *) id2;
434
435   if (GST_CLOCK_ENTRY_TIME (entry1) > GST_CLOCK_ENTRY_TIME (entry2)) {
436     return 1;
437   }
438   if (GST_CLOCK_ENTRY_TIME (entry1) < GST_CLOCK_ENTRY_TIME (entry2)) {
439     return -1;
440   }
441   return 0;
442 }
443
444 /**
445  * gst_clock_id_get_time:
446  * @id: The #GstClockID to query
447  *
448  * Get the time of the clock ID
449  *
450  * Returns: the time of the given clock id.
451  *
452  * MT safe.
453  */
454 GstClockTime
455 gst_clock_id_get_time (GstClockID id)
456 {
457   g_return_val_if_fail (id != NULL, GST_CLOCK_TIME_NONE);
458
459   return GST_CLOCK_ENTRY_TIME ((GstClockEntry *) id);
460 }
461
462 /**
463  * gst_clock_id_wait:
464  * @id: The #GstClockID to wait on
465  * @jitter: (out) (allow-none): a pointer that will contain the jitter,
466  *     can be %NULL.
467  *
468  * Perform a blocking wait on @id. 
469  * @id should have been created with gst_clock_new_single_shot_id()
470  * or gst_clock_new_periodic_id() and should not have been unscheduled
471  * with a call to gst_clock_id_unschedule(). 
472  *
473  * If the @jitter argument is not %NULL and this function returns #GST_CLOCK_OK
474  * or #GST_CLOCK_EARLY, it will contain the difference
475  * against the clock and the time of @id when this method was
476  * called. 
477  * Positive values indicate how late @id was relative to the clock
478  * (in which case this function will return #GST_CLOCK_EARLY). 
479  * Negative values indicate how much time was spent waiting on the clock 
480  * before this function returned.
481  *
482  * Returns: the result of the blocking wait. #GST_CLOCK_EARLY will be returned
483  * if the current clock time is past the time of @id, #GST_CLOCK_OK if 
484  * @id was scheduled in time. #GST_CLOCK_UNSCHEDULED if @id was 
485  * unscheduled with gst_clock_id_unschedule().
486  *
487  * MT safe.
488  */
489 GstClockReturn
490 gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
491 {
492   GstClockEntry *entry;
493   GstClock *clock;
494   GstClockReturn res;
495   GstClockTime requested;
496   GstClockClass *cclass;
497
498   g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
499
500   entry = (GstClockEntry *) id;
501   requested = GST_CLOCK_ENTRY_TIME (entry);
502
503   clock = GST_CLOCK_ENTRY_CLOCK (entry);
504
505   /* can't sync on invalid times */
506   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
507     goto invalid_time;
508
509   cclass = GST_CLOCK_GET_CLASS (clock);
510
511   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);
512
513   /* if we have a wait_jitter function, use that */
514   if (G_UNLIKELY (cclass->wait == NULL))
515     goto not_supported;
516
517   res = cclass->wait (clock, entry, jitter);
518
519   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
520       "done waiting entry %p, res: %d", id, res);
521
522   if (entry->type == GST_CLOCK_ENTRY_PERIODIC)
523     entry->time = requested + entry->interval;
524
525   return res;
526
527   /* ERRORS */
528 invalid_time:
529   {
530     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
531         "invalid time requested, returning _BADTIME");
532     return GST_CLOCK_BADTIME;
533   }
534 not_supported:
535   {
536     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
537     return GST_CLOCK_UNSUPPORTED;
538   }
539 }
540
541 /**
542  * gst_clock_id_wait_async:
543  * @id: a #GstClockID to wait on
544  * @func: The callback function
545  * @user_data: User data passed in the callback
546  * @destroy_data: #GDestroyNotify for user_data
547  *
548  * Register a callback on the given #GstClockID @id with the given
549  * function and user_data. When passing a #GstClockID with an invalid
550  * time to this function, the callback will be called immediately
551  * with  a time set to GST_CLOCK_TIME_NONE. The callback will
552  * be called when the time of @id has been reached.
553  *
554  * The callback @func can be invoked from any thread, either provided by the
555  * core or from a streaming thread. The application should be prepared for this.
556  *
557  * Returns: the result of the non blocking wait.
558  *
559  * MT safe.
560  *
561  * Since: 0.10.30
562  */
563 GstClockReturn
564 gst_clock_id_wait_async (GstClockID id,
565     GstClockCallback func, gpointer user_data, GDestroyNotify destroy_data)
566 {
567   GstClockEntry *entry;
568   GstClock *clock;
569   GstClockReturn res;
570   GstClockClass *cclass;
571   GstClockTime requested;
572
573   g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
574   g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);
575
576   entry = (GstClockEntry *) id;
577   requested = GST_CLOCK_ENTRY_TIME (entry);
578   clock = GST_CLOCK_ENTRY_CLOCK (entry);
579
580   /* can't sync on invalid times */
581   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
582     goto invalid_time;
583
584   cclass = GST_CLOCK_GET_CLASS (clock);
585
586   if (G_UNLIKELY (cclass->wait_async == NULL))
587     goto not_supported;
588
589   entry->func = func;
590   entry->user_data = user_data;
591   entry->destroy_data = destroy_data;
592
593   res = cclass->wait_async (clock, entry);
594
595   return res;
596
597   /* ERRORS */
598 invalid_time:
599   {
600     (func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
601     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
602         "invalid time requested, returning _BADTIME");
603     return GST_CLOCK_BADTIME;
604   }
605 not_supported:
606   {
607     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
608     return GST_CLOCK_UNSUPPORTED;
609   }
610 }
611
612 /**
613  * gst_clock_id_unschedule:
614  * @id: The id to unschedule
615  *
616  * Cancel an outstanding request with @id. This can either
617  * be an outstanding async notification or a pending sync notification.
618  * After this call, @id cannot be used anymore to receive sync or
619  * async notifications, you need to create a new #GstClockID.
620  *
621  * MT safe.
622  */
623 void
624 gst_clock_id_unschedule (GstClockID id)
625 {
626   GstClockEntry *entry;
627   GstClock *clock;
628   GstClockClass *cclass;
629
630   g_return_if_fail (id != NULL);
631
632   entry = (GstClockEntry *) id;
633   clock = entry->clock;
634
635   cclass = GST_CLOCK_GET_CLASS (clock);
636
637   if (G_LIKELY (cclass->unschedule))
638     cclass->unschedule (clock, entry);
639 }
640
641
642 /*
643  * GstClock abstract base class implementation
644  */
645 #define gst_clock_parent_class parent_class
646 G_DEFINE_TYPE (GstClock, gst_clock, GST_TYPE_OBJECT);
647
648 static void
649 gst_clock_class_init (GstClockClass * klass)
650 {
651   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
652
653 #ifndef GST_DISABLE_TRACE
654   _gst_clock_entry_trace = _gst_alloc_trace_register ("GstClockEntry", -1);
655 #endif
656
657   gobject_class->dispose = gst_clock_dispose;
658   gobject_class->finalize = gst_clock_finalize;
659   gobject_class->set_property = gst_clock_set_property;
660   gobject_class->get_property = gst_clock_get_property;
661
662   g_object_class_install_property (gobject_class, PROP_WINDOW_SIZE,
663       g_param_spec_int ("window-size", "Window size",
664           "The size of the window used to calculate rate and offset", 2, 1024,
665           DEFAULT_WINDOW_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
666   g_object_class_install_property (gobject_class, PROP_WINDOW_THRESHOLD,
667       g_param_spec_int ("window-threshold", "Window threshold",
668           "The threshold to start calculating rate and offset", 2, 1024,
669           DEFAULT_WINDOW_THRESHOLD,
670           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
671   g_object_class_install_property (gobject_class, PROP_TIMEOUT,
672       g_param_spec_uint64 ("timeout", "Timeout",
673           "The amount of time, in nanoseconds, to sample master and slave clocks",
674           0, G_MAXUINT64, DEFAULT_TIMEOUT,
675           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
676
677   g_type_class_add_private (klass, sizeof (GstClockPrivate));
678 }
679
680 static void
681 gst_clock_init (GstClock * clock)
682 {
683   GstClockPrivate *priv;
684
685   clock->priv = priv =
686       G_TYPE_INSTANCE_GET_PRIVATE (clock, GST_TYPE_CLOCK, GstClockPrivate);
687
688   priv->last_time = 0;
689
690   priv->internal_calibration = 0;
691   priv->external_calibration = 0;
692   priv->rate_numerator = 1;
693   priv->rate_denominator = 1;
694
695   g_mutex_init (&priv->slave_lock);
696   priv->window_size = DEFAULT_WINDOW_SIZE;
697   priv->window_threshold = DEFAULT_WINDOW_THRESHOLD;
698   priv->filling = TRUE;
699   priv->time_index = 0;
700   priv->timeout = DEFAULT_TIMEOUT;
701   priv->times = g_new0 (GstClockTime, 4 * priv->window_size);
702 }
703
704 static void
705 gst_clock_dispose (GObject * object)
706 {
707   GstClock *clock = GST_CLOCK (object);
708   GstClock **master_p;
709
710   GST_OBJECT_LOCK (clock);
711   master_p = &clock->priv->master;
712   gst_object_replace ((GstObject **) master_p, NULL);
713   GST_OBJECT_UNLOCK (clock);
714
715   G_OBJECT_CLASS (parent_class)->dispose (object);
716 }
717
718 static void
719 gst_clock_finalize (GObject * object)
720 {
721   GstClock *clock = GST_CLOCK (object);
722
723   GST_CLOCK_SLAVE_LOCK (clock);
724   if (clock->priv->clockid) {
725     gst_clock_id_unschedule (clock->priv->clockid);
726     gst_clock_id_unref (clock->priv->clockid);
727     clock->priv->clockid = NULL;
728   }
729   g_free (clock->priv->times);
730   clock->priv->times = NULL;
731   GST_CLOCK_SLAVE_UNLOCK (clock);
732
733   g_mutex_clear (&clock->priv->slave_lock);
734
735   G_OBJECT_CLASS (parent_class)->finalize (object);
736 }
737
738 /**
739  * gst_clock_set_resolution:
740  * @clock: a #GstClock
741  * @resolution: The resolution to set
742  *
743  * Set the accuracy of the clock. Some clocks have the possibility to operate
744  * with different accuracy at the expense of more resource usage. There is
745  * normally no need to change the default resolution of a clock. The resolution
746  * of a clock can only be changed if the clock has the
747  * #GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set.
748  *
749  * Returns: the new resolution of the clock.
750  */
751 GstClockTime
752 gst_clock_set_resolution (GstClock * clock, GstClockTime resolution)
753 {
754   GstClockPrivate *priv;
755   GstClockClass *cclass;
756
757   g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
758   g_return_val_if_fail (resolution != 0, 0);
759
760   cclass = GST_CLOCK_GET_CLASS (clock);
761   priv = clock->priv;
762
763   if (cclass->change_resolution)
764     priv->resolution =
765         cclass->change_resolution (clock, priv->resolution, resolution);
766
767   return priv->resolution;
768 }
769
770 /**
771  * gst_clock_get_resolution:
772  * @clock: a #GstClock
773  *
774  * Get the accuracy of the clock. The accuracy of the clock is the granularity
775  * of the values returned by gst_clock_get_time().
776  *
777  * Returns: the resolution of the clock in units of #GstClockTime.
778  *
779  * MT safe.
780  */
781 GstClockTime
782 gst_clock_get_resolution (GstClock * clock)
783 {
784   GstClockClass *cclass;
785
786   g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
787
788   cclass = GST_CLOCK_GET_CLASS (clock);
789
790   if (cclass->get_resolution)
791     return cclass->get_resolution (clock);
792
793   return 1;
794 }
795
796 /**
797  * gst_clock_adjust_unlocked:
798  * @clock: a #GstClock to use
799  * @internal: a clock time
800  *
801  * Converts the given @internal clock time to the external time, adjusting for the
802  * rate and reference time set with gst_clock_set_calibration() and making sure
803  * that the returned time is increasing. This function should be called with the
804  * clock's OBJECT_LOCK held and is mainly used by clock subclasses.
805  *
806  * This function is the reverse of gst_clock_unadjust_unlocked().
807  *
808  * Returns: the converted time of the clock.
809  */
810 GstClockTime
811 gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
812 {
813   GstClockTime ret, cinternal, cexternal, cnum, cdenom;
814   GstClockPrivate *priv = clock->priv;
815
816   /* get calibration values for readability */
817   cinternal = priv->internal_calibration;
818   cexternal = priv->external_calibration;
819   cnum = priv->rate_numerator;
820   cdenom = priv->rate_denominator;
821
822   /* avoid divide by 0 */
823   if (G_UNLIKELY (cdenom == 0))
824     cnum = cdenom = 1;
825
826   /* The formula is (internal - cinternal) * cnum / cdenom + cexternal
827    *
828    * Since we do math on unsigned 64-bit ints we have to special case for
829    * internal < cinternal to get the sign right. this case is not very common,
830    * though.
831    */
832   if (G_LIKELY (internal >= cinternal)) {
833     ret = internal - cinternal;
834     ret = gst_util_uint64_scale (ret, cnum, cdenom);
835     ret += cexternal;
836   } else {
837     ret = cinternal - internal;
838     ret = gst_util_uint64_scale (ret, cnum, cdenom);
839     /* clamp to 0 */
840     if (G_LIKELY (cexternal > ret))
841       ret = cexternal - ret;
842     else
843       ret = 0;
844   }
845
846   /* make sure the time is increasing */
847   priv->last_time = MAX (ret, priv->last_time);
848
849   return priv->last_time;
850 }
851
852 /**
853  * gst_clock_unadjust_unlocked:
854  * @clock: a #GstClock to use
855  * @external: an external clock time
856  *
857  * Converts the given @external clock time to the internal time of @clock,
858  * using the rate and reference time set with gst_clock_set_calibration().
859  * This function should be called with the clock's OBJECT_LOCK held and
860  * is mainly used by clock subclasses.
861  *
862  * This function is the reverse of gst_clock_adjust_unlocked().
863  *
864  * Returns: the internal time of the clock corresponding to @external.
865  *
866  * Since: 0.10.13
867  */
868 GstClockTime
869 gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external)
870 {
871   GstClockTime ret, cinternal, cexternal, cnum, cdenom;
872   GstClockPrivate *priv = clock->priv;
873
874   /* get calibration values for readability */
875   cinternal = priv->internal_calibration;
876   cexternal = priv->external_calibration;
877   cnum = priv->rate_numerator;
878   cdenom = priv->rate_denominator;
879
880   /* avoid divide by 0 */
881   if (G_UNLIKELY (cnum == 0))
882     cnum = cdenom = 1;
883
884   /* The formula is (external - cexternal) * cdenom / cnum + cinternal */
885   if (G_LIKELY (external >= cexternal)) {
886     ret = external - cexternal;
887     ret = gst_util_uint64_scale (ret, cdenom, cnum);
888     ret += cinternal;
889   } else {
890     ret = cexternal - external;
891     ret = gst_util_uint64_scale (ret, cdenom, cnum);
892     if (G_LIKELY (cinternal > ret))
893       ret = cinternal - ret;
894     else
895       ret = 0;
896   }
897   return ret;
898 }
899
900 /**
901  * gst_clock_get_internal_time:
902  * @clock: a #GstClock to query
903  *
904  * Gets the current internal time of the given clock. The time is returned
905  * unadjusted for the offset and the rate.
906  *
907  * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
908  * given invalid input.
909  *
910  * MT safe.
911  */
912 GstClockTime
913 gst_clock_get_internal_time (GstClock * clock)
914 {
915   GstClockTime ret;
916   GstClockClass *cclass;
917
918   g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
919
920   cclass = GST_CLOCK_GET_CLASS (clock);
921
922   if (G_UNLIKELY (cclass->get_internal_time == NULL))
923     goto not_supported;
924
925   ret = cclass->get_internal_time (clock);
926
927   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
928       GST_TIME_ARGS (ret));
929
930   return ret;
931
932   /* ERRORS */
933 not_supported:
934   {
935     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
936         "internal time not supported, return 0");
937     return G_GINT64_CONSTANT (0);
938   }
939 }
940
941 /**
942  * gst_clock_get_time:
943  * @clock: a #GstClock to query
944  *
945  * Gets the current time of the given clock. The time is always
946  * monotonically increasing and adjusted according to the current
947  * offset and rate.
948  *
949  * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when
950  * given invalid input.
951  *
952  * MT safe.
953  */
954 GstClockTime
955 gst_clock_get_time (GstClock * clock)
956 {
957   GstClockTime ret;
958   gint seq;
959
960   g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
961
962   do {
963     /* reget the internal time when we retry to get the most current
964      * timevalue */
965     ret = gst_clock_get_internal_time (clock);
966
967     seq = read_seqbegin (clock);
968     /* this will scale for rate and offset */
969     ret = gst_clock_adjust_unlocked (clock, ret);
970   } while (read_seqretry (clock, seq));
971
972   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "adjusted time %" GST_TIME_FORMAT,
973       GST_TIME_ARGS (ret));
974
975   return ret;
976 }
977
978 /**
979  * gst_clock_set_calibration:
980  * @clock: a #GstClock to calibrate
981  * @internal: a reference internal time
982  * @external: a reference external time
983  * @rate_num: the numerator of the rate of the clock relative to its
984  *            internal time 
985  * @rate_denom: the denominator of the rate of the clock
986  *
987  * Adjusts the rate and time of @clock. A rate of 1/1 is the normal speed of
988  * the clock. Values bigger than 1/1 make the clock go faster.
989  *
990  * @internal and @external are calibration parameters that arrange that
991  * gst_clock_get_time() should have been @external at internal time @internal.
992  * This internal time should not be in the future; that is, it should be less
993  * than the value of gst_clock_get_internal_time() when this function is called.
994  *
995  * Subsequent calls to gst_clock_get_time() will return clock times computed as
996  * follows:
997  *
998  * <programlisting>
999  *   time = (internal_time - internal) * rate_num / rate_denom + external
1000  * </programlisting>
1001  *
1002  * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
1003  * tries to do the integer arithmetic as precisely as possible.
1004  *
1005  * Note that gst_clock_get_time() always returns increasing values so when you
1006  * move the clock backwards, gst_clock_get_time() will report the previous value
1007  * until the clock catches up.
1008  *
1009  * MT safe.
1010  */
1011 void
1012 gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
1013     external, GstClockTime rate_num, GstClockTime rate_denom)
1014 {
1015   GstClockPrivate *priv;
1016
1017   g_return_if_fail (GST_IS_CLOCK (clock));
1018   g_return_if_fail (rate_num != GST_CLOCK_TIME_NONE);
1019   g_return_if_fail (rate_denom > 0 && rate_denom != GST_CLOCK_TIME_NONE);
1020
1021   priv = clock->priv;
1022
1023   write_seqlock (clock);
1024   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1025       "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT " %"
1026       G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f", GST_TIME_ARGS (internal),
1027       GST_TIME_ARGS (external), rate_num, rate_denom,
1028       gst_guint64_to_gdouble (rate_num) / gst_guint64_to_gdouble (rate_denom));
1029
1030   priv->internal_calibration = internal;
1031   priv->external_calibration = external;
1032   priv->rate_numerator = rate_num;
1033   priv->rate_denominator = rate_denom;
1034   write_sequnlock (clock);
1035 }
1036
1037 /**
1038  * gst_clock_get_calibration:
1039  * @clock: a #GstClock 
1040  * @internal: (out) (allow-none): a location to store the internal time
1041  * @external: (out) (allow-none): a location to store the external time
1042  * @rate_num: (out) (allow-none): a location to store the rate numerator
1043  * @rate_denom: (out) (allow-none): a location to store the rate denominator
1044  *
1045  * Gets the internal rate and reference time of @clock. See
1046  * gst_clock_set_calibration() for more information.
1047  *
1048  * @internal, @external, @rate_num, and @rate_denom can be left %NULL if the
1049  * caller is not interested in the values.
1050  *
1051  * MT safe.
1052  */
1053 void
1054 gst_clock_get_calibration (GstClock * clock, GstClockTime * internal,
1055     GstClockTime * external, GstClockTime * rate_num, GstClockTime * rate_denom)
1056 {
1057   gint seq;
1058   GstClockPrivate *priv;
1059
1060   g_return_if_fail (GST_IS_CLOCK (clock));
1061
1062   priv = clock->priv;
1063
1064   do {
1065     seq = read_seqbegin (clock);
1066     if (rate_num)
1067       *rate_num = priv->rate_numerator;
1068     if (rate_denom)
1069       *rate_denom = priv->rate_denominator;
1070     if (external)
1071       *external = priv->external_calibration;
1072     if (internal)
1073       *internal = priv->internal_calibration;
1074   } while (read_seqretry (clock, seq));
1075 }
1076
1077 /* will be called repeatedly to sample the master and slave clock
1078  * to recalibrate the clock  */
1079 static gboolean
1080 gst_clock_slave_callback (GstClock * master, GstClockTime time,
1081     GstClockID id, GstClock * clock)
1082 {
1083   GstClockTime stime, mtime;
1084   gdouble r_squared;
1085
1086   stime = gst_clock_get_internal_time (clock);
1087   mtime = gst_clock_get_time (master);
1088
1089   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1090       "master %" GST_TIME_FORMAT ", slave %" GST_TIME_FORMAT,
1091       GST_TIME_ARGS (mtime), GST_TIME_ARGS (stime));
1092
1093   gst_clock_add_observation (clock, stime, mtime, &r_squared);
1094
1095   /* FIXME, we can use the r_squared value to adjust the timeout
1096    * value of the clockid */
1097
1098   return TRUE;
1099 }
1100
1101 /**
1102  * gst_clock_set_master:
1103  * @clock: a #GstClock 
1104  * @master: (allow-none): a master #GstClock 
1105  *
1106  * Set @master as the master clock for @clock. @clock will be automatically
1107  * calibrated so that gst_clock_get_time() reports the same time as the
1108  * master clock.  
1109  * 
1110  * A clock provider that slaves its clock to a master can get the current
1111  * calibration values with gst_clock_get_calibration().
1112  *
1113  * @master can be %NULL in which case @clock will not be slaved anymore. It will
1114  * however keep reporting its time adjusted with the last configured rate 
1115  * and time offsets.
1116  *
1117  * Returns: %TRUE if the clock is capable of being slaved to a master clock. 
1118  * Trying to set a master on a clock without the 
1119  * #GST_CLOCK_FLAG_CAN_SET_MASTER flag will make this function return %FALSE.
1120  *
1121  * MT safe.
1122  */
1123 gboolean
1124 gst_clock_set_master (GstClock * clock, GstClock * master)
1125 {
1126   GstClock **master_p;
1127   GstClockPrivate *priv;
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   priv = clock->priv;
1141
1142   GST_CLOCK_SLAVE_LOCK (clock);
1143   if (priv->clockid) {
1144     gst_clock_id_unschedule (priv->clockid);
1145     gst_clock_id_unref (priv->clockid);
1146     priv->clockid = NULL;
1147   }
1148   if (master) {
1149     priv->filling = TRUE;
1150     priv->time_index = 0;
1151     /* use the master periodic id to schedule sampling and
1152      * clock calibration. */
1153     priv->clockid = gst_clock_new_periodic_id (master,
1154         gst_clock_get_time (master), priv->timeout);
1155     gst_clock_id_wait_async (priv->clockid,
1156         (GstClockCallback) gst_clock_slave_callback,
1157         gst_object_ref (clock), (GDestroyNotify) gst_object_unref);
1158   }
1159   GST_CLOCK_SLAVE_UNLOCK (clock);
1160
1161   GST_OBJECT_LOCK (clock);
1162   master_p = &priv->master;
1163   gst_object_replace ((GstObject **) master_p, (GstObject *) master);
1164   GST_OBJECT_UNLOCK (clock);
1165
1166   return TRUE;
1167
1168   /* ERRORS */
1169 not_supported:
1170   {
1171     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1172         "cannot be slaved to a master clock");
1173     GST_OBJECT_UNLOCK (clock);
1174     return FALSE;
1175   }
1176 }
1177
1178 /**
1179  * gst_clock_get_master:
1180  * @clock: a #GstClock 
1181  *
1182  * Get the master clock that @clock is slaved to or %NULL when the clock is
1183  * not slaved to any master clock.
1184  *
1185  * Returns: (transfer full): a master #GstClock or %NULL when this clock is
1186  *     not slaved to a master clock. Unref after usage.
1187  *
1188  * MT safe.
1189  */
1190 GstClock *
1191 gst_clock_get_master (GstClock * clock)
1192 {
1193   GstClock *result = NULL;
1194   GstClockPrivate *priv;
1195
1196   g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
1197
1198   priv = clock->priv;
1199
1200   GST_OBJECT_LOCK (clock);
1201   if (priv->master)
1202     result = gst_object_ref (priv->master);
1203   GST_OBJECT_UNLOCK (clock);
1204
1205   return result;
1206 }
1207
1208 /* http://mathworld.wolfram.com/LeastSquaresFitting.html
1209  * with SLAVE_LOCK
1210  */
1211 static gboolean
1212 do_linear_regression (GstClock * clock, GstClockTime * m_num,
1213     GstClockTime * m_denom, GstClockTime * b, GstClockTime * xbase,
1214     gdouble * r_squared)
1215 {
1216   GstClockTime *newx, *newy;
1217   GstClockTime xmin, ymin, xbar, ybar, xbar4, ybar4;
1218   GstClockTimeDiff sxx, sxy, syy;
1219   GstClockTime *x, *y;
1220   gint i, j;
1221   guint n;
1222   GstClockPrivate *priv;
1223
1224   xbar = ybar = sxx = syy = sxy = 0;
1225
1226   priv = clock->priv;
1227
1228   x = priv->times;
1229   y = priv->times + 2;
1230   n = priv->filling ? priv->time_index : priv->window_size;
1231
1232 #ifdef DEBUGGING_ENABLED
1233   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "doing regression on:");
1234   for (i = j = 0; i < n; i++, j += 4)
1235     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1236         "  %" G_GUINT64_FORMAT "  %" G_GUINT64_FORMAT, x[j], y[j]);
1237 #endif
1238
1239   xmin = ymin = G_MAXUINT64;
1240   for (i = j = 0; i < n; i++, j += 4) {
1241     xmin = MIN (xmin, x[j]);
1242     ymin = MIN (ymin, y[j]);
1243   }
1244
1245 #ifdef DEBUGGING_ENABLED
1246   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min x: %" G_GUINT64_FORMAT,
1247       xmin);
1248   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min y: %" G_GUINT64_FORMAT,
1249       ymin);
1250 #endif
1251
1252   newx = priv->times + 1;
1253   newy = priv->times + 3;
1254
1255   /* strip off unnecessary bits of precision */
1256   for (i = j = 0; i < n; i++, j += 4) {
1257     newx[j] = x[j] - xmin;
1258     newy[j] = y[j] - ymin;
1259   }
1260
1261 #ifdef DEBUGGING_ENABLED
1262   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "reduced numbers:");
1263   for (i = j = 0; i < n; i++, j += 4)
1264     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1265         "  %" G_GUINT64_FORMAT "  %" G_GUINT64_FORMAT, newx[j], newy[j]);
1266 #endif
1267
1268   /* have to do this precisely otherwise the results are pretty much useless.
1269    * should guarantee that none of these accumulators can overflow */
1270
1271   /* quantities on the order of 1e10 -> 30 bits; window size a max of 2^10, so
1272      this addition could end up around 2^40 or so -- ample headroom */
1273   for (i = j = 0; i < n; i++, j += 4) {
1274     xbar += newx[j];
1275     ybar += newy[j];
1276   }
1277   xbar /= n;
1278   ybar /= n;
1279
1280 #ifdef DEBUGGING_ENABLED
1281   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  xbar  = %" G_GUINT64_FORMAT,
1282       xbar);
1283   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  ybar  = %" G_GUINT64_FORMAT,
1284       ybar);
1285 #endif
1286
1287   /* multiplying directly would give quantities on the order of 1e20 -> 60 bits;
1288      times the window size that's 70 which is too much. Instead we (1) subtract
1289      off the xbar*ybar in the loop instead of after, to avoid accumulation; (2)
1290      shift off 4 bits from each multiplicand, giving an expected ceiling of 52
1291      bits, which should be enough. Need to check the incoming range and domain
1292      to ensure this is an appropriate loss of precision though. */
1293   xbar4 = xbar >> 4;
1294   ybar4 = ybar >> 4;
1295   for (i = j = 0; i < n; i++, j += 4) {
1296     GstClockTime newx4, newy4;
1297
1298     newx4 = newx[j] >> 4;
1299     newy4 = newy[j] >> 4;
1300
1301     sxx += newx4 * newx4 - xbar4 * xbar4;
1302     syy += newy4 * newy4 - ybar4 * ybar4;
1303     sxy += newx4 * newy4 - xbar4 * ybar4;
1304   }
1305
1306   if (G_UNLIKELY (sxx == 0))
1307     goto invalid;
1308
1309   *m_num = sxy;
1310   *m_denom = sxx;
1311   *xbase = xmin;
1312   *b = (ybar + ymin) - gst_util_uint64_scale (xbar, *m_num, *m_denom);
1313   *r_squared = ((double) sxy * (double) sxy) / ((double) sxx * (double) syy);
1314
1315 #ifdef DEBUGGING_ENABLED
1316   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  m      = %g",
1317       ((double) *m_num) / *m_denom);
1318   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  b      = %" G_GUINT64_FORMAT,
1319       *b);
1320   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  xbase  = %" G_GUINT64_FORMAT,
1321       *xbase);
1322   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  r2     = %g", *r_squared);
1323 #endif
1324
1325   return TRUE;
1326
1327 invalid:
1328   {
1329     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "sxx == 0, regression failed");
1330     return FALSE;
1331   }
1332 }
1333
1334 /**
1335  * gst_clock_add_observation:
1336  * @clock: a #GstClock 
1337  * @slave: a time on the slave
1338  * @master: a time on the master
1339  * @r_squared: (out): a pointer to hold the result
1340  *
1341  * The time @master of the master clock and the time @slave of the slave
1342  * clock are added to the list of observations. If enough observations
1343  * are available, a linear regression algorithm is run on the
1344  * observations and @clock is recalibrated.
1345  *
1346  * If this functions returns %TRUE, @r_squared will contain the 
1347  * correlation coefficient of the interpolation. A value of 1.0
1348  * means a perfect regression was performed. This value can
1349  * be used to control the sampling frequency of the master and slave
1350  * clocks.
1351  *
1352  * Returns: %TRUE if enough observations were added to run the 
1353  * regression algorithm.
1354  *
1355  * MT safe.
1356  */
1357 gboolean
1358 gst_clock_add_observation (GstClock * clock, GstClockTime slave,
1359     GstClockTime master, gdouble * r_squared)
1360 {
1361   GstClockTime m_num, m_denom, b, xbase;
1362   GstClockPrivate *priv;
1363
1364   g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1365   g_return_val_if_fail (r_squared != NULL, FALSE);
1366
1367   priv = clock->priv;
1368
1369   GST_CLOCK_SLAVE_LOCK (clock);
1370
1371   GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1372       "adding observation slave %" GST_TIME_FORMAT ", master %" GST_TIME_FORMAT,
1373       GST_TIME_ARGS (slave), GST_TIME_ARGS (master));
1374
1375   priv->times[(4 * priv->time_index)] = slave;
1376   priv->times[(4 * priv->time_index) + 2] = master;
1377
1378   priv->time_index++;
1379   if (G_UNLIKELY (priv->time_index == priv->window_size)) {
1380     priv->filling = FALSE;
1381     priv->time_index = 0;
1382   }
1383
1384   if (G_UNLIKELY (priv->filling && priv->time_index < priv->window_threshold))
1385     goto filling;
1386
1387   if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared))
1388     goto invalid;
1389
1390   GST_CLOCK_SLAVE_UNLOCK (clock);
1391
1392   GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1393       "adjusting clock to m=%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT ", b=%"
1394       G_GUINT64_FORMAT " (rsquared=%g)", m_num, m_denom, b, *r_squared);
1395
1396   /* if we have a valid regression, adjust the clock */
1397   gst_clock_set_calibration (clock, xbase, b, m_num, m_denom);
1398
1399   return TRUE;
1400
1401 filling:
1402   {
1403     GST_CLOCK_SLAVE_UNLOCK (clock);
1404     return FALSE;
1405   }
1406 invalid:
1407   {
1408     /* no valid regression has been done, ignore the result then */
1409     GST_CLOCK_SLAVE_UNLOCK (clock);
1410     return TRUE;
1411   }
1412 }
1413
1414 /**
1415  * gst_clock_set_timeout:
1416  * @clock: a #GstClock
1417  * @timeout: a timeout
1418  *
1419  * Set the amount of time, in nanoseconds, to sample master and slave
1420  * clocks
1421  */
1422 void
1423 gst_clock_set_timeout (GstClock * clock, GstClockTime timeout)
1424 {
1425   g_return_if_fail (GST_IS_CLOCK (clock));
1426
1427   GST_CLOCK_SLAVE_LOCK (clock);
1428   clock->priv->timeout = timeout;
1429   GST_CLOCK_SLAVE_UNLOCK (clock);
1430 }
1431
1432 /**
1433  * gst_clock_get_timeout:
1434  * @clock: a #GstClock
1435  *
1436  * Get the amount of time that master and slave clocks are sampled.
1437  *
1438  * Returns: the interval between samples.
1439  */
1440 GstClockTime
1441 gst_clock_get_timeout (GstClock * clock)
1442 {
1443   GstClockTime result;
1444
1445   g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
1446
1447   GST_CLOCK_SLAVE_LOCK (clock);
1448   result = clock->priv->timeout;
1449   GST_CLOCK_SLAVE_UNLOCK (clock);
1450
1451   return result;
1452 }
1453
1454 static void
1455 gst_clock_set_property (GObject * object, guint prop_id,
1456     const GValue * value, GParamSpec * pspec)
1457 {
1458   GstClock *clock;
1459   GstClockPrivate *priv;
1460
1461   clock = GST_CLOCK (object);
1462   priv = clock->priv;
1463
1464   switch (prop_id) {
1465     case PROP_WINDOW_SIZE:
1466       GST_CLOCK_SLAVE_LOCK (clock);
1467       priv->window_size = g_value_get_int (value);
1468       priv->window_threshold = MIN (priv->window_threshold, priv->window_size);
1469       priv->times = g_renew (GstClockTime, priv->times, 4 * priv->window_size);
1470       /* restart calibration */
1471       priv->filling = TRUE;
1472       priv->time_index = 0;
1473       GST_CLOCK_SLAVE_UNLOCK (clock);
1474       break;
1475     case PROP_WINDOW_THRESHOLD:
1476       GST_CLOCK_SLAVE_LOCK (clock);
1477       priv->window_threshold = MIN (g_value_get_int (value), priv->window_size);
1478       GST_CLOCK_SLAVE_UNLOCK (clock);
1479       break;
1480     case PROP_TIMEOUT:
1481       gst_clock_set_timeout (clock, g_value_get_uint64 (value));
1482       break;
1483     default:
1484       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1485       break;
1486   }
1487 }
1488
1489 static void
1490 gst_clock_get_property (GObject * object, guint prop_id,
1491     GValue * value, GParamSpec * pspec)
1492 {
1493   GstClock *clock;
1494   GstClockPrivate *priv;
1495
1496   clock = GST_CLOCK (object);
1497   priv = clock->priv;
1498
1499   switch (prop_id) {
1500     case PROP_WINDOW_SIZE:
1501       GST_CLOCK_SLAVE_LOCK (clock);
1502       g_value_set_int (value, priv->window_size);
1503       GST_CLOCK_SLAVE_UNLOCK (clock);
1504       break;
1505     case PROP_WINDOW_THRESHOLD:
1506       GST_CLOCK_SLAVE_LOCK (clock);
1507       g_value_set_int (value, priv->window_threshold);
1508       GST_CLOCK_SLAVE_UNLOCK (clock);
1509       break;
1510     case PROP_TIMEOUT:
1511       g_value_set_uint64 (value, gst_clock_get_timeout (clock));
1512       break;
1513     default:
1514       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1515       break;
1516   }
1517 }