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