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