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