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