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