bus, clock: make sure these never have a floating ref
[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   /* clear floating flag */
704   gst_object_ref_sink (clock);
705 }
706
707 static void
708 gst_clock_dispose (GObject * object)
709 {
710   GstClock *clock = GST_CLOCK (object);
711   GstClock **master_p;
712
713   GST_OBJECT_LOCK (clock);
714   master_p = &clock->priv->master;
715   gst_object_replace ((GstObject **) master_p, NULL);
716   GST_OBJECT_UNLOCK (clock);
717
718   G_OBJECT_CLASS (parent_class)->dispose (object);
719 }
720
721 static void
722 gst_clock_finalize (GObject * object)
723 {
724   GstClock *clock = GST_CLOCK (object);
725
726   GST_CLOCK_SLAVE_LOCK (clock);
727   if (clock->priv->clockid) {
728     gst_clock_id_unschedule (clock->priv->clockid);
729     gst_clock_id_unref (clock->priv->clockid);
730     clock->priv->clockid = NULL;
731   }
732   g_free (clock->priv->times);
733   clock->priv->times = NULL;
734   GST_CLOCK_SLAVE_UNLOCK (clock);
735
736   g_mutex_clear (&clock->priv->slave_lock);
737
738   G_OBJECT_CLASS (parent_class)->finalize (object);
739 }
740
741 /**
742  * gst_clock_set_resolution:
743  * @clock: a #GstClock
744  * @resolution: The resolution to set
745  *
746  * Set the accuracy of the clock. Some clocks have the possibility to operate
747  * with different accuracy at the expense of more resource usage. There is
748  * normally no need to change the default resolution of a clock. The resolution
749  * of a clock can only be changed if the clock has the
750  * #GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set.
751  *
752  * Returns: the new resolution of the clock.
753  */
754 GstClockTime
755 gst_clock_set_resolution (GstClock * clock, GstClockTime resolution)
756 {
757   GstClockPrivate *priv;
758   GstClockClass *cclass;
759
760   g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
761   g_return_val_if_fail (resolution != 0, 0);
762
763   cclass = GST_CLOCK_GET_CLASS (clock);
764   priv = clock->priv;
765
766   if (cclass->change_resolution)
767     priv->resolution =
768         cclass->change_resolution (clock, priv->resolution, resolution);
769
770   return priv->resolution;
771 }
772
773 /**
774  * gst_clock_get_resolution:
775  * @clock: a #GstClock
776  *
777  * Get the accuracy of the clock. The accuracy of the clock is the granularity
778  * of the values returned by gst_clock_get_time().
779  *
780  * Returns: the resolution of the clock in units of #GstClockTime.
781  *
782  * MT safe.
783  */
784 GstClockTime
785 gst_clock_get_resolution (GstClock * clock)
786 {
787   GstClockClass *cclass;
788
789   g_return_val_if_fail (GST_IS_CLOCK (clock), 0);
790
791   cclass = GST_CLOCK_GET_CLASS (clock);
792
793   if (cclass->get_resolution)
794     return cclass->get_resolution (clock);
795
796   return 1;
797 }
798
799 /**
800  * gst_clock_adjust_unlocked:
801  * @clock: a #GstClock to use
802  * @internal: a clock time
803  *
804  * Converts the given @internal clock time to the external time, adjusting for the
805  * rate and reference time set with gst_clock_set_calibration() and making sure
806  * that the returned time is increasing. This function should be called with the
807  * clock's OBJECT_LOCK held and is mainly used by clock subclasses.
808  *
809  * This function is the reverse of gst_clock_unadjust_unlocked().
810  *
811  * Returns: the converted time of the clock.
812  */
813 GstClockTime
814 gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
815 {
816   GstClockTime ret, cinternal, cexternal, cnum, cdenom;
817   GstClockPrivate *priv = clock->priv;
818
819   /* get calibration values for readability */
820   cinternal = priv->internal_calibration;
821   cexternal = priv->external_calibration;
822   cnum = priv->rate_numerator;
823   cdenom = priv->rate_denominator;
824
825   /* avoid divide by 0 */
826   if (G_UNLIKELY (cdenom == 0))
827     cnum = cdenom = 1;
828
829   /* The formula is (internal - cinternal) * cnum / cdenom + cexternal
830    *
831    * Since we do math on unsigned 64-bit ints we have to special case for
832    * internal < cinternal to get the sign right. this case is not very common,
833    * though.
834    */
835   if (G_LIKELY (internal >= cinternal)) {
836     ret = internal - cinternal;
837     ret = gst_util_uint64_scale (ret, cnum, cdenom);
838     ret += cexternal;
839   } else {
840     ret = cinternal - internal;
841     ret = gst_util_uint64_scale (ret, cnum, cdenom);
842     /* clamp to 0 */
843     if (G_LIKELY (cexternal > ret))
844       ret = cexternal - ret;
845     else
846       ret = 0;
847   }
848
849   /* make sure the time is increasing */
850   priv->last_time = MAX (ret, priv->last_time);
851
852   return priv->last_time;
853 }
854
855 /**
856  * gst_clock_unadjust_unlocked:
857  * @clock: a #GstClock to use
858  * @external: an external clock time
859  *
860  * Converts the given @external clock time to the internal time of @clock,
861  * using the rate and reference time set with gst_clock_set_calibration().
862  * This function should be called with the clock's OBJECT_LOCK held and
863  * is mainly used by clock subclasses.
864  *
865  * This function is the reverse of gst_clock_adjust_unlocked().
866  *
867  * Returns: the internal time of the clock corresponding to @external.
868  *
869  * Since: 0.10.13
870  */
871 GstClockTime
872 gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external)
873 {
874   GstClockTime ret, cinternal, cexternal, cnum, cdenom;
875   GstClockPrivate *priv = clock->priv;
876
877   /* get calibration values for readability */
878   cinternal = priv->internal_calibration;
879   cexternal = priv->external_calibration;
880   cnum = priv->rate_numerator;
881   cdenom = priv->rate_denominator;
882
883   /* avoid divide by 0 */
884   if (G_UNLIKELY (cnum == 0))
885     cnum = cdenom = 1;
886
887   /* The formula is (external - cexternal) * cdenom / cnum + cinternal */
888   if (G_LIKELY (external >= cexternal)) {
889     ret = external - cexternal;
890     ret = gst_util_uint64_scale (ret, cdenom, cnum);
891     ret += cinternal;
892   } else {
893     ret = cexternal - external;
894     ret = gst_util_uint64_scale (ret, cdenom, cnum);
895     if (G_LIKELY (cinternal > ret))
896       ret = cinternal - ret;
897     else
898       ret = 0;
899   }
900   return ret;
901 }
902
903 /**
904  * gst_clock_get_internal_time:
905  * @clock: a #GstClock to query
906  *
907  * Gets the current internal time of the given clock. The time is returned
908  * unadjusted for the offset and the rate.
909  *
910  * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
911  * given invalid input.
912  *
913  * MT safe.
914  */
915 GstClockTime
916 gst_clock_get_internal_time (GstClock * clock)
917 {
918   GstClockTime ret;
919   GstClockClass *cclass;
920
921   g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
922
923   cclass = GST_CLOCK_GET_CLASS (clock);
924
925   if (G_UNLIKELY (cclass->get_internal_time == NULL))
926     goto not_supported;
927
928   ret = cclass->get_internal_time (clock);
929
930   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
931       GST_TIME_ARGS (ret));
932
933   return ret;
934
935   /* ERRORS */
936 not_supported:
937   {
938     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
939         "internal time not supported, return 0");
940     return G_GINT64_CONSTANT (0);
941   }
942 }
943
944 /**
945  * gst_clock_get_time:
946  * @clock: a #GstClock to query
947  *
948  * Gets the current time of the given clock. The time is always
949  * monotonically increasing and adjusted according to the current
950  * offset and rate.
951  *
952  * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when
953  * given invalid input.
954  *
955  * MT safe.
956  */
957 GstClockTime
958 gst_clock_get_time (GstClock * clock)
959 {
960   GstClockTime ret;
961   gint seq;
962
963   g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
964
965   do {
966     /* reget the internal time when we retry to get the most current
967      * timevalue */
968     ret = gst_clock_get_internal_time (clock);
969
970     seq = read_seqbegin (clock);
971     /* this will scale for rate and offset */
972     ret = gst_clock_adjust_unlocked (clock, ret);
973   } while (read_seqretry (clock, seq));
974
975   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "adjusted time %" GST_TIME_FORMAT,
976       GST_TIME_ARGS (ret));
977
978   return ret;
979 }
980
981 /**
982  * gst_clock_set_calibration:
983  * @clock: a #GstClock to calibrate
984  * @internal: a reference internal time
985  * @external: a reference external time
986  * @rate_num: the numerator of the rate of the clock relative to its
987  *            internal time 
988  * @rate_denom: the denominator of the rate of the clock
989  *
990  * Adjusts the rate and time of @clock. A rate of 1/1 is the normal speed of
991  * the clock. Values bigger than 1/1 make the clock go faster.
992  *
993  * @internal and @external are calibration parameters that arrange that
994  * gst_clock_get_time() should have been @external at internal time @internal.
995  * This internal time should not be in the future; that is, it should be less
996  * than the value of gst_clock_get_internal_time() when this function is called.
997  *
998  * Subsequent calls to gst_clock_get_time() will return clock times computed as
999  * follows:
1000  *
1001  * <programlisting>
1002  *   time = (internal_time - internal) * rate_num / rate_denom + external
1003  * </programlisting>
1004  *
1005  * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
1006  * tries to do the integer arithmetic as precisely as possible.
1007  *
1008  * Note that gst_clock_get_time() always returns increasing values so when you
1009  * move the clock backwards, gst_clock_get_time() will report the previous value
1010  * until the clock catches up.
1011  *
1012  * MT safe.
1013  */
1014 void
1015 gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
1016     external, GstClockTime rate_num, GstClockTime rate_denom)
1017 {
1018   GstClockPrivate *priv;
1019
1020   g_return_if_fail (GST_IS_CLOCK (clock));
1021   g_return_if_fail (rate_num != GST_CLOCK_TIME_NONE);
1022   g_return_if_fail (rate_denom > 0 && rate_denom != GST_CLOCK_TIME_NONE);
1023
1024   priv = clock->priv;
1025
1026   write_seqlock (clock);
1027   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1028       "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT " %"
1029       G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f", GST_TIME_ARGS (internal),
1030       GST_TIME_ARGS (external), rate_num, rate_denom,
1031       gst_guint64_to_gdouble (rate_num) / gst_guint64_to_gdouble (rate_denom));
1032
1033   priv->internal_calibration = internal;
1034   priv->external_calibration = external;
1035   priv->rate_numerator = rate_num;
1036   priv->rate_denominator = rate_denom;
1037   write_sequnlock (clock);
1038 }
1039
1040 /**
1041  * gst_clock_get_calibration:
1042  * @clock: a #GstClock 
1043  * @internal: (out) (allow-none): a location to store the internal time
1044  * @external: (out) (allow-none): a location to store the external time
1045  * @rate_num: (out) (allow-none): a location to store the rate numerator
1046  * @rate_denom: (out) (allow-none): a location to store the rate denominator
1047  *
1048  * Gets the internal rate and reference time of @clock. See
1049  * gst_clock_set_calibration() for more information.
1050  *
1051  * @internal, @external, @rate_num, and @rate_denom can be left %NULL if the
1052  * caller is not interested in the values.
1053  *
1054  * MT safe.
1055  */
1056 void
1057 gst_clock_get_calibration (GstClock * clock, GstClockTime * internal,
1058     GstClockTime * external, GstClockTime * rate_num, GstClockTime * rate_denom)
1059 {
1060   gint seq;
1061   GstClockPrivate *priv;
1062
1063   g_return_if_fail (GST_IS_CLOCK (clock));
1064
1065   priv = clock->priv;
1066
1067   do {
1068     seq = read_seqbegin (clock);
1069     if (rate_num)
1070       *rate_num = priv->rate_numerator;
1071     if (rate_denom)
1072       *rate_denom = priv->rate_denominator;
1073     if (external)
1074       *external = priv->external_calibration;
1075     if (internal)
1076       *internal = priv->internal_calibration;
1077   } while (read_seqretry (clock, seq));
1078 }
1079
1080 /* will be called repeatedly to sample the master and slave clock
1081  * to recalibrate the clock  */
1082 static gboolean
1083 gst_clock_slave_callback (GstClock * master, GstClockTime time,
1084     GstClockID id, GstClock * clock)
1085 {
1086   GstClockTime stime, mtime;
1087   gdouble r_squared;
1088
1089   stime = gst_clock_get_internal_time (clock);
1090   mtime = gst_clock_get_time (master);
1091
1092   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1093       "master %" GST_TIME_FORMAT ", slave %" GST_TIME_FORMAT,
1094       GST_TIME_ARGS (mtime), GST_TIME_ARGS (stime));
1095
1096   gst_clock_add_observation (clock, stime, mtime, &r_squared);
1097
1098   /* FIXME, we can use the r_squared value to adjust the timeout
1099    * value of the clockid */
1100
1101   return TRUE;
1102 }
1103
1104 /**
1105  * gst_clock_set_master:
1106  * @clock: a #GstClock 
1107  * @master: (allow-none): a master #GstClock 
1108  *
1109  * Set @master as the master clock for @clock. @clock will be automatically
1110  * calibrated so that gst_clock_get_time() reports the same time as the
1111  * master clock.  
1112  * 
1113  * A clock provider that slaves its clock to a master can get the current
1114  * calibration values with gst_clock_get_calibration().
1115  *
1116  * @master can be %NULL in which case @clock will not be slaved anymore. It will
1117  * however keep reporting its time adjusted with the last configured rate 
1118  * and time offsets.
1119  *
1120  * Returns: %TRUE if the clock is capable of being slaved to a master clock. 
1121  * Trying to set a master on a clock without the 
1122  * #GST_CLOCK_FLAG_CAN_SET_MASTER flag will make this function return %FALSE.
1123  *
1124  * MT safe.
1125  */
1126 gboolean
1127 gst_clock_set_master (GstClock * clock, GstClock * master)
1128 {
1129   GstClock **master_p;
1130   GstClockPrivate *priv;
1131
1132   g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1133   g_return_val_if_fail (master != clock, FALSE);
1134
1135   GST_OBJECT_LOCK (clock);
1136   /* we always allow setting the master to NULL */
1137   if (master && !GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER))
1138     goto not_supported;
1139   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1140       "slaving %p to master clock %p", clock, master);
1141   GST_OBJECT_UNLOCK (clock);
1142
1143   priv = clock->priv;
1144
1145   GST_CLOCK_SLAVE_LOCK (clock);
1146   if (priv->clockid) {
1147     gst_clock_id_unschedule (priv->clockid);
1148     gst_clock_id_unref (priv->clockid);
1149     priv->clockid = NULL;
1150   }
1151   if (master) {
1152     priv->filling = TRUE;
1153     priv->time_index = 0;
1154     /* use the master periodic id to schedule sampling and
1155      * clock calibration. */
1156     priv->clockid = gst_clock_new_periodic_id (master,
1157         gst_clock_get_time (master), priv->timeout);
1158     gst_clock_id_wait_async (priv->clockid,
1159         (GstClockCallback) gst_clock_slave_callback,
1160         gst_object_ref (clock), (GDestroyNotify) gst_object_unref);
1161   }
1162   GST_CLOCK_SLAVE_UNLOCK (clock);
1163
1164   GST_OBJECT_LOCK (clock);
1165   master_p = &priv->master;
1166   gst_object_replace ((GstObject **) master_p, (GstObject *) master);
1167   GST_OBJECT_UNLOCK (clock);
1168
1169   return TRUE;
1170
1171   /* ERRORS */
1172 not_supported:
1173   {
1174     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1175         "cannot be slaved to a master clock");
1176     GST_OBJECT_UNLOCK (clock);
1177     return FALSE;
1178   }
1179 }
1180
1181 /**
1182  * gst_clock_get_master:
1183  * @clock: a #GstClock 
1184  *
1185  * Get the master clock that @clock is slaved to or %NULL when the clock is
1186  * not slaved to any master clock.
1187  *
1188  * Returns: (transfer full): a master #GstClock or %NULL when this clock is
1189  *     not slaved to a master clock. Unref after usage.
1190  *
1191  * MT safe.
1192  */
1193 GstClock *
1194 gst_clock_get_master (GstClock * clock)
1195 {
1196   GstClock *result = NULL;
1197   GstClockPrivate *priv;
1198
1199   g_return_val_if_fail (GST_IS_CLOCK (clock), NULL);
1200
1201   priv = clock->priv;
1202
1203   GST_OBJECT_LOCK (clock);
1204   if (priv->master)
1205     result = gst_object_ref (priv->master);
1206   GST_OBJECT_UNLOCK (clock);
1207
1208   return result;
1209 }
1210
1211 /* http://mathworld.wolfram.com/LeastSquaresFitting.html
1212  * with SLAVE_LOCK
1213  */
1214 static gboolean
1215 do_linear_regression (GstClock * clock, GstClockTime * m_num,
1216     GstClockTime * m_denom, GstClockTime * b, GstClockTime * xbase,
1217     gdouble * r_squared)
1218 {
1219   GstClockTime *newx, *newy;
1220   GstClockTime xmin, ymin, xbar, ybar, xbar4, ybar4;
1221   GstClockTimeDiff sxx, sxy, syy;
1222   GstClockTime *x, *y;
1223   gint i, j;
1224   guint n;
1225   GstClockPrivate *priv;
1226
1227   xbar = ybar = sxx = syy = sxy = 0;
1228
1229   priv = clock->priv;
1230
1231   x = priv->times;
1232   y = priv->times + 2;
1233   n = priv->filling ? priv->time_index : priv->window_size;
1234
1235 #ifdef DEBUGGING_ENABLED
1236   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "doing regression on:");
1237   for (i = j = 0; i < n; i++, j += 4)
1238     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1239         "  %" G_GUINT64_FORMAT "  %" G_GUINT64_FORMAT, x[j], y[j]);
1240 #endif
1241
1242   xmin = ymin = G_MAXUINT64;
1243   for (i = j = 0; i < n; i++, j += 4) {
1244     xmin = MIN (xmin, x[j]);
1245     ymin = MIN (ymin, y[j]);
1246   }
1247
1248 #ifdef DEBUGGING_ENABLED
1249   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min x: %" G_GUINT64_FORMAT,
1250       xmin);
1251   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "min y: %" G_GUINT64_FORMAT,
1252       ymin);
1253 #endif
1254
1255   newx = priv->times + 1;
1256   newy = priv->times + 3;
1257
1258   /* strip off unnecessary bits of precision */
1259   for (i = j = 0; i < n; i++, j += 4) {
1260     newx[j] = x[j] - xmin;
1261     newy[j] = y[j] - ymin;
1262   }
1263
1264 #ifdef DEBUGGING_ENABLED
1265   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "reduced numbers:");
1266   for (i = j = 0; i < n; i++, j += 4)
1267     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
1268         "  %" G_GUINT64_FORMAT "  %" G_GUINT64_FORMAT, newx[j], newy[j]);
1269 #endif
1270
1271   /* have to do this precisely otherwise the results are pretty much useless.
1272    * should guarantee that none of these accumulators can overflow */
1273
1274   /* quantities on the order of 1e10 -> 30 bits; window size a max of 2^10, so
1275      this addition could end up around 2^40 or so -- ample headroom */
1276   for (i = j = 0; i < n; i++, j += 4) {
1277     xbar += newx[j];
1278     ybar += newy[j];
1279   }
1280   xbar /= n;
1281   ybar /= n;
1282
1283 #ifdef DEBUGGING_ENABLED
1284   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  xbar  = %" G_GUINT64_FORMAT,
1285       xbar);
1286   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  ybar  = %" G_GUINT64_FORMAT,
1287       ybar);
1288 #endif
1289
1290   /* multiplying directly would give quantities on the order of 1e20 -> 60 bits;
1291      times the window size that's 70 which is too much. Instead we (1) subtract
1292      off the xbar*ybar in the loop instead of after, to avoid accumulation; (2)
1293      shift off 4 bits from each multiplicand, giving an expected ceiling of 52
1294      bits, which should be enough. Need to check the incoming range and domain
1295      to ensure this is an appropriate loss of precision though. */
1296   xbar4 = xbar >> 4;
1297   ybar4 = ybar >> 4;
1298   for (i = j = 0; i < n; i++, j += 4) {
1299     GstClockTime newx4, newy4;
1300
1301     newx4 = newx[j] >> 4;
1302     newy4 = newy[j] >> 4;
1303
1304     sxx += newx4 * newx4 - xbar4 * xbar4;
1305     syy += newy4 * newy4 - ybar4 * ybar4;
1306     sxy += newx4 * newy4 - xbar4 * ybar4;
1307   }
1308
1309   if (G_UNLIKELY (sxx == 0))
1310     goto invalid;
1311
1312   *m_num = sxy;
1313   *m_denom = sxx;
1314   *xbase = xmin;
1315   *b = (ybar + ymin) - gst_util_uint64_scale (xbar, *m_num, *m_denom);
1316   *r_squared = ((double) sxy * (double) sxy) / ((double) sxx * (double) syy);
1317
1318 #ifdef DEBUGGING_ENABLED
1319   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  m      = %g",
1320       ((double) *m_num) / *m_denom);
1321   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  b      = %" G_GUINT64_FORMAT,
1322       *b);
1323   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  xbase  = %" G_GUINT64_FORMAT,
1324       *xbase);
1325   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "  r2     = %g", *r_squared);
1326 #endif
1327
1328   return TRUE;
1329
1330 invalid:
1331   {
1332     GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "sxx == 0, regression failed");
1333     return FALSE;
1334   }
1335 }
1336
1337 /**
1338  * gst_clock_add_observation:
1339  * @clock: a #GstClock 
1340  * @slave: a time on the slave
1341  * @master: a time on the master
1342  * @r_squared: (out): a pointer to hold the result
1343  *
1344  * The time @master of the master clock and the time @slave of the slave
1345  * clock are added to the list of observations. If enough observations
1346  * are available, a linear regression algorithm is run on the
1347  * observations and @clock is recalibrated.
1348  *
1349  * If this functions returns %TRUE, @r_squared will contain the 
1350  * correlation coefficient of the interpolation. A value of 1.0
1351  * means a perfect regression was performed. This value can
1352  * be used to control the sampling frequency of the master and slave
1353  * clocks.
1354  *
1355  * Returns: %TRUE if enough observations were added to run the 
1356  * regression algorithm.
1357  *
1358  * MT safe.
1359  */
1360 gboolean
1361 gst_clock_add_observation (GstClock * clock, GstClockTime slave,
1362     GstClockTime master, gdouble * r_squared)
1363 {
1364   GstClockTime m_num, m_denom, b, xbase;
1365   GstClockPrivate *priv;
1366
1367   g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
1368   g_return_val_if_fail (r_squared != NULL, FALSE);
1369
1370   priv = clock->priv;
1371
1372   GST_CLOCK_SLAVE_LOCK (clock);
1373
1374   GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1375       "adding observation slave %" GST_TIME_FORMAT ", master %" GST_TIME_FORMAT,
1376       GST_TIME_ARGS (slave), GST_TIME_ARGS (master));
1377
1378   priv->times[(4 * priv->time_index)] = slave;
1379   priv->times[(4 * priv->time_index) + 2] = master;
1380
1381   priv->time_index++;
1382   if (G_UNLIKELY (priv->time_index == priv->window_size)) {
1383     priv->filling = FALSE;
1384     priv->time_index = 0;
1385   }
1386
1387   if (G_UNLIKELY (priv->filling && priv->time_index < priv->window_threshold))
1388     goto filling;
1389
1390   if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared))
1391     goto invalid;
1392
1393   GST_CLOCK_SLAVE_UNLOCK (clock);
1394
1395   GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock,
1396       "adjusting clock to m=%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT ", b=%"
1397       G_GUINT64_FORMAT " (rsquared=%g)", m_num, m_denom, b, *r_squared);
1398
1399   /* if we have a valid regression, adjust the clock */
1400   gst_clock_set_calibration (clock, xbase, b, m_num, m_denom);
1401
1402   return TRUE;
1403
1404 filling:
1405   {
1406     GST_CLOCK_SLAVE_UNLOCK (clock);
1407     return FALSE;
1408   }
1409 invalid:
1410   {
1411     /* no valid regression has been done, ignore the result then */
1412     GST_CLOCK_SLAVE_UNLOCK (clock);
1413     return TRUE;
1414   }
1415 }
1416
1417 /**
1418  * gst_clock_set_timeout:
1419  * @clock: a #GstClock
1420  * @timeout: a timeout
1421  *
1422  * Set the amount of time, in nanoseconds, to sample master and slave
1423  * clocks
1424  */
1425 void
1426 gst_clock_set_timeout (GstClock * clock, GstClockTime timeout)
1427 {
1428   g_return_if_fail (GST_IS_CLOCK (clock));
1429
1430   GST_CLOCK_SLAVE_LOCK (clock);
1431   clock->priv->timeout = timeout;
1432   GST_CLOCK_SLAVE_UNLOCK (clock);
1433 }
1434
1435 /**
1436  * gst_clock_get_timeout:
1437  * @clock: a #GstClock
1438  *
1439  * Get the amount of time that master and slave clocks are sampled.
1440  *
1441  * Returns: the interval between samples.
1442  */
1443 GstClockTime
1444 gst_clock_get_timeout (GstClock * clock)
1445 {
1446   GstClockTime result;
1447
1448   g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);
1449
1450   GST_CLOCK_SLAVE_LOCK (clock);
1451   result = clock->priv->timeout;
1452   GST_CLOCK_SLAVE_UNLOCK (clock);
1453
1454   return result;
1455 }
1456
1457 static void
1458 gst_clock_set_property (GObject * object, guint prop_id,
1459     const GValue * value, GParamSpec * pspec)
1460 {
1461   GstClock *clock;
1462   GstClockPrivate *priv;
1463
1464   clock = GST_CLOCK (object);
1465   priv = clock->priv;
1466
1467   switch (prop_id) {
1468     case PROP_WINDOW_SIZE:
1469       GST_CLOCK_SLAVE_LOCK (clock);
1470       priv->window_size = g_value_get_int (value);
1471       priv->window_threshold = MIN (priv->window_threshold, priv->window_size);
1472       priv->times = g_renew (GstClockTime, priv->times, 4 * priv->window_size);
1473       /* restart calibration */
1474       priv->filling = TRUE;
1475       priv->time_index = 0;
1476       GST_CLOCK_SLAVE_UNLOCK (clock);
1477       break;
1478     case PROP_WINDOW_THRESHOLD:
1479       GST_CLOCK_SLAVE_LOCK (clock);
1480       priv->window_threshold = MIN (g_value_get_int (value), priv->window_size);
1481       GST_CLOCK_SLAVE_UNLOCK (clock);
1482       break;
1483     case PROP_TIMEOUT:
1484       gst_clock_set_timeout (clock, g_value_get_uint64 (value));
1485       break;
1486     default:
1487       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1488       break;
1489   }
1490 }
1491
1492 static void
1493 gst_clock_get_property (GObject * object, guint prop_id,
1494     GValue * value, GParamSpec * pspec)
1495 {
1496   GstClock *clock;
1497   GstClockPrivate *priv;
1498
1499   clock = GST_CLOCK (object);
1500   priv = clock->priv;
1501
1502   switch (prop_id) {
1503     case PROP_WINDOW_SIZE:
1504       GST_CLOCK_SLAVE_LOCK (clock);
1505       g_value_set_int (value, priv->window_size);
1506       GST_CLOCK_SLAVE_UNLOCK (clock);
1507       break;
1508     case PROP_WINDOW_THRESHOLD:
1509       GST_CLOCK_SLAVE_LOCK (clock);
1510       g_value_set_int (value, priv->window_threshold);
1511       GST_CLOCK_SLAVE_UNLOCK (clock);
1512       break;
1513     case PROP_TIMEOUT:
1514       g_value_set_uint64 (value, gst_clock_get_timeout (clock));
1515       break;
1516     default:
1517       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1518       break;
1519   }
1520 }