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