Merge remote-tracking branch 'origin/master' into 0.11
[platform/upstream/gstreamer.git] / gst-libs / gst / audio / gstaudiobasesink.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2005 Wim Taymans <wim@fluendo.com>
4  *
5  * gstaudiobasesink.c:
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /**
24  * SECTION:gstaudiobasesink
25  * @short_description: Base class for audio sinks
26  * @see_also: #GstAudioSink, #GstAudioRingBuffer.
27  *
28  * This is the base class for audio sinks. Subclasses need to implement the
29  * ::create_ringbuffer vmethod. This base class will then take care of
30  * writing samples to the ringbuffer, synchronisation, clipping and flushing.
31  *
32  * Last reviewed on 2006-09-27 (0.10.12)
33  */
34
35 #include <string.h>
36
37 /* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
38  * with newer GLib versions (>= 2.31.0) */
39 #define GLIB_DISABLE_DEPRECATION_WARNINGS
40 #include "gstaudiobasesink.h"
41
42 GST_DEBUG_CATEGORY_STATIC (gst_audio_base_sink_debug);
43 #define GST_CAT_DEFAULT gst_audio_base_sink_debug
44
45 #define GST_AUDIO_BASE_SINK_GET_PRIVATE(obj)  \
46    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_AUDIO_BASE_SINK, GstAudioBaseSinkPrivate))
47
48 struct _GstAudioBaseSinkPrivate
49 {
50   /* upstream latency */
51   GstClockTime us_latency;
52   /* the clock slaving algorithm in use */
53   GstAudioBaseSinkSlaveMethod slave_method;
54   /* running average of clock skew */
55   GstClockTimeDiff avg_skew;
56   /* the number of samples we aligned last time */
57   gint64 last_align;
58
59   gboolean sync_latency;
60
61   GstClockTime eos_time;
62
63   /* number of microseconds we allow clock slaving to drift
64    * before resyncing */
65   guint64 drift_tolerance;
66
67   /* number of nanoseconds we allow timestamps to drift
68    * before resyncing */
69   GstClockTime alignment_threshold;
70
71   /* time of the previous detected discont candidate */
72   GstClockTime discont_time;
73
74   /* number of nanoseconds to wait until creating a discontinuity */
75   GstClockTime discont_wait;
76 };
77
78 /* BaseAudioSink signals and args */
79 enum
80 {
81   /* FILL ME */
82   LAST_SIGNAL
83 };
84
85 /* FIXME: 0.11, store the buffer_time and latency_time in nanoseconds */
86 #define DEFAULT_BUFFER_TIME     ((200 * GST_MSECOND) / GST_USECOND)
87 #define DEFAULT_LATENCY_TIME    ((10 * GST_MSECOND) / GST_USECOND)
88 #define DEFAULT_PROVIDE_CLOCK   TRUE
89 #define DEFAULT_SLAVE_METHOD    GST_AUDIO_BASE_SINK_SLAVE_SKEW
90
91 /* FIXME, enable pull mode when clock slaving and trick modes are figured out */
92 #define DEFAULT_CAN_ACTIVATE_PULL FALSE
93
94 /* when timestamps drift for more than 40ms we resync. This should
95  * be anough to compensate for timestamp rounding errors. */
96 #define DEFAULT_ALIGNMENT_THRESHOLD   (40 * GST_MSECOND)
97
98 /* when clock slaving drift for more than 40ms we resync. This is
99  * a reasonable default */
100 #define DEFAULT_DRIFT_TOLERANCE   ((40 * GST_MSECOND) / GST_USECOND)
101
102 /* allow for one second before resyncing to see if the timestamps drift will
103  * fix itself, or is a permanent offset */
104 #define DEFAULT_DISCONT_WAIT        (1 * GST_SECOND)
105
106 enum
107 {
108   PROP_0,
109
110   PROP_BUFFER_TIME,
111   PROP_LATENCY_TIME,
112   PROP_PROVIDE_CLOCK,
113   PROP_SLAVE_METHOD,
114   PROP_CAN_ACTIVATE_PULL,
115   PROP_ALIGNMENT_THRESHOLD,
116   PROP_DRIFT_TOLERANCE,
117   PROP_DISCONT_WAIT,
118
119   PROP_LAST
120 };
121
122 GType
123 gst_audio_base_sink_slave_method_get_type (void)
124 {
125   static volatile gsize slave_method_type = 0;
126   static const GEnumValue slave_method[] = {
127     {GST_AUDIO_BASE_SINK_SLAVE_RESAMPLE, "GST_AUDIO_BASE_SINK_SLAVE_RESAMPLE",
128         "resample"},
129     {GST_AUDIO_BASE_SINK_SLAVE_SKEW, "GST_AUDIO_BASE_SINK_SLAVE_SKEW", "skew"},
130     {GST_AUDIO_BASE_SINK_SLAVE_NONE, "GST_AUDIO_BASE_SINK_SLAVE_NONE", "none"},
131     {0, NULL, NULL},
132   };
133
134   if (g_once_init_enter (&slave_method_type)) {
135     GType tmp =
136         g_enum_register_static ("GstAudioBaseSinkSlaveMethod", slave_method);
137     g_once_init_leave (&slave_method_type, tmp);
138   }
139
140   return (GType) slave_method_type;
141 }
142
143
144 #define _do_init \
145     GST_DEBUG_CATEGORY_INIT (gst_audio_base_sink_debug, "audiobasesink", 0, "audiobasesink element");
146 #define gst_audio_base_sink_parent_class parent_class
147 G_DEFINE_TYPE_WITH_CODE (GstAudioBaseSink, gst_audio_base_sink,
148     GST_TYPE_BASE_SINK, _do_init);
149
150 static void gst_audio_base_sink_dispose (GObject * object);
151
152 static void gst_audio_base_sink_set_property (GObject * object, guint prop_id,
153     const GValue * value, GParamSpec * pspec);
154 static void gst_audio_base_sink_get_property (GObject * object, guint prop_id,
155     GValue * value, GParamSpec * pspec);
156
157 #if 0
158 static GstStateChangeReturn gst_audio_base_sink_async_play (GstBaseSink *
159     basesink);
160 #endif
161 static GstStateChangeReturn gst_audio_base_sink_change_state (GstElement *
162     element, GstStateChange transition);
163 static gboolean gst_audio_base_sink_activate_pull (GstBaseSink * basesink,
164     gboolean active);
165 static gboolean gst_audio_base_sink_query (GstElement * element, GstQuery *
166     query);
167
168 static GstClock *gst_audio_base_sink_provide_clock (GstElement * elem);
169 static GstClockTime gst_audio_base_sink_get_time (GstClock * clock,
170     GstAudioBaseSink * sink);
171 static void gst_audio_base_sink_callback (GstAudioRingBuffer * rbuf,
172     guint8 * data, guint len, gpointer user_data);
173
174 static GstFlowReturn gst_audio_base_sink_preroll (GstBaseSink * bsink,
175     GstBuffer * buffer);
176 static GstFlowReturn gst_audio_base_sink_render (GstBaseSink * bsink,
177     GstBuffer * buffer);
178 static gboolean gst_audio_base_sink_event (GstBaseSink * bsink,
179     GstEvent * event);
180 static GstFlowReturn gst_audio_base_sink_wait_eos (GstBaseSink * bsink,
181     GstEvent * event);
182 static void gst_audio_base_sink_get_times (GstBaseSink * bsink,
183     GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
184 static gboolean gst_audio_base_sink_setcaps (GstBaseSink * bsink,
185     GstCaps * caps);
186 static void gst_audio_base_sink_fixate (GstBaseSink * bsink, GstCaps * caps);
187
188 static gboolean gst_audio_base_sink_query_pad (GstBaseSink * bsink,
189     GstQuery * query);
190
191
192 /* static guint gst_audio_base_sink_signals[LAST_SIGNAL] = { 0 }; */
193
194 static void
195 gst_audio_base_sink_class_init (GstAudioBaseSinkClass * klass)
196 {
197   GObjectClass *gobject_class;
198   GstElementClass *gstelement_class;
199   GstBaseSinkClass *gstbasesink_class;
200
201   gobject_class = (GObjectClass *) klass;
202   gstelement_class = (GstElementClass *) klass;
203   gstbasesink_class = (GstBaseSinkClass *) klass;
204
205   g_type_class_add_private (klass, sizeof (GstAudioBaseSinkPrivate));
206
207   gobject_class->set_property = gst_audio_base_sink_set_property;
208   gobject_class->get_property = gst_audio_base_sink_get_property;
209   gobject_class->dispose = gst_audio_base_sink_dispose;
210
211   g_object_class_install_property (gobject_class, PROP_BUFFER_TIME,
212       g_param_spec_int64 ("buffer-time", "Buffer Time",
213           "Size of audio buffer in microseconds", 1,
214           G_MAXINT64, DEFAULT_BUFFER_TIME,
215           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
216
217   g_object_class_install_property (gobject_class, PROP_LATENCY_TIME,
218       g_param_spec_int64 ("latency-time", "Latency Time",
219           "Audio latency in microseconds", 1,
220           G_MAXINT64, DEFAULT_LATENCY_TIME,
221           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
222
223   g_object_class_install_property (gobject_class, PROP_PROVIDE_CLOCK,
224       g_param_spec_boolean ("provide-clock", "Provide Clock",
225           "Provide a clock to be used as the global pipeline clock",
226           DEFAULT_PROVIDE_CLOCK, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
227
228   g_object_class_install_property (gobject_class, PROP_SLAVE_METHOD,
229       g_param_spec_enum ("slave-method", "Slave Method",
230           "Algorithm to use to match the rate of the masterclock",
231           GST_TYPE_AUDIO_BASE_SINK_SLAVE_METHOD, DEFAULT_SLAVE_METHOD,
232           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
233
234   g_object_class_install_property (gobject_class, PROP_CAN_ACTIVATE_PULL,
235       g_param_spec_boolean ("can-activate-pull", "Allow Pull Scheduling",
236           "Allow pull-based scheduling", DEFAULT_CAN_ACTIVATE_PULL,
237           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
238   /**
239    * GstAudioBaseSink:drift-tolerance
240    *
241    * Controls the amount of time in microseconds that clocks are allowed
242    * to drift before resynchronisation happens.
243    *
244    * Since: 0.10.26
245    */
246   g_object_class_install_property (gobject_class, PROP_DRIFT_TOLERANCE,
247       g_param_spec_int64 ("drift-tolerance", "Drift Tolerance",
248           "Tolerance for clock drift in microseconds", 1,
249           G_MAXINT64, DEFAULT_DRIFT_TOLERANCE,
250           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
251   /**
252    * GstAudioBaseSink:alignment_threshold
253    *
254    * Controls the amount of time in nanoseconds that timestamps are allowed
255    * to drift from their ideal time before choosing not to align them.
256    *
257    * Since: 0.10.36
258    */
259   g_object_class_install_property (gobject_class, PROP_ALIGNMENT_THRESHOLD,
260       g_param_spec_uint64 ("alignment-threshold", "Alignment Threshold",
261           "Timestamp alignment threshold in nanoseconds", 1,
262           G_MAXUINT64 - 1, DEFAULT_ALIGNMENT_THRESHOLD,
263           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
264
265   /**
266    * GstAudioBaseSink:discont-wait
267    *
268    * A window of time in nanoseconds to wait before creating a discontinuity as
269    * a result of breaching the drift-tolerance.
270    *
271    * Since: 0.10.36
272    */
273   g_object_class_install_property (gobject_class, PROP_DISCONT_WAIT,
274       g_param_spec_uint64 ("discont-wait", "Discont Wait",
275           "Window of time in nanoseconds to wait before "
276           "creating a discontinuity", 0,
277           G_MAXUINT64 - 1, DEFAULT_DISCONT_WAIT,
278           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
279
280   gstelement_class->change_state =
281       GST_DEBUG_FUNCPTR (gst_audio_base_sink_change_state);
282   gstelement_class->provide_clock =
283       GST_DEBUG_FUNCPTR (gst_audio_base_sink_provide_clock);
284   gstelement_class->query = GST_DEBUG_FUNCPTR (gst_audio_base_sink_query);
285
286   gstbasesink_class->fixate = GST_DEBUG_FUNCPTR (gst_audio_base_sink_fixate);
287   gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_audio_base_sink_setcaps);
288   gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_audio_base_sink_event);
289   gstbasesink_class->wait_eos =
290       GST_DEBUG_FUNCPTR (gst_audio_base_sink_wait_eos);
291   gstbasesink_class->get_times =
292       GST_DEBUG_FUNCPTR (gst_audio_base_sink_get_times);
293   gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_audio_base_sink_preroll);
294   gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_audio_base_sink_render);
295   gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_audio_base_sink_query_pad);
296   gstbasesink_class->activate_pull =
297       GST_DEBUG_FUNCPTR (gst_audio_base_sink_activate_pull);
298
299   /* ref class from a thread-safe context to work around missing bit of
300    * thread-safety in GObject */
301   g_type_class_ref (GST_TYPE_AUDIO_CLOCK);
302   g_type_class_ref (GST_TYPE_AUDIO_RING_BUFFER);
303
304 }
305
306 static void
307 gst_audio_base_sink_init (GstAudioBaseSink * audiobasesink)
308 {
309   GstBaseSink *basesink;
310
311   audiobasesink->priv = GST_AUDIO_BASE_SINK_GET_PRIVATE (audiobasesink);
312
313   audiobasesink->buffer_time = DEFAULT_BUFFER_TIME;
314   audiobasesink->latency_time = DEFAULT_LATENCY_TIME;
315   audiobasesink->priv->slave_method = DEFAULT_SLAVE_METHOD;
316   audiobasesink->priv->drift_tolerance = DEFAULT_DRIFT_TOLERANCE;
317   audiobasesink->priv->alignment_threshold = DEFAULT_ALIGNMENT_THRESHOLD;
318   audiobasesink->priv->discont_wait = DEFAULT_DISCONT_WAIT;
319
320   audiobasesink->provided_clock = gst_audio_clock_new ("GstAudioSinkClock",
321       (GstAudioClockGetTimeFunc) gst_audio_base_sink_get_time, audiobasesink,
322       NULL);
323
324   basesink = GST_BASE_SINK_CAST (audiobasesink);
325   basesink->can_activate_push = TRUE;
326   basesink->can_activate_pull = DEFAULT_CAN_ACTIVATE_PULL;
327
328   gst_base_sink_set_last_sample_enabled (basesink, FALSE);
329   if (DEFAULT_PROVIDE_CLOCK)
330     GST_OBJECT_FLAG_SET (basesink, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
331   else
332     GST_OBJECT_FLAG_UNSET (basesink, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
333 }
334
335 static void
336 gst_audio_base_sink_dispose (GObject * object)
337 {
338   GstAudioBaseSink *sink;
339
340   sink = GST_AUDIO_BASE_SINK (object);
341
342   if (sink->provided_clock) {
343     gst_audio_clock_invalidate (sink->provided_clock);
344     gst_object_unref (sink->provided_clock);
345     sink->provided_clock = NULL;
346   }
347
348   if (sink->ringbuffer) {
349     gst_object_unparent (GST_OBJECT_CAST (sink->ringbuffer));
350     sink->ringbuffer = NULL;
351   }
352
353   G_OBJECT_CLASS (parent_class)->dispose (object);
354 }
355
356
357 static GstClock *
358 gst_audio_base_sink_provide_clock (GstElement * elem)
359 {
360   GstAudioBaseSink *sink;
361   GstClock *clock;
362
363   sink = GST_AUDIO_BASE_SINK (elem);
364
365   /* we have no ringbuffer (must be NULL state) */
366   if (sink->ringbuffer == NULL)
367     goto wrong_state;
368
369   if (!gst_audio_ring_buffer_is_acquired (sink->ringbuffer))
370     goto wrong_state;
371
372   GST_OBJECT_LOCK (sink);
373   if (!GST_OBJECT_FLAG_IS_SET (sink, GST_ELEMENT_FLAG_PROVIDE_CLOCK))
374     goto clock_disabled;
375
376   clock = GST_CLOCK_CAST (gst_object_ref (sink->provided_clock));
377   GST_OBJECT_UNLOCK (sink);
378
379   return clock;
380
381   /* ERRORS */
382 wrong_state:
383   {
384     GST_DEBUG_OBJECT (sink, "ringbuffer not acquired");
385     return NULL;
386   }
387 clock_disabled:
388   {
389     GST_DEBUG_OBJECT (sink, "clock provide disabled");
390     GST_OBJECT_UNLOCK (sink);
391     return NULL;
392   }
393 }
394
395 static gboolean
396 gst_audio_base_sink_query_pad (GstBaseSink * bsink, GstQuery * query)
397 {
398   gboolean res = FALSE;
399   GstAudioBaseSink *basesink;
400
401   basesink = GST_AUDIO_BASE_SINK (bsink);
402
403   switch (GST_QUERY_TYPE (query)) {
404     case GST_QUERY_CONVERT:
405     {
406       GstFormat src_fmt, dest_fmt;
407       gint64 src_val, dest_val;
408
409       GST_LOG_OBJECT (basesink, "query convert");
410
411       if (basesink->ringbuffer) {
412         gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
413         res =
414             gst_audio_ring_buffer_convert (basesink->ringbuffer, src_fmt,
415             src_val, dest_fmt, &dest_val);
416         if (res) {
417           gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
418         }
419       }
420       break;
421     }
422     default:
423       res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
424       break;
425   }
426   return res;
427 }
428
429 static gboolean
430 gst_audio_base_sink_query (GstElement * element, GstQuery * query)
431 {
432   gboolean res = FALSE;
433   GstAudioBaseSink *basesink;
434
435   basesink = GST_AUDIO_BASE_SINK (element);
436
437   switch (GST_QUERY_TYPE (query)) {
438     case GST_QUERY_LATENCY:
439     {
440       gboolean live, us_live;
441       GstClockTime min_l, max_l;
442
443       GST_DEBUG_OBJECT (basesink, "latency query");
444
445       /* ask parent first, it will do an upstream query for us. */
446       if ((res =
447               gst_base_sink_query_latency (GST_BASE_SINK_CAST (basesink), &live,
448                   &us_live, &min_l, &max_l))) {
449         GstClockTime base_latency, min_latency, max_latency;
450
451         /* we and upstream are both live, adjust the min_latency */
452         if (live && us_live) {
453           GstAudioRingBufferSpec *spec;
454
455           GST_OBJECT_LOCK (basesink);
456           if (!basesink->ringbuffer || !basesink->ringbuffer->spec.info.rate) {
457             GST_OBJECT_UNLOCK (basesink);
458
459             GST_DEBUG_OBJECT (basesink,
460                 "we are not yet negotiated, can't report latency yet");
461             res = FALSE;
462             goto done;
463           }
464           spec = &basesink->ringbuffer->spec;
465
466           basesink->priv->us_latency = min_l;
467
468           base_latency =
469               gst_util_uint64_scale_int (spec->seglatency * spec->segsize,
470               GST_SECOND, spec->info.rate * spec->info.bpf);
471           GST_OBJECT_UNLOCK (basesink);
472
473           /* we cannot go lower than the buffer size and the min peer latency */
474           min_latency = base_latency + min_l;
475           /* the max latency is the max of the peer, we can delay an infinite
476            * amount of time. */
477           max_latency = (max_l == -1) ? -1 : (base_latency + max_l);
478
479           GST_DEBUG_OBJECT (basesink,
480               "peer min %" GST_TIME_FORMAT ", our min latency: %"
481               GST_TIME_FORMAT, GST_TIME_ARGS (min_l),
482               GST_TIME_ARGS (min_latency));
483           GST_DEBUG_OBJECT (basesink,
484               "peer max %" GST_TIME_FORMAT ", our max latency: %"
485               GST_TIME_FORMAT, GST_TIME_ARGS (max_l),
486               GST_TIME_ARGS (max_latency));
487         } else {
488           GST_DEBUG_OBJECT (basesink,
489               "peer or we are not live, don't care about latency");
490           min_latency = min_l;
491           max_latency = max_l;
492         }
493         gst_query_set_latency (query, live, min_latency, max_latency);
494       }
495       break;
496     }
497     case GST_QUERY_CONVERT:
498     {
499       GstFormat src_fmt, dest_fmt;
500       gint64 src_val, dest_val;
501
502       GST_LOG_OBJECT (basesink, "query convert");
503
504       if (basesink->ringbuffer) {
505         gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
506         res =
507             gst_audio_ring_buffer_convert (basesink->ringbuffer, src_fmt,
508             src_val, dest_fmt, &dest_val);
509         if (res) {
510           gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
511         }
512       }
513       break;
514     }
515     default:
516       res = GST_ELEMENT_CLASS (parent_class)->query (element, query);
517       break;
518   }
519
520 done:
521   return res;
522 }
523
524
525 static GstClockTime
526 gst_audio_base_sink_get_time (GstClock * clock, GstAudioBaseSink * sink)
527 {
528   guint64 raw, samples;
529   guint delay;
530   GstClockTime result;
531
532   if (sink->ringbuffer == NULL || sink->ringbuffer->spec.info.rate == 0)
533     return GST_CLOCK_TIME_NONE;
534
535   /* our processed samples are always increasing */
536   raw = samples = gst_audio_ring_buffer_samples_done (sink->ringbuffer);
537
538   /* the number of samples not yet processed, this is still queued in the
539    * device (not played for playback). */
540   delay = gst_audio_ring_buffer_delay (sink->ringbuffer);
541
542   if (G_LIKELY (samples >= delay))
543     samples -= delay;
544   else
545     samples = 0;
546
547   result = gst_util_uint64_scale_int (samples, GST_SECOND,
548       sink->ringbuffer->spec.info.rate);
549
550   GST_DEBUG_OBJECT (sink,
551       "processed samples: raw %" G_GUINT64_FORMAT ", delay %u, real %"
552       G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT,
553       raw, delay, samples, GST_TIME_ARGS (result));
554
555   return result;
556 }
557
558 /**
559  * gst_audio_base_sink_set_provide_clock:
560  * @sink: a #GstAudioBaseSink
561  * @provide: new state
562  *
563  * Controls whether @sink will provide a clock or not. If @provide is %TRUE,
564  * gst_element_provide_clock() will return a clock that reflects the datarate
565  * of @sink. If @provide is %FALSE, gst_element_provide_clock() will return NULL.
566  *
567  * Since: 0.10.16
568  */
569 void
570 gst_audio_base_sink_set_provide_clock (GstAudioBaseSink * sink,
571     gboolean provide)
572 {
573   g_return_if_fail (GST_IS_AUDIO_BASE_SINK (sink));
574
575   GST_OBJECT_LOCK (sink);
576   if (provide)
577     GST_OBJECT_FLAG_SET (sink, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
578   else
579     GST_OBJECT_FLAG_UNSET (sink, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
580   GST_OBJECT_UNLOCK (sink);
581 }
582
583 /**
584  * gst_audio_base_sink_get_provide_clock:
585  * @sink: a #GstAudioBaseSink
586  *
587  * Queries whether @sink will provide a clock or not. See also
588  * gst_audio_base_sink_set_provide_clock.
589  *
590  * Returns: %TRUE if @sink will provide a clock.
591  *
592  * Since: 0.10.16
593  */
594 gboolean
595 gst_audio_base_sink_get_provide_clock (GstAudioBaseSink * sink)
596 {
597   gboolean result;
598
599   g_return_val_if_fail (GST_IS_AUDIO_BASE_SINK (sink), FALSE);
600
601   GST_OBJECT_LOCK (sink);
602   result = GST_OBJECT_FLAG_IS_SET (sink, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
603   GST_OBJECT_UNLOCK (sink);
604
605   return result;
606 }
607
608 /**
609  * gst_audio_base_sink_set_slave_method:
610  * @sink: a #GstAudioBaseSink
611  * @method: the new slave method
612  *
613  * Controls how clock slaving will be performed in @sink.
614  *
615  * Since: 0.10.16
616  */
617 void
618 gst_audio_base_sink_set_slave_method (GstAudioBaseSink * sink,
619     GstAudioBaseSinkSlaveMethod method)
620 {
621   g_return_if_fail (GST_IS_AUDIO_BASE_SINK (sink));
622
623   GST_OBJECT_LOCK (sink);
624   sink->priv->slave_method = method;
625   GST_OBJECT_UNLOCK (sink);
626 }
627
628 /**
629  * gst_audio_base_sink_get_slave_method:
630  * @sink: a #GstAudioBaseSink
631  *
632  * Get the current slave method used by @sink.
633  *
634  * Returns: The current slave method used by @sink.
635  *
636  * Since: 0.10.16
637  */
638 GstAudioBaseSinkSlaveMethod
639 gst_audio_base_sink_get_slave_method (GstAudioBaseSink * sink)
640 {
641   GstAudioBaseSinkSlaveMethod result;
642
643   g_return_val_if_fail (GST_IS_AUDIO_BASE_SINK (sink), -1);
644
645   GST_OBJECT_LOCK (sink);
646   result = sink->priv->slave_method;
647   GST_OBJECT_UNLOCK (sink);
648
649   return result;
650 }
651
652
653 /**
654  * gst_audio_base_sink_set_drift_tolerance:
655  * @sink: a #GstAudioBaseSink
656  * @drift_tolerance: the new drift tolerance in microseconds
657  *
658  * Controls the sink's drift tolerance.
659  *
660  * Since: 0.10.31
661  */
662 void
663 gst_audio_base_sink_set_drift_tolerance (GstAudioBaseSink * sink,
664     gint64 drift_tolerance)
665 {
666   g_return_if_fail (GST_IS_AUDIO_BASE_SINK (sink));
667
668   GST_OBJECT_LOCK (sink);
669   sink->priv->drift_tolerance = drift_tolerance;
670   GST_OBJECT_UNLOCK (sink);
671 }
672
673 /**
674  * gst_audio_base_sink_get_drift_tolerance
675  * @sink: a #GstAudioBaseSink
676  *
677  * Get the current drift tolerance, in microseconds, used by @sink.
678  *
679  * Returns: The current drift tolerance used by @sink.
680  *
681  * Since: 0.10.31
682  */
683 gint64
684 gst_audio_base_sink_get_drift_tolerance (GstAudioBaseSink * sink)
685 {
686   gint64 result;
687
688   g_return_val_if_fail (GST_IS_AUDIO_BASE_SINK (sink), -1);
689
690   GST_OBJECT_LOCK (sink);
691   result = sink->priv->drift_tolerance;
692   GST_OBJECT_UNLOCK (sink);
693
694   return result;
695 }
696
697 /**
698  * gst_audio_base_sink_set_alignment_threshold:
699  * @sink: a #GstAudioBaseSink
700  * @alignment_threshold: the new alignment threshold in nanoseconds
701  *
702  * Controls the sink's alignment threshold.
703  *
704  * Since: 0.10.36
705  */
706 void
707 gst_audio_base_sink_set_alignment_threshold (GstAudioBaseSink * sink,
708     GstClockTime alignment_threshold)
709 {
710   g_return_if_fail (GST_IS_AUDIO_BASE_SINK (sink));
711
712   GST_OBJECT_LOCK (sink);
713   sink->priv->alignment_threshold = alignment_threshold;
714   GST_OBJECT_UNLOCK (sink);
715 }
716
717 /**
718  * gst_audio_base_sink_get_alignment_threshold
719  * @sink: a #GstAudioBaseSink
720  *
721  * Get the current alignment threshold, in nanoseconds, used by @sink.
722  *
723  * Returns: The current alignment threshold used by @sink.
724  *
725  * Since: 0.10.36
726  */
727 GstClockTime
728 gst_audio_base_sink_get_alignment_threshold (GstAudioBaseSink * sink)
729 {
730   gint64 result;
731
732   g_return_val_if_fail (GST_IS_AUDIO_BASE_SINK (sink), -1);
733
734   GST_OBJECT_LOCK (sink);
735   result = sink->priv->alignment_threshold;
736   GST_OBJECT_UNLOCK (sink);
737
738   return result;
739 }
740
741 /**
742  * gst_audio_base_sink_set_discont_wait:
743  * @sink: a #GstAudioBaseSink
744  * @discont_wait: the new discont wait in nanoseconds
745  *
746  * Controls how long the sink will wait before creating a discontinuity.
747  *
748  * Since: 0.10.36
749  */
750 void
751 gst_audio_base_sink_set_discont_wait (GstAudioBaseSink * sink,
752     GstClockTime discont_wait)
753 {
754   g_return_if_fail (GST_IS_AUDIO_BASE_SINK (sink));
755
756   GST_OBJECT_LOCK (sink);
757   sink->priv->discont_wait = discont_wait;
758   GST_OBJECT_UNLOCK (sink);
759 }
760
761 /**
762  * gst_audio_base_sink_get_discont_wait
763  * @sink: a #GstAudioBaseSink
764  *
765  * Get the current discont wait, in nanoseconds, used by @sink.
766  *
767  * Returns: The current discont wait used by @sink.
768  *
769  * Since: 0.10.36
770  */
771 GstClockTime
772 gst_audio_base_sink_get_discont_wait (GstAudioBaseSink * sink)
773 {
774   GstClockTime result;
775
776   g_return_val_if_fail (GST_IS_AUDIO_BASE_SINK (sink), -1);
777
778   GST_OBJECT_LOCK (sink);
779   result = sink->priv->discont_wait;
780   GST_OBJECT_UNLOCK (sink);
781
782   return result;
783 }
784
785 static void
786 gst_audio_base_sink_set_property (GObject * object, guint prop_id,
787     const GValue * value, GParamSpec * pspec)
788 {
789   GstAudioBaseSink *sink;
790
791   sink = GST_AUDIO_BASE_SINK (object);
792
793   switch (prop_id) {
794     case PROP_BUFFER_TIME:
795       sink->buffer_time = g_value_get_int64 (value);
796       break;
797     case PROP_LATENCY_TIME:
798       sink->latency_time = g_value_get_int64 (value);
799       break;
800     case PROP_PROVIDE_CLOCK:
801       gst_audio_base_sink_set_provide_clock (sink, g_value_get_boolean (value));
802       break;
803     case PROP_SLAVE_METHOD:
804       gst_audio_base_sink_set_slave_method (sink, g_value_get_enum (value));
805       break;
806     case PROP_CAN_ACTIVATE_PULL:
807       GST_BASE_SINK (sink)->can_activate_pull = g_value_get_boolean (value);
808       break;
809     case PROP_DRIFT_TOLERANCE:
810       gst_audio_base_sink_set_drift_tolerance (sink, g_value_get_int64 (value));
811       break;
812     case PROP_ALIGNMENT_THRESHOLD:
813       gst_audio_base_sink_set_alignment_threshold (sink,
814           g_value_get_uint64 (value));
815       break;
816     case PROP_DISCONT_WAIT:
817       gst_audio_base_sink_set_discont_wait (sink, g_value_get_uint64 (value));
818       break;
819     default:
820       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
821       break;
822   }
823 }
824
825 static void
826 gst_audio_base_sink_get_property (GObject * object, guint prop_id,
827     GValue * value, GParamSpec * pspec)
828 {
829   GstAudioBaseSink *sink;
830
831   sink = GST_AUDIO_BASE_SINK (object);
832
833   switch (prop_id) {
834     case PROP_BUFFER_TIME:
835       g_value_set_int64 (value, sink->buffer_time);
836       break;
837     case PROP_LATENCY_TIME:
838       g_value_set_int64 (value, sink->latency_time);
839       break;
840     case PROP_PROVIDE_CLOCK:
841       g_value_set_boolean (value, gst_audio_base_sink_get_provide_clock (sink));
842       break;
843     case PROP_SLAVE_METHOD:
844       g_value_set_enum (value, gst_audio_base_sink_get_slave_method (sink));
845       break;
846     case PROP_CAN_ACTIVATE_PULL:
847       g_value_set_boolean (value, GST_BASE_SINK (sink)->can_activate_pull);
848       break;
849     case PROP_DRIFT_TOLERANCE:
850       g_value_set_int64 (value, gst_audio_base_sink_get_drift_tolerance (sink));
851       break;
852     case PROP_ALIGNMENT_THRESHOLD:
853       g_value_set_uint64 (value,
854           gst_audio_base_sink_get_alignment_threshold (sink));
855       break;
856     case PROP_DISCONT_WAIT:
857       g_value_set_uint64 (value, gst_audio_base_sink_get_discont_wait (sink));
858       break;
859     default:
860       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
861       break;
862   }
863 }
864
865 static gboolean
866 gst_audio_base_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
867 {
868   GstAudioBaseSink *sink = GST_AUDIO_BASE_SINK (bsink);
869   GstAudioRingBufferSpec *spec;
870   GstClockTime now;
871   GstClockTime crate_num, crate_denom;
872
873   if (!sink->ringbuffer)
874     return FALSE;
875
876   spec = &sink->ringbuffer->spec;
877
878   GST_DEBUG_OBJECT (sink, "release old ringbuffer");
879
880   /* get current time, updates the last_time. When the subclass has a clock that
881    * restarts from 0 when a new format is negotiated, it will call
882    * gst_audio_clock_reset() which will use this last_time to create an offset
883    * so that time from the clock keeps on increasing monotonically. */
884   now = gst_clock_get_time (sink->provided_clock);
885
886   GST_DEBUG_OBJECT (sink, "time was %" GST_TIME_FORMAT, GST_TIME_ARGS (now));
887
888   /* release old ringbuffer */
889   gst_audio_ring_buffer_pause (sink->ringbuffer);
890   gst_audio_ring_buffer_activate (sink->ringbuffer, FALSE);
891   gst_audio_ring_buffer_release (sink->ringbuffer);
892
893   GST_DEBUG_OBJECT (sink, "parse caps");
894
895   spec->buffer_time = sink->buffer_time;
896   spec->latency_time = sink->latency_time;
897
898   /* parse new caps */
899   if (!gst_audio_ring_buffer_parse_caps (spec, caps))
900     goto parse_error;
901
902   gst_audio_ring_buffer_debug_spec_buff (spec);
903
904   GST_DEBUG_OBJECT (sink, "acquire ringbuffer");
905   if (!gst_audio_ring_buffer_acquire (sink->ringbuffer, spec))
906     goto acquire_error;
907
908   if (bsink->pad_mode == GST_PAD_MODE_PUSH) {
909     GST_DEBUG_OBJECT (sink, "activate ringbuffer");
910     gst_audio_ring_buffer_activate (sink->ringbuffer, TRUE);
911   }
912
913   /* due to possible changes in the spec file we should recalibrate the clock */
914   gst_clock_get_calibration (sink->provided_clock, NULL, NULL,
915       &crate_num, &crate_denom);
916   gst_clock_set_calibration (sink->provided_clock,
917       gst_clock_get_internal_time (sink->provided_clock), now, crate_num,
918       crate_denom);
919
920   /* calculate actual latency and buffer times.
921    * FIXME: In 0.11, store the latency_time internally in ns */
922   spec->latency_time = gst_util_uint64_scale (spec->segsize,
923       (GST_SECOND / GST_USECOND), spec->info.rate * spec->info.bpf);
924
925   spec->buffer_time = spec->segtotal * spec->latency_time;
926
927   gst_audio_ring_buffer_debug_spec_buff (spec);
928
929   return TRUE;
930
931   /* ERRORS */
932 parse_error:
933   {
934     GST_DEBUG_OBJECT (sink, "could not parse caps");
935     GST_ELEMENT_ERROR (sink, STREAM, FORMAT,
936         (NULL), ("cannot parse audio format."));
937     return FALSE;
938   }
939 acquire_error:
940   {
941     GST_DEBUG_OBJECT (sink, "could not acquire ringbuffer");
942     return FALSE;
943   }
944 }
945
946 static void
947 gst_audio_base_sink_fixate (GstBaseSink * bsink, GstCaps * caps)
948 {
949   GstStructure *s;
950   gint width, depth;
951
952   s = gst_caps_get_structure (caps, 0);
953
954   /* fields for all formats */
955   gst_structure_fixate_field_nearest_int (s, "rate", 44100);
956   gst_structure_fixate_field_nearest_int (s, "channels", 2);
957   gst_structure_fixate_field_nearest_int (s, "width", 16);
958
959   /* fields for int */
960   if (gst_structure_has_field (s, "depth")) {
961     gst_structure_get_int (s, "width", &width);
962     /* round width to nearest multiple of 8 for the depth */
963     depth = GST_ROUND_UP_8 (width);
964     gst_structure_fixate_field_nearest_int (s, "depth", depth);
965   }
966   if (gst_structure_has_field (s, "signed"))
967     gst_structure_fixate_field_boolean (s, "signed", TRUE);
968   if (gst_structure_has_field (s, "endianness"))
969     gst_structure_fixate_field_nearest_int (s, "endianness", G_BYTE_ORDER);
970
971   GST_BASE_SINK_CLASS (parent_class)->fixate (bsink, caps);
972 }
973
974 static void
975 gst_audio_base_sink_get_times (GstBaseSink * bsink, GstBuffer * buffer,
976     GstClockTime * start, GstClockTime * end)
977 {
978   /* our clock sync is a bit too much for the base class to handle so
979    * we implement it ourselves. */
980   *start = GST_CLOCK_TIME_NONE;
981   *end = GST_CLOCK_TIME_NONE;
982 }
983
984 /* This waits for the drain to happen and can be canceled */
985 static gboolean
986 gst_audio_base_sink_drain (GstAudioBaseSink * sink)
987 {
988   if (!sink->ringbuffer)
989     return TRUE;
990   if (!sink->ringbuffer->spec.info.rate)
991     return TRUE;
992
993   /* if PLAYING is interrupted,
994    * arrange to have clock running when going to PLAYING again */
995   g_atomic_int_set (&sink->eos_rendering, 1);
996
997   /* need to start playback before we can drain, but only when
998    * we have successfully negotiated a format and thus acquired the
999    * ringbuffer. */
1000   if (gst_audio_ring_buffer_is_acquired (sink->ringbuffer))
1001     gst_audio_ring_buffer_start (sink->ringbuffer);
1002
1003   if (sink->priv->eos_time != -1) {
1004     GST_DEBUG_OBJECT (sink,
1005         "last sample time %" GST_TIME_FORMAT,
1006         GST_TIME_ARGS (sink->priv->eos_time));
1007
1008     /* wait for the EOS time to be reached, this is the time when the last
1009      * sample is played. */
1010     gst_base_sink_wait_eos (GST_BASE_SINK (sink), sink->priv->eos_time, NULL);
1011
1012     GST_DEBUG_OBJECT (sink, "drained audio");
1013   }
1014   g_atomic_int_set (&sink->eos_rendering, 0);
1015   return TRUE;
1016 }
1017
1018 static GstFlowReturn
1019 gst_audio_base_sink_wait_eos (GstBaseSink * bsink, GstEvent * event)
1020 {
1021   GstAudioBaseSink *sink = GST_AUDIO_BASE_SINK (bsink);
1022   GstFlowReturn ret;
1023
1024   ret = GST_BASE_SINK_CLASS (parent_class)->event (bsink, event);
1025   if (ret != GST_FLOW_OK)
1026     return ret;
1027
1028   /* now wait till we played everything */
1029   gst_audio_base_sink_drain (sink);
1030
1031   return ret;
1032 }
1033
1034 static gboolean
1035 gst_audio_base_sink_event (GstBaseSink * bsink, GstEvent * event)
1036 {
1037   GstAudioBaseSink *sink = GST_AUDIO_BASE_SINK (bsink);
1038
1039   switch (GST_EVENT_TYPE (event)) {
1040     case GST_EVENT_FLUSH_START:
1041       if (sink->ringbuffer)
1042         gst_audio_ring_buffer_set_flushing (sink->ringbuffer, TRUE);
1043       break;
1044     case GST_EVENT_FLUSH_STOP:
1045       /* always resync on sample after a flush */
1046       sink->priv->avg_skew = -1;
1047       sink->next_sample = -1;
1048       sink->priv->eos_time = -1;
1049       sink->priv->discont_time = -1;
1050       if (sink->ringbuffer)
1051         gst_audio_ring_buffer_set_flushing (sink->ringbuffer, FALSE);
1052       break;
1053     default:
1054       break;
1055   }
1056   return GST_BASE_SINK_CLASS (parent_class)->event (bsink, event);
1057 }
1058
1059 static GstFlowReturn
1060 gst_audio_base_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
1061 {
1062   GstAudioBaseSink *sink = GST_AUDIO_BASE_SINK (bsink);
1063
1064   if (!gst_audio_ring_buffer_is_acquired (sink->ringbuffer))
1065     goto wrong_state;
1066
1067   /* we don't really do anything when prerolling. We could make a
1068    * property to play this buffer to have some sort of scrubbing
1069    * support. */
1070   return GST_FLOW_OK;
1071
1072 wrong_state:
1073   {
1074     GST_DEBUG_OBJECT (sink, "ringbuffer in wrong state");
1075     GST_ELEMENT_ERROR (sink, STREAM, FORMAT, (NULL), ("sink not negotiated."));
1076     return GST_FLOW_NOT_NEGOTIATED;
1077   }
1078 }
1079
1080 static guint64
1081 gst_audio_base_sink_get_offset (GstAudioBaseSink * sink)
1082 {
1083   guint64 sample;
1084   gint writeseg, segdone, sps;
1085   gint diff;
1086
1087   /* assume we can append to the previous sample */
1088   sample = sink->next_sample;
1089   /* no previous sample, try to insert at position 0 */
1090   if (sample == -1)
1091     sample = 0;
1092
1093   sps = sink->ringbuffer->samples_per_seg;
1094
1095   /* figure out the segment and the offset inside the segment where
1096    * the sample should be written. */
1097   writeseg = sample / sps;
1098
1099   /* get the currently processed segment */
1100   segdone = g_atomic_int_get (&sink->ringbuffer->segdone)
1101       - sink->ringbuffer->segbase;
1102
1103   /* see how far away it is from the write segment */
1104   diff = writeseg - segdone;
1105   if (diff < 0) {
1106     /* sample would be dropped, position to next playable position */
1107     sample = (segdone + 1) * sps;
1108   }
1109
1110   return sample;
1111 }
1112
1113 static GstClockTime
1114 clock_convert_external (GstClockTime external, GstClockTime cinternal,
1115     GstClockTime cexternal, GstClockTime crate_num, GstClockTime crate_denom)
1116 {
1117   /* adjust for rate and speed */
1118   if (external >= cexternal) {
1119     external =
1120         gst_util_uint64_scale (external - cexternal, crate_denom, crate_num);
1121     external += cinternal;
1122   } else {
1123     external =
1124         gst_util_uint64_scale (cexternal - external, crate_denom, crate_num);
1125     if (cinternal > external)
1126       external = cinternal - external;
1127     else
1128       external = 0;
1129   }
1130   return external;
1131 }
1132
1133 /* algorithm to calculate sample positions that will result in resampling to
1134  * match the clock rate of the master */
1135 static void
1136 gst_audio_base_sink_resample_slaving (GstAudioBaseSink * sink,
1137     GstClockTime render_start, GstClockTime render_stop,
1138     GstClockTime * srender_start, GstClockTime * srender_stop)
1139 {
1140   GstClockTime cinternal, cexternal;
1141   GstClockTime crate_num, crate_denom;
1142
1143   /* FIXME, we can sample and add observations here or use the timeouts on the
1144    * clock. No idea which one is better or more stable. The timeout seems more
1145    * arbitrary but this one seems more demanding and does not work when there is
1146    * no data comming in to the sink. */
1147 #if 0
1148   GstClockTime etime, itime;
1149   gdouble r_squared;
1150
1151   /* sample clocks and figure out clock skew */
1152   etime = gst_clock_get_time (GST_ELEMENT_CLOCK (sink));
1153   itime = gst_audio_clock_get_time (sink->provided_clock);
1154
1155   /* add new observation */
1156   gst_clock_add_observation (sink->provided_clock, itime, etime, &r_squared);
1157 #endif
1158
1159   /* get calibration parameters to compensate for speed and offset differences
1160    * when we are slaved */
1161   gst_clock_get_calibration (sink->provided_clock, &cinternal, &cexternal,
1162       &crate_num, &crate_denom);
1163
1164   GST_DEBUG_OBJECT (sink, "internal %" GST_TIME_FORMAT " external %"
1165       GST_TIME_FORMAT " %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f",
1166       GST_TIME_ARGS (cinternal), GST_TIME_ARGS (cexternal), crate_num,
1167       crate_denom, gst_guint64_to_gdouble (crate_num) /
1168       gst_guint64_to_gdouble (crate_denom));
1169
1170   if (crate_num == 0)
1171     crate_denom = crate_num = 1;
1172
1173   /* bring external time to internal time */
1174   render_start = clock_convert_external (render_start, cinternal, cexternal,
1175       crate_num, crate_denom);
1176   render_stop = clock_convert_external (render_stop, cinternal, cexternal,
1177       crate_num, crate_denom);
1178
1179   GST_DEBUG_OBJECT (sink,
1180       "after slaving: start %" GST_TIME_FORMAT " - stop %" GST_TIME_FORMAT,
1181       GST_TIME_ARGS (render_start), GST_TIME_ARGS (render_stop));
1182
1183   *srender_start = render_start;
1184   *srender_stop = render_stop;
1185 }
1186
1187 /* algorithm to calculate sample positions that will result in changing the
1188  * playout pointer to match the clock rate of the master */
1189 static void
1190 gst_audio_base_sink_skew_slaving (GstAudioBaseSink * sink,
1191     GstClockTime render_start, GstClockTime render_stop,
1192     GstClockTime * srender_start, GstClockTime * srender_stop)
1193 {
1194   GstClockTime cinternal, cexternal, crate_num, crate_denom;
1195   GstClockTime etime, itime;
1196   GstClockTimeDiff skew, mdrift, mdrift2;
1197   gint driftsamples;
1198   gint64 last_align;
1199
1200   /* get calibration parameters to compensate for offsets */
1201   gst_clock_get_calibration (sink->provided_clock, &cinternal, &cexternal,
1202       &crate_num, &crate_denom);
1203
1204   /* sample clocks and figure out clock skew */
1205   etime = gst_clock_get_time (GST_ELEMENT_CLOCK (sink));
1206   itime = gst_audio_clock_get_time (sink->provided_clock);
1207   itime = gst_audio_clock_adjust (sink->provided_clock, itime);
1208
1209   GST_DEBUG_OBJECT (sink,
1210       "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT
1211       " cinternal %" GST_TIME_FORMAT " cexternal %" GST_TIME_FORMAT,
1212       GST_TIME_ARGS (itime), GST_TIME_ARGS (etime),
1213       GST_TIME_ARGS (cinternal), GST_TIME_ARGS (cexternal));
1214
1215   /* make sure we never go below 0 */
1216   etime = etime > cexternal ? etime - cexternal : 0;
1217   itime = itime > cinternal ? itime - cinternal : 0;
1218
1219   /* do itime - etime.
1220    * positive value means external clock goes slower
1221    * negative value means external clock goes faster */
1222   skew = GST_CLOCK_DIFF (etime, itime);
1223   if (sink->priv->avg_skew == -1) {
1224     /* first observation */
1225     sink->priv->avg_skew = skew;
1226   } else {
1227     /* next observations use a moving average */
1228     sink->priv->avg_skew = (31 * sink->priv->avg_skew + skew) / 32;
1229   }
1230
1231   GST_DEBUG_OBJECT (sink, "internal %" GST_TIME_FORMAT " external %"
1232       GST_TIME_FORMAT " skew %" G_GINT64_FORMAT " avg %" G_GINT64_FORMAT,
1233       GST_TIME_ARGS (itime), GST_TIME_ARGS (etime), skew, sink->priv->avg_skew);
1234
1235   /* the max drift we allow */
1236   mdrift = sink->priv->drift_tolerance * 1000;
1237   mdrift2 = mdrift / 2;
1238
1239   /* adjust playout pointer based on skew */
1240   if (sink->priv->avg_skew > mdrift2) {
1241     /* master is running slower, move internal time forward */
1242     GST_WARNING_OBJECT (sink,
1243         "correct clock skew %" G_GINT64_FORMAT " > %" G_GINT64_FORMAT,
1244         sink->priv->avg_skew, mdrift2);
1245     cexternal = cexternal > mdrift ? cexternal - mdrift : 0;
1246     sink->priv->avg_skew -= mdrift;
1247
1248     driftsamples = (sink->ringbuffer->spec.info.rate * mdrift) / GST_SECOND;
1249     last_align = sink->priv->last_align;
1250
1251     /* if we were aligning in the wrong direction or we aligned more than what we
1252      * will correct, resync */
1253     if (last_align < 0 || last_align > driftsamples)
1254       sink->next_sample = -1;
1255
1256     GST_DEBUG_OBJECT (sink,
1257         "last_align %" G_GINT64_FORMAT " driftsamples %u, next %"
1258         G_GUINT64_FORMAT, last_align, driftsamples, sink->next_sample);
1259
1260     gst_clock_set_calibration (sink->provided_clock, cinternal, cexternal,
1261         crate_num, crate_denom);
1262   } else if (sink->priv->avg_skew < -mdrift2) {
1263     /* master is running faster, move external time forwards */
1264     GST_WARNING_OBJECT (sink,
1265         "correct clock skew %" G_GINT64_FORMAT " < %" G_GINT64_FORMAT,
1266         sink->priv->avg_skew, -mdrift2);
1267     cexternal += mdrift;
1268     sink->priv->avg_skew += mdrift;
1269
1270     driftsamples = (sink->ringbuffer->spec.info.rate * mdrift) / GST_SECOND;
1271     last_align = sink->priv->last_align;
1272
1273     /* if we were aligning in the wrong direction or we aligned more than what we
1274      * will correct, resync */
1275     if (last_align > 0 || -last_align > driftsamples)
1276       sink->next_sample = -1;
1277
1278     GST_DEBUG_OBJECT (sink,
1279         "last_align %" G_GINT64_FORMAT " driftsamples %u, next %"
1280         G_GUINT64_FORMAT, last_align, driftsamples, sink->next_sample);
1281
1282     gst_clock_set_calibration (sink->provided_clock, cinternal, cexternal,
1283         crate_num, crate_denom);
1284   }
1285
1286   /* convert, ignoring speed */
1287   render_start = clock_convert_external (render_start, cinternal, cexternal,
1288       crate_num, crate_denom);
1289   render_stop = clock_convert_external (render_stop, cinternal, cexternal,
1290       crate_num, crate_denom);
1291
1292   *srender_start = render_start;
1293   *srender_stop = render_stop;
1294 }
1295
1296 /* apply the clock offset but do no slaving otherwise */
1297 static void
1298 gst_audio_base_sink_none_slaving (GstAudioBaseSink * sink,
1299     GstClockTime render_start, GstClockTime render_stop,
1300     GstClockTime * srender_start, GstClockTime * srender_stop)
1301 {
1302   GstClockTime cinternal, cexternal, crate_num, crate_denom;
1303
1304   /* get calibration parameters to compensate for offsets */
1305   gst_clock_get_calibration (sink->provided_clock, &cinternal, &cexternal,
1306       &crate_num, &crate_denom);
1307
1308   /* convert, ignoring speed */
1309   render_start = clock_convert_external (render_start, cinternal, cexternal,
1310       crate_num, crate_denom);
1311   render_stop = clock_convert_external (render_stop, cinternal, cexternal,
1312       crate_num, crate_denom);
1313
1314   *srender_start = render_start;
1315   *srender_stop = render_stop;
1316 }
1317
1318 /* converts render_start and render_stop to their slaved values */
1319 static void
1320 gst_audio_base_sink_handle_slaving (GstAudioBaseSink * sink,
1321     GstClockTime render_start, GstClockTime render_stop,
1322     GstClockTime * srender_start, GstClockTime * srender_stop)
1323 {
1324   switch (sink->priv->slave_method) {
1325     case GST_AUDIO_BASE_SINK_SLAVE_RESAMPLE:
1326       gst_audio_base_sink_resample_slaving (sink, render_start, render_stop,
1327           srender_start, srender_stop);
1328       break;
1329     case GST_AUDIO_BASE_SINK_SLAVE_SKEW:
1330       gst_audio_base_sink_skew_slaving (sink, render_start, render_stop,
1331           srender_start, srender_stop);
1332       break;
1333     case GST_AUDIO_BASE_SINK_SLAVE_NONE:
1334       gst_audio_base_sink_none_slaving (sink, render_start, render_stop,
1335           srender_start, srender_stop);
1336       break;
1337     default:
1338       g_warning ("unknown slaving method %d", sink->priv->slave_method);
1339       break;
1340   }
1341 }
1342
1343 /* must be called with LOCK */
1344 static GstFlowReturn
1345 gst_audio_base_sink_sync_latency (GstBaseSink * bsink, GstMiniObject * obj)
1346 {
1347   GstClock *clock;
1348   GstClockReturn status;
1349   GstClockTime time, render_delay;
1350   GstFlowReturn ret;
1351   GstAudioBaseSink *sink;
1352   GstClockTime itime, etime;
1353   GstClockTime rate_num, rate_denom;
1354   GstClockTimeDiff jitter;
1355
1356   sink = GST_AUDIO_BASE_SINK (bsink);
1357
1358   clock = GST_ELEMENT_CLOCK (sink);
1359   if (G_UNLIKELY (clock == NULL))
1360     goto no_clock;
1361
1362   /* we provided the global clock, don't need to do anything special */
1363   if (clock == sink->provided_clock)
1364     goto no_slaving;
1365
1366   GST_OBJECT_UNLOCK (sink);
1367
1368   do {
1369     GST_DEBUG_OBJECT (sink, "checking preroll");
1370
1371     ret = gst_base_sink_do_preroll (bsink, obj);
1372     if (ret != GST_FLOW_OK)
1373       goto flushing;
1374
1375     GST_OBJECT_LOCK (sink);
1376     time = sink->priv->us_latency;
1377     GST_OBJECT_UNLOCK (sink);
1378
1379     /* Renderdelay is added onto our own latency, and needs
1380      * to be subtracted as well */
1381     render_delay = gst_base_sink_get_render_delay (bsink);
1382
1383     if (G_LIKELY (time > render_delay))
1384       time -= render_delay;
1385     else
1386       time = 0;
1387
1388     /* preroll done, we can sync since we are in PLAYING now. */
1389     GST_DEBUG_OBJECT (sink, "possibly waiting for clock to reach %"
1390         GST_TIME_FORMAT, GST_TIME_ARGS (time));
1391
1392     /* wait for the clock, this can be interrupted because we got shut down or
1393      * we PAUSED. */
1394     status = gst_base_sink_wait_clock (bsink, time, &jitter);
1395
1396     GST_DEBUG_OBJECT (sink, "clock returned %d %" GST_TIME_FORMAT, status,
1397         GST_TIME_ARGS (jitter));
1398
1399     /* invalid time, no clock or sync disabled, just continue then */
1400     if (status == GST_CLOCK_BADTIME)
1401       break;
1402
1403     /* waiting could have been interrupted and we can be flushing now */
1404     if (G_UNLIKELY (bsink->flushing))
1405       goto flushing;
1406
1407     /* retry if we got unscheduled, which means we did not reach the timeout
1408      * yet. if some other error occures, we continue. */
1409   } while (status == GST_CLOCK_UNSCHEDULED);
1410
1411   GST_OBJECT_LOCK (sink);
1412   GST_DEBUG_OBJECT (sink, "latency synced");
1413
1414   /* when we prerolled in time, we can accurately set the calibration,
1415    * our internal clock should exactly have been the latency (== the running
1416    * time of the external clock) */
1417   etime = GST_ELEMENT_CAST (sink)->base_time + time;
1418   itime = gst_audio_clock_get_time (sink->provided_clock);
1419   itime = gst_audio_clock_adjust (sink->provided_clock, itime);
1420
1421   if (status == GST_CLOCK_EARLY) {
1422     /* when we prerolled late, we have to take into account the lateness */
1423     GST_DEBUG_OBJECT (sink, "late preroll, adding jitter");
1424     etime += jitter;
1425   }
1426
1427   /* start ringbuffer so we can start slaving right away when we need to */
1428   gst_audio_ring_buffer_start (sink->ringbuffer);
1429
1430   GST_DEBUG_OBJECT (sink,
1431       "internal time: %" GST_TIME_FORMAT " external time: %" GST_TIME_FORMAT,
1432       GST_TIME_ARGS (itime), GST_TIME_ARGS (etime));
1433
1434   /* copy the original calibrated rate but update the internal and external
1435    * times. */
1436   gst_clock_get_calibration (sink->provided_clock, NULL, NULL, &rate_num,
1437       &rate_denom);
1438   gst_clock_set_calibration (sink->provided_clock, itime, etime,
1439       rate_num, rate_denom);
1440
1441   switch (sink->priv->slave_method) {
1442     case GST_AUDIO_BASE_SINK_SLAVE_RESAMPLE:
1443       /* only set as master when we are resampling */
1444       GST_DEBUG_OBJECT (sink, "Setting clock as master");
1445       gst_clock_set_master (sink->provided_clock, clock);
1446       break;
1447     case GST_AUDIO_BASE_SINK_SLAVE_SKEW:
1448     case GST_AUDIO_BASE_SINK_SLAVE_NONE:
1449     default:
1450       break;
1451   }
1452
1453   sink->priv->avg_skew = -1;
1454   sink->next_sample = -1;
1455   sink->priv->eos_time = -1;
1456   sink->priv->discont_time = -1;
1457
1458   return GST_FLOW_OK;
1459
1460   /* ERRORS */
1461 no_clock:
1462   {
1463     GST_DEBUG_OBJECT (sink, "we have no clock");
1464     return GST_FLOW_OK;
1465   }
1466 no_slaving:
1467   {
1468     GST_DEBUG_OBJECT (sink, "we are not slaved");
1469     return GST_FLOW_OK;
1470   }
1471 flushing:
1472   {
1473     GST_DEBUG_OBJECT (sink, "we are flushing");
1474     GST_OBJECT_LOCK (sink);
1475     return GST_FLOW_WRONG_STATE;
1476   }
1477 }
1478
1479 static gint64
1480 gst_audio_base_sink_get_alignment (GstAudioBaseSink * sink,
1481     GstClockTime sample_offset)
1482 {
1483   GstAudioRingBuffer *ringbuf = sink->ringbuffer;
1484   gint64 align;
1485   gint64 sample_diff;
1486   gint64 max_sample_diff;
1487   gint segdone = g_atomic_int_get (&ringbuf->segdone) - ringbuf->segbase;
1488   gint64 samples_done = segdone * ringbuf->samples_per_seg;
1489   gint64 headroom = sample_offset - samples_done;
1490   gboolean allow_align = TRUE;
1491   gboolean discont = FALSE;
1492   gint rate;
1493
1494   /* now try to align the sample to the previous one, first see how big the
1495    * difference is. */
1496   if (sample_offset >= sink->next_sample)
1497     sample_diff = sample_offset - sink->next_sample;
1498   else
1499     sample_diff = sink->next_sample - sample_offset;
1500
1501   rate = GST_AUDIO_INFO_RATE (&ringbuf->spec.info);
1502
1503   /* calculate the max allowed drift in units of samples. */
1504   max_sample_diff = gst_util_uint64_scale_int (sink->priv->alignment_threshold,
1505       rate, GST_SECOND);
1506
1507   /* calc align with previous sample */
1508   align = sink->next_sample - sample_offset;
1509
1510   /* don't align if it means writing behind the read-segment */
1511   if (sample_diff > headroom && align < 0)
1512     allow_align = FALSE;
1513
1514   if (G_UNLIKELY (sample_diff >= max_sample_diff)) {
1515     /* wait before deciding to make a discontinuity */
1516     if (sink->priv->discont_wait > 0) {
1517       GstClockTime time = gst_util_uint64_scale_int (sample_offset,
1518           GST_SECOND, rate);
1519       if (sink->priv->discont_time == -1) {
1520         /* discont candidate */
1521         sink->priv->discont_time = time;
1522       } else if (time - sink->priv->discont_time >= sink->priv->discont_wait) {
1523         /* discont_wait expired, discontinuity detected */
1524         discont = TRUE;
1525         sink->priv->discont_time = -1;
1526       }
1527     } else {
1528       discont = TRUE;
1529     }
1530   } else if (G_UNLIKELY (sink->priv->discont_time != -1)) {
1531     /* we have had a discont, but are now back on track! */
1532     sink->priv->discont_time = -1;
1533   }
1534
1535   if (G_LIKELY (!discont && allow_align)) {
1536     GST_DEBUG_OBJECT (sink,
1537         "align with prev sample, ABS (%" G_GINT64_FORMAT ") < %"
1538         G_GINT64_FORMAT, align, max_sample_diff);
1539   } else {
1540     gint64 diff_s G_GNUC_UNUSED;
1541
1542     /* calculate sample diff in seconds for error message */
1543     diff_s = gst_util_uint64_scale_int (sample_diff, GST_SECOND, rate);
1544
1545     /* timestamps drifted apart from previous samples too much, we need to
1546      * resync. We log this as an element warning. */
1547     GST_WARNING_OBJECT (sink,
1548         "Unexpected discontinuity in audio timestamps of "
1549         "%s%" GST_TIME_FORMAT ", resyncing",
1550         sample_offset > sink->next_sample ? "+" : "-", GST_TIME_ARGS (diff_s));
1551     align = 0;
1552   }
1553
1554   return align;
1555 }
1556
1557 static GstFlowReturn
1558 gst_audio_base_sink_render (GstBaseSink * bsink, GstBuffer * buf)
1559 {
1560   guint64 in_offset;
1561   GstClockTime time, stop, render_start, render_stop, sample_offset;
1562   GstClockTimeDiff sync_offset, ts_offset;
1563   GstAudioBaseSinkClass *bclass;
1564   GstAudioBaseSink *sink;
1565   GstAudioRingBuffer *ringbuf;
1566   gint64 diff, align;
1567   guint64 ctime, cstop;
1568   gsize offset;
1569   guint8 *data;
1570   gsize size;
1571   guint samples, written;
1572   gint bpf, rate;
1573   gint accum;
1574   gint out_samples;
1575   GstClockTime base_time, render_delay, latency;
1576   GstClock *clock;
1577   gboolean sync, slaved, align_next;
1578   GstFlowReturn ret;
1579   GstSegment clip_seg;
1580   gint64 time_offset;
1581   GstBuffer *out = NULL;
1582
1583   sink = GST_AUDIO_BASE_SINK (bsink);
1584   bclass = GST_AUDIO_BASE_SINK_GET_CLASS (sink);
1585
1586   ringbuf = sink->ringbuffer;
1587
1588   /* can't do anything when we don't have the device */
1589   if (G_UNLIKELY (!gst_audio_ring_buffer_is_acquired (ringbuf)))
1590     goto wrong_state;
1591
1592   /* Wait for upstream latency before starting the ringbuffer, we do this so
1593    * that we can align the first sample of the ringbuffer to the base_time +
1594    * latency. */
1595   GST_OBJECT_LOCK (sink);
1596   base_time = GST_ELEMENT_CAST (sink)->base_time;
1597   if (G_UNLIKELY (sink->priv->sync_latency)) {
1598     ret = gst_audio_base_sink_sync_latency (bsink, GST_MINI_OBJECT_CAST (buf));
1599     GST_OBJECT_UNLOCK (sink);
1600     if (G_UNLIKELY (ret != GST_FLOW_OK))
1601       goto sync_latency_failed;
1602     /* only do this once until we are set back to PLAYING */
1603     sink->priv->sync_latency = FALSE;
1604   } else {
1605     GST_OBJECT_UNLOCK (sink);
1606   }
1607
1608   /* Before we go on, let's see if we need to payload the data. If yes, we also
1609    * need to unref the output buffer before leaving. */
1610   if (bclass->payload) {
1611     out = bclass->payload (sink, buf);
1612
1613     if (!out)
1614       goto payload_failed;
1615
1616     buf = out;
1617   }
1618
1619   bpf = GST_AUDIO_INFO_BPF (&ringbuf->spec.info);
1620   rate = GST_AUDIO_INFO_RATE (&ringbuf->spec.info);
1621
1622   size = gst_buffer_get_size (buf);
1623   if (G_UNLIKELY (size % bpf) != 0)
1624     goto wrong_size;
1625
1626   samples = size / bpf;
1627   out_samples = samples;
1628
1629   in_offset = GST_BUFFER_OFFSET (buf);
1630   time = GST_BUFFER_TIMESTAMP (buf);
1631
1632   GST_DEBUG_OBJECT (sink,
1633       "time %" GST_TIME_FORMAT ", offset %" G_GUINT64_FORMAT ", start %"
1634       GST_TIME_FORMAT ", samples %u", GST_TIME_ARGS (time), in_offset,
1635       GST_TIME_ARGS (bsink->segment.start), samples);
1636
1637   offset = 0;
1638
1639   /* if not valid timestamp or we can't clip or sync, try to play
1640    * sample ASAP */
1641   if (!GST_CLOCK_TIME_IS_VALID (time)) {
1642     render_start = gst_audio_base_sink_get_offset (sink);
1643     render_stop = render_start + samples;
1644     GST_DEBUG_OBJECT (sink, "Buffer of size %" G_GSIZE_FORMAT " has no time."
1645         " Using render_start=%" G_GUINT64_FORMAT, size, render_start);
1646     /* we don't have a start so we don't know stop either */
1647     stop = -1;
1648     goto no_sync;
1649   }
1650
1651   /* let's calc stop based on the number of samples in the buffer instead
1652    * of trusting the DURATION */
1653   stop = time + gst_util_uint64_scale_int (samples, GST_SECOND, rate);
1654
1655   /* prepare the clipping segment. Since we will be subtracting ts-offset and
1656    * device-delay later we scale the start and stop with those values so that we
1657    * can correctly clip them */
1658   clip_seg.format = GST_FORMAT_TIME;
1659   clip_seg.start = bsink->segment.start;
1660   clip_seg.stop = bsink->segment.stop;
1661   clip_seg.duration = -1;
1662
1663   /* the sync offset is the combination of ts-offset and device-delay */
1664   latency = gst_base_sink_get_latency (bsink);
1665   ts_offset = gst_base_sink_get_ts_offset (bsink);
1666   render_delay = gst_base_sink_get_render_delay (bsink);
1667   sync_offset = ts_offset - render_delay + latency;
1668
1669   GST_DEBUG_OBJECT (sink,
1670       "sync-offset %" G_GINT64_FORMAT ", render-delay %" GST_TIME_FORMAT
1671       ", ts-offset %" G_GINT64_FORMAT, sync_offset,
1672       GST_TIME_ARGS (render_delay), ts_offset);
1673
1674   /* compensate for ts-offset and device-delay when negative we need to
1675    * clip. */
1676   if (sync_offset < 0) {
1677     clip_seg.start += -sync_offset;
1678     if (clip_seg.stop != -1)
1679       clip_seg.stop += -sync_offset;
1680   }
1681
1682   /* samples should be rendered based on their timestamp. All samples
1683    * arriving before the segment.start or after segment.stop are to be
1684    * thrown away. All samples should also be clipped to the segment
1685    * boundaries */
1686   if (!gst_segment_clip (&clip_seg, GST_FORMAT_TIME, time, stop, &ctime,
1687           &cstop))
1688     goto out_of_segment;
1689
1690   /* see if some clipping happened */
1691   diff = ctime - time;
1692   if (diff > 0) {
1693     /* bring clipped time to samples */
1694     diff = gst_util_uint64_scale_int (diff, rate, GST_SECOND);
1695     GST_DEBUG_OBJECT (sink, "clipping start to %" GST_TIME_FORMAT " %"
1696         G_GUINT64_FORMAT " samples", GST_TIME_ARGS (ctime), diff);
1697     samples -= diff;
1698     offset += diff * bpf;
1699     time = ctime;
1700   }
1701   diff = stop - cstop;
1702   if (diff > 0) {
1703     /* bring clipped time to samples */
1704     diff = gst_util_uint64_scale_int (diff, rate, GST_SECOND);
1705     GST_DEBUG_OBJECT (sink, "clipping stop to %" GST_TIME_FORMAT " %"
1706         G_GUINT64_FORMAT " samples", GST_TIME_ARGS (cstop), diff);
1707     samples -= diff;
1708     stop = cstop;
1709   }
1710
1711   /* figure out how to sync */
1712   if ((clock = GST_ELEMENT_CLOCK (bsink)))
1713     sync = bsink->sync;
1714   else
1715     sync = FALSE;
1716
1717   if (!sync) {
1718     /* no sync needed, play sample ASAP */
1719     render_start = gst_audio_base_sink_get_offset (sink);
1720     render_stop = render_start + samples;
1721     GST_DEBUG_OBJECT (sink,
1722         "no sync needed. Using render_start=%" G_GUINT64_FORMAT, render_start);
1723     goto no_sync;
1724   }
1725
1726   /* bring buffer start and stop times to running time */
1727   render_start =
1728       gst_segment_to_running_time (&bsink->segment, GST_FORMAT_TIME, time);
1729   render_stop =
1730       gst_segment_to_running_time (&bsink->segment, GST_FORMAT_TIME, stop);
1731
1732   GST_DEBUG_OBJECT (sink,
1733       "running: start %" GST_TIME_FORMAT " - stop %" GST_TIME_FORMAT,
1734       GST_TIME_ARGS (render_start), GST_TIME_ARGS (render_stop));
1735
1736   /* store the time of the last sample, we'll use this to perform sync on the
1737    * last sample when draining the buffer */
1738   if (bsink->segment.rate >= 0.0) {
1739     sink->priv->eos_time = render_stop;
1740   } else {
1741     sink->priv->eos_time = render_start;
1742   }
1743
1744   /* compensate for ts-offset and delay we know this will not underflow because we
1745    * clipped above. */
1746   GST_DEBUG_OBJECT (sink,
1747       "compensating for sync-offset %" GST_TIME_FORMAT,
1748       GST_TIME_ARGS (sync_offset));
1749   render_start += sync_offset;
1750   render_stop += sync_offset;
1751
1752   GST_DEBUG_OBJECT (sink, "adding base_time %" GST_TIME_FORMAT,
1753       GST_TIME_ARGS (base_time));
1754
1755   /* add base time to sync against the clock */
1756   render_start += base_time;
1757   render_stop += base_time;
1758
1759   GST_DEBUG_OBJECT (sink,
1760       "after compensation: start %" GST_TIME_FORMAT " - stop %" GST_TIME_FORMAT,
1761       GST_TIME_ARGS (render_start), GST_TIME_ARGS (render_stop));
1762
1763   if ((slaved = clock != sink->provided_clock)) {
1764     /* handle clock slaving */
1765     gst_audio_base_sink_handle_slaving (sink, render_start, render_stop,
1766         &render_start, &render_stop);
1767   } else {
1768     /* no slaving needed but we need to adapt to the clock calibration
1769      * parameters */
1770     gst_audio_base_sink_none_slaving (sink, render_start, render_stop,
1771         &render_start, &render_stop);
1772   }
1773
1774   GST_DEBUG_OBJECT (sink,
1775       "final timestamps: start %" GST_TIME_FORMAT " - stop %" GST_TIME_FORMAT,
1776       GST_TIME_ARGS (render_start), GST_TIME_ARGS (render_stop));
1777
1778   /* bring to position in the ringbuffer */
1779   time_offset = GST_AUDIO_CLOCK_CAST (sink->provided_clock)->time_offset;
1780   GST_DEBUG_OBJECT (sink,
1781       "time offset %" GST_TIME_FORMAT, GST_TIME_ARGS (time_offset));
1782   if (render_start > time_offset)
1783     render_start -= time_offset;
1784   else
1785     render_start = 0;
1786   if (render_stop > time_offset)
1787     render_stop -= time_offset;
1788   else
1789     render_stop = 0;
1790
1791   /* in some clock slaving cases, all late samples end up at 0 first,
1792    * and subsequent ones align with that until threshold exceeded,
1793    * and then sync back to 0 and so on, so avoid that altogether */
1794   if (G_UNLIKELY (render_start == 0 && render_stop == 0))
1795     goto too_late;
1796
1797   /* and bring the time to the rate corrected offset in the buffer */
1798   render_start = gst_util_uint64_scale_int (render_start, rate, GST_SECOND);
1799   render_stop = gst_util_uint64_scale_int (render_stop, rate, GST_SECOND);
1800
1801   /* positive playback rate, first sample is render_start, negative rate, first
1802    * sample is render_stop. When no rate conversion is active, render exactly
1803    * the amount of input samples to avoid aligning to rounding errors. */
1804   if (bsink->segment.rate >= 0.0) {
1805     sample_offset = render_start;
1806     if (bsink->segment.rate == 1.0)
1807       render_stop = sample_offset + samples;
1808   } else {
1809     sample_offset = render_stop;
1810     if (bsink->segment.rate == -1.0)
1811       render_start = sample_offset + samples;
1812   }
1813
1814   /* always resync after a discont */
1815   if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) {
1816     GST_DEBUG_OBJECT (sink, "resync after discont");
1817     goto no_align;
1818   }
1819
1820   /* resync when we don't know what to align the sample with */
1821   if (G_UNLIKELY (sink->next_sample == -1)) {
1822     GST_DEBUG_OBJECT (sink,
1823         "no align possible: no previous sample position known");
1824     goto no_align;
1825   }
1826
1827   align = gst_audio_base_sink_get_alignment (sink, sample_offset);
1828   sink->priv->last_align = align;
1829
1830   /* apply alignment */
1831   render_start += align;
1832
1833   /* only align stop if we are not slaved to resample */
1834   if (slaved && sink->priv->slave_method == GST_AUDIO_BASE_SINK_SLAVE_RESAMPLE) {
1835     GST_DEBUG_OBJECT (sink, "no stop time align needed: we are slaved");
1836     goto no_align;
1837   }
1838   render_stop += align;
1839
1840 no_align:
1841   /* number of target samples is difference between start and stop */
1842   out_samples = render_stop - render_start;
1843
1844 no_sync:
1845   /* we render the first or last sample first, depending on the rate */
1846   if (bsink->segment.rate >= 0.0)
1847     sample_offset = render_start;
1848   else
1849     sample_offset = render_stop;
1850
1851   GST_DEBUG_OBJECT (sink, "rendering at %" G_GUINT64_FORMAT " %d/%d",
1852       sample_offset, samples, out_samples);
1853
1854   /* we need to accumulate over different runs for when we get interrupted */
1855   accum = 0;
1856   align_next = TRUE;
1857   data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
1858   do {
1859     written =
1860         gst_audio_ring_buffer_commit (ringbuf, &sample_offset,
1861         data + offset, samples, out_samples, &accum);
1862
1863     GST_DEBUG_OBJECT (sink, "wrote %u of %u", written, samples);
1864     /* if we wrote all, we're done */
1865     if (written == samples)
1866       break;
1867
1868     /* else something interrupted us and we wait for preroll. */
1869     if ((ret = gst_base_sink_wait_preroll (bsink)) != GST_FLOW_OK)
1870       goto stopping;
1871
1872     /* if we got interrupted, we cannot assume that the next sample should
1873      * be aligned to this one */
1874     align_next = FALSE;
1875
1876     /* update the output samples. FIXME, this will just skip them when pausing
1877      * during trick mode */
1878     if (out_samples > written) {
1879       out_samples -= written;
1880       accum = 0;
1881     } else
1882       break;
1883
1884     samples -= written;
1885     offset += written * bpf;
1886   } while (TRUE);
1887   gst_buffer_unmap (buf, data, size);
1888
1889   if (align_next)
1890     sink->next_sample = sample_offset;
1891   else
1892     sink->next_sample = -1;
1893
1894   GST_DEBUG_OBJECT (sink, "next sample expected at %" G_GUINT64_FORMAT,
1895       sink->next_sample);
1896
1897   if (GST_CLOCK_TIME_IS_VALID (stop) && stop >= bsink->segment.stop) {
1898     GST_DEBUG_OBJECT (sink,
1899         "start playback because we are at the end of segment");
1900     gst_audio_ring_buffer_start (ringbuf);
1901   }
1902
1903   ret = GST_FLOW_OK;
1904
1905 done:
1906   if (out)
1907     gst_buffer_unref (out);
1908
1909   return ret;
1910
1911   /* SPECIAL cases */
1912 out_of_segment:
1913   {
1914     GST_DEBUG_OBJECT (sink,
1915         "dropping sample out of segment time %" GST_TIME_FORMAT ", start %"
1916         GST_TIME_FORMAT, GST_TIME_ARGS (time),
1917         GST_TIME_ARGS (bsink->segment.start));
1918     ret = GST_FLOW_OK;
1919     goto done;
1920   }
1921 too_late:
1922   {
1923     GST_DEBUG_OBJECT (sink, "dropping late sample");
1924     return GST_FLOW_OK;
1925   }
1926   /* ERRORS */
1927 payload_failed:
1928   {
1929     GST_ELEMENT_ERROR (sink, STREAM, FORMAT, (NULL), ("failed to payload."));
1930     ret = GST_FLOW_ERROR;
1931     goto done;
1932   }
1933 wrong_state:
1934   {
1935     GST_DEBUG_OBJECT (sink, "ringbuffer not negotiated");
1936     GST_ELEMENT_ERROR (sink, STREAM, FORMAT, (NULL), ("sink not negotiated."));
1937     ret = GST_FLOW_NOT_NEGOTIATED;
1938     goto done;
1939   }
1940 wrong_size:
1941   {
1942     GST_DEBUG_OBJECT (sink, "wrong size");
1943     GST_ELEMENT_ERROR (sink, STREAM, WRONG_TYPE,
1944         (NULL), ("sink received buffer of wrong size."));
1945     ret = GST_FLOW_ERROR;
1946     goto done;
1947   }
1948 stopping:
1949   {
1950     GST_DEBUG_OBJECT (sink, "preroll got interrupted: %d (%s)", ret,
1951         gst_flow_get_name (ret));
1952     gst_buffer_unmap (buf, data, size);
1953     goto done;
1954   }
1955 sync_latency_failed:
1956   {
1957     GST_DEBUG_OBJECT (sink, "failed waiting for latency");
1958     goto done;
1959   }
1960 }
1961
1962 /**
1963  * gst_audio_base_sink_create_ringbuffer:
1964  * @sink: a #GstAudioBaseSink.
1965  *
1966  * Create and return the #GstAudioRingBuffer for @sink. This function will call the
1967  * ::create_ringbuffer vmethod and will set @sink as the parent of the returned
1968  * buffer (see gst_object_set_parent()).
1969  *
1970  * Returns: The new ringbuffer of @sink.
1971  */
1972 GstAudioRingBuffer *
1973 gst_audio_base_sink_create_ringbuffer (GstAudioBaseSink * sink)
1974 {
1975   GstAudioBaseSinkClass *bclass;
1976   GstAudioRingBuffer *buffer = NULL;
1977
1978   bclass = GST_AUDIO_BASE_SINK_GET_CLASS (sink);
1979   if (bclass->create_ringbuffer)
1980     buffer = bclass->create_ringbuffer (sink);
1981
1982   if (buffer)
1983     gst_object_set_parent (GST_OBJECT (buffer), GST_OBJECT (sink));
1984
1985   return buffer;
1986 }
1987
1988 static void
1989 gst_audio_base_sink_callback (GstAudioRingBuffer * rbuf, guint8 * data,
1990     guint len, gpointer user_data)
1991 {
1992   GstBaseSink *basesink;
1993   GstAudioBaseSink *sink;
1994   GstBuffer *buf;
1995   GstFlowReturn ret;
1996   gsize size;
1997
1998   basesink = GST_BASE_SINK (user_data);
1999   sink = GST_AUDIO_BASE_SINK (user_data);
2000
2001   GST_PAD_STREAM_LOCK (basesink->sinkpad);
2002
2003   /* would be nice to arrange for pad_alloc_buffer to return data -- as it is we
2004      will copy twice, once into data, once into DMA */
2005   GST_LOG_OBJECT (basesink, "pulling %u bytes offset %" G_GUINT64_FORMAT
2006       " to fill audio buffer", len, basesink->offset);
2007   ret =
2008       gst_pad_pull_range (basesink->sinkpad, basesink->segment.position, len,
2009       &buf);
2010
2011   if (ret != GST_FLOW_OK) {
2012     if (ret == GST_FLOW_EOS)
2013       goto eos;
2014     else
2015       goto error;
2016   }
2017
2018   GST_BASE_SINK_PREROLL_LOCK (basesink);
2019   if (basesink->flushing)
2020     goto flushing;
2021
2022   /* complete preroll and wait for PLAYING */
2023   ret = gst_base_sink_do_preroll (basesink, GST_MINI_OBJECT_CAST (buf));
2024   if (ret != GST_FLOW_OK)
2025     goto preroll_error;
2026
2027   size = gst_buffer_get_size (buf);
2028
2029   if (len != size) {
2030     GST_INFO_OBJECT (basesink,
2031         "got different size than requested from sink pad: %u"
2032         " != %" G_GSIZE_FORMAT, len, size);
2033     len = MIN (size, len);
2034   }
2035
2036   basesink->segment.position += len;
2037
2038   gst_buffer_extract (buf, 0, data, len);
2039   GST_BASE_SINK_PREROLL_UNLOCK (basesink);
2040
2041   GST_PAD_STREAM_UNLOCK (basesink->sinkpad);
2042
2043   return;
2044
2045 error:
2046   {
2047     GST_WARNING_OBJECT (basesink, "Got flow '%s' but can't return it: %d",
2048         gst_flow_get_name (ret), ret);
2049     gst_audio_ring_buffer_pause (rbuf);
2050     GST_PAD_STREAM_UNLOCK (basesink->sinkpad);
2051     return;
2052   }
2053 eos:
2054   {
2055     /* FIXME: this is not quite correct; we'll be called endlessly until
2056      * the sink gets shut down; maybe we should set a flag somewhere, or
2057      * set segment.stop and segment.duration to the last sample or so */
2058     GST_DEBUG_OBJECT (sink, "EOS");
2059     gst_audio_base_sink_drain (sink);
2060     gst_audio_ring_buffer_pause (rbuf);
2061     gst_element_post_message (GST_ELEMENT_CAST (sink),
2062         gst_message_new_eos (GST_OBJECT_CAST (sink)));
2063     GST_PAD_STREAM_UNLOCK (basesink->sinkpad);
2064   }
2065 flushing:
2066   {
2067     GST_DEBUG_OBJECT (sink, "we are flushing");
2068     gst_audio_ring_buffer_pause (rbuf);
2069     GST_BASE_SINK_PREROLL_UNLOCK (basesink);
2070     GST_PAD_STREAM_UNLOCK (basesink->sinkpad);
2071     return;
2072   }
2073 preroll_error:
2074   {
2075     GST_DEBUG_OBJECT (sink, "error %s", gst_flow_get_name (ret));
2076     gst_audio_ring_buffer_pause (rbuf);
2077     GST_BASE_SINK_PREROLL_UNLOCK (basesink);
2078     GST_PAD_STREAM_UNLOCK (basesink->sinkpad);
2079     return;
2080   }
2081 }
2082
2083 static gboolean
2084 gst_audio_base_sink_activate_pull (GstBaseSink * basesink, gboolean active)
2085 {
2086   gboolean ret;
2087   GstAudioBaseSink *sink = GST_AUDIO_BASE_SINK (basesink);
2088
2089   if (active) {
2090     GST_DEBUG_OBJECT (basesink, "activating pull");
2091
2092     gst_audio_ring_buffer_set_callback (sink->ringbuffer,
2093         gst_audio_base_sink_callback, sink);
2094
2095     ret = gst_audio_ring_buffer_activate (sink->ringbuffer, TRUE);
2096   } else {
2097     GST_DEBUG_OBJECT (basesink, "deactivating pull");
2098     gst_audio_ring_buffer_set_callback (sink->ringbuffer, NULL, NULL);
2099     ret = gst_audio_ring_buffer_activate (sink->ringbuffer, FALSE);
2100   }
2101
2102   return ret;
2103 }
2104
2105 #if 0
2106 /* should be called with the LOCK */
2107 static GstStateChangeReturn
2108 gst_audio_base_sink_async_play (GstBaseSink * basesink)
2109 {
2110   GstAudioBaseSink *sink;
2111
2112   sink = GST_AUDIO_BASE_SINK (basesink);
2113
2114   GST_DEBUG_OBJECT (sink, "ringbuffer may start now");
2115   sink->priv->sync_latency = TRUE;
2116   gst_audio_ring_buffer_may_start (sink->ringbuffer, TRUE);
2117   if (basesink->pad_mode == GST_PAD_MODE_PULL) {
2118     /* we always start the ringbuffer in pull mode immediatly */
2119     gst_audio_ring_buffer_start (sink->ringbuffer);
2120   }
2121
2122   return GST_STATE_CHANGE_SUCCESS;
2123 }
2124 #endif
2125
2126 static GstStateChangeReturn
2127 gst_audio_base_sink_change_state (GstElement * element,
2128     GstStateChange transition)
2129 {
2130   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2131   GstAudioBaseSink *sink = GST_AUDIO_BASE_SINK (element);
2132
2133   switch (transition) {
2134     case GST_STATE_CHANGE_NULL_TO_READY:
2135       if (sink->ringbuffer == NULL) {
2136         gst_audio_clock_reset (GST_AUDIO_CLOCK (sink->provided_clock), 0);
2137         sink->ringbuffer = gst_audio_base_sink_create_ringbuffer (sink);
2138       }
2139       if (!gst_audio_ring_buffer_open_device (sink->ringbuffer))
2140         goto open_failed;
2141       break;
2142     case GST_STATE_CHANGE_READY_TO_PAUSED:
2143       sink->next_sample = -1;
2144       sink->priv->last_align = -1;
2145       sink->priv->eos_time = -1;
2146       sink->priv->discont_time = -1;
2147       gst_audio_ring_buffer_set_flushing (sink->ringbuffer, FALSE);
2148       gst_audio_ring_buffer_may_start (sink->ringbuffer, FALSE);
2149
2150       /* Only post clock-provide messages if this is the clock that
2151        * we've created. If the subclass has overriden it the subclass
2152        * should post this messages whenever necessary */
2153       if (sink->provided_clock && GST_IS_AUDIO_CLOCK (sink->provided_clock) &&
2154           GST_AUDIO_CLOCK_CAST (sink->provided_clock)->func ==
2155           (GstAudioClockGetTimeFunc) gst_audio_base_sink_get_time)
2156         gst_element_post_message (element,
2157             gst_message_new_clock_provide (GST_OBJECT_CAST (element),
2158                 sink->provided_clock, TRUE));
2159       break;
2160     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
2161     {
2162       gboolean eos;
2163
2164       GST_OBJECT_LOCK (sink);
2165       GST_DEBUG_OBJECT (sink, "ringbuffer may start now");
2166       sink->priv->sync_latency = TRUE;
2167       eos = GST_BASE_SINK (sink)->eos;
2168       GST_OBJECT_UNLOCK (sink);
2169
2170       gst_audio_ring_buffer_may_start (sink->ringbuffer, TRUE);
2171       if (GST_BASE_SINK_CAST (sink)->pad_mode == GST_PAD_MODE_PULL ||
2172           g_atomic_int_get (&sink->eos_rendering) || eos) {
2173         /* we always start the ringbuffer in pull mode immediatly */
2174         /* sync rendering on eos needs running clock,
2175          * and others need running clock when finished rendering eos */
2176         gst_audio_ring_buffer_start (sink->ringbuffer);
2177       }
2178       break;
2179     }
2180     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2181       /* ringbuffer cannot start anymore */
2182       gst_audio_ring_buffer_may_start (sink->ringbuffer, FALSE);
2183       gst_audio_ring_buffer_pause (sink->ringbuffer);
2184
2185       GST_OBJECT_LOCK (sink);
2186       sink->priv->sync_latency = FALSE;
2187       GST_OBJECT_UNLOCK (sink);
2188       break;
2189     case GST_STATE_CHANGE_PAUSED_TO_READY:
2190       /* Only post clock-lost messages if this is the clock that
2191        * we've created. If the subclass has overriden it the subclass
2192        * should post this messages whenever necessary */
2193       if (sink->provided_clock && GST_IS_AUDIO_CLOCK (sink->provided_clock) &&
2194           GST_AUDIO_CLOCK_CAST (sink->provided_clock)->func ==
2195           (GstAudioClockGetTimeFunc) gst_audio_base_sink_get_time)
2196         gst_element_post_message (element,
2197             gst_message_new_clock_lost (GST_OBJECT_CAST (element),
2198                 sink->provided_clock));
2199
2200       /* make sure we unblock before calling the parent state change
2201        * so it can grab the STREAM_LOCK */
2202       gst_audio_ring_buffer_set_flushing (sink->ringbuffer, TRUE);
2203       break;
2204     default:
2205       break;
2206   }
2207
2208   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2209
2210   switch (transition) {
2211     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2212       /* stop slaving ourselves to the master, if any */
2213       gst_clock_set_master (sink->provided_clock, NULL);
2214       break;
2215     case GST_STATE_CHANGE_PAUSED_TO_READY:
2216       gst_audio_ring_buffer_activate (sink->ringbuffer, FALSE);
2217       gst_audio_ring_buffer_release (sink->ringbuffer);
2218       break;
2219     case GST_STATE_CHANGE_READY_TO_NULL:
2220       /* we release again here because the aqcuire happens when setting the
2221        * caps, which happens before we commit the state to PAUSED and thus the
2222        * PAUSED->READY state change (see above, where we release the ringbuffer)
2223        * might not be called when we get here. */
2224       gst_audio_ring_buffer_activate (sink->ringbuffer, FALSE);
2225       gst_audio_ring_buffer_release (sink->ringbuffer);
2226       gst_audio_ring_buffer_close_device (sink->ringbuffer);
2227       GST_OBJECT_LOCK (sink);
2228       gst_object_unparent (GST_OBJECT_CAST (sink->ringbuffer));
2229       sink->ringbuffer = NULL;
2230       GST_OBJECT_UNLOCK (sink);
2231       break;
2232     default:
2233       break;
2234   }
2235
2236   return ret;
2237
2238   /* ERRORS */
2239 open_failed:
2240   {
2241     /* subclass must post a meaningful error message */
2242     GST_DEBUG_OBJECT (sink, "open failed");
2243     return GST_STATE_CHANGE_FAILURE;
2244   }
2245 }