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