1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2005 Wim Taymans <wim@fluendo.com>
4  *
5  * gstaudiobasesrc.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., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 /**
24  * SECTION:gstaudiobasesrc
25  * @title: GstAudioBaseSrc
26  * @short_description: Base class for audio sources
27  * @see_also: #GstAudioSrc, #GstAudioRingBuffer.
28  *
29  * This is the base class for audio sources. Subclasses need to implement the
30  * ::create_ringbuffer vmethod. This base class will then take care of
31  * reading samples from the ringbuffer, synchronisation and flushing.
32  */
33 
34 #ifdef HAVE_CONFIG_H
35 #  include "config.h"
36 #endif
37 
38 #include <string.h>
39 
40 #include <gst/audio/audio.h>
41 #include "gstaudiobasesrc.h"
42 
43 #include "gst/gst-i18n-plugin.h"
44 
45 GST_DEBUG_CATEGORY_STATIC (gst_audio_base_src_debug);
46 #define GST_CAT_DEFAULT gst_audio_base_src_debug
47 
48 struct _GstAudioBaseSrcPrivate
49 {
50   /* the clock slaving algorithm in use */
51   GstAudioBaseSrcSlaveMethod slave_method;
52 };
53 
54 /* BaseAudioSrc signals and args */
55 enum
56 {
57   /* FILL ME */
58   LAST_SIGNAL
59 };
60 
61 /* FIXME: 2.0, handle BUFFER_TIME and LATENCY in nanoseconds */
62 #define DEFAULT_BUFFER_TIME     ((200 * GST_MSECOND) / GST_USECOND)
63 #define DEFAULT_LATENCY_TIME    ((10 * GST_MSECOND) / GST_USECOND)
64 #define DEFAULT_ACTUAL_BUFFER_TIME     -1
65 #define DEFAULT_ACTUAL_LATENCY_TIME    -1
66 #define DEFAULT_PROVIDE_CLOCK   TRUE
67 #define DEFAULT_SLAVE_METHOD    GST_AUDIO_BASE_SRC_SLAVE_SKEW
68 
69 enum
70 {
71   PROP_0,
72   PROP_BUFFER_TIME,
73   PROP_LATENCY_TIME,
74   PROP_ACTUAL_BUFFER_TIME,
75   PROP_ACTUAL_LATENCY_TIME,
76   PROP_PROVIDE_CLOCK,
77   PROP_SLAVE_METHOD,
78   PROP_LAST
79 };
80 
81 static void
_do_init(GType type)82 _do_init (GType type)
83 {
84   GST_DEBUG_CATEGORY_INIT (gst_audio_base_src_debug, "audiobasesrc", 0,
85       "audiobasesrc element");
86 
87 #ifdef ENABLE_NLS
88   GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
89       LOCALEDIR);
90   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
91   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
92 #endif /* ENABLE_NLS */
93 }
94 
95 #define gst_audio_base_src_parent_class parent_class
96 G_DEFINE_TYPE_WITH_CODE (GstAudioBaseSrc, gst_audio_base_src, GST_TYPE_PUSH_SRC,
97     G_ADD_PRIVATE (GstAudioBaseSrc)
98     _do_init (g_define_type_id));
99 
100 static void gst_audio_base_src_set_property (GObject * object, guint prop_id,
101     const GValue * value, GParamSpec * pspec);
102 static void gst_audio_base_src_get_property (GObject * object, guint prop_id,
103     GValue * value, GParamSpec * pspec);
104 static void gst_audio_base_src_dispose (GObject * object);
105 
106 static GstStateChangeReturn gst_audio_base_src_change_state (GstElement *
107     element, GstStateChange transition);
108 static gboolean gst_audio_base_src_post_message (GstElement * element,
109     GstMessage * message);
110 static GstClock *gst_audio_base_src_provide_clock (GstElement * elem);
111 static GstClockTime gst_audio_base_src_get_time (GstClock * clock,
112     GstAudioBaseSrc * src);
113 
114 static GstFlowReturn gst_audio_base_src_create (GstBaseSrc * bsrc,
115     guint64 offset, guint length, GstBuffer ** buf);
116 
117 static gboolean gst_audio_base_src_event (GstBaseSrc * bsrc, GstEvent * event);
118 static void gst_audio_base_src_get_times (GstBaseSrc * bsrc,
119     GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
120 static gboolean gst_audio_base_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps);
121 static gboolean gst_audio_base_src_query (GstBaseSrc * bsrc, GstQuery * query);
122 static GstCaps *gst_audio_base_src_fixate (GstBaseSrc * bsrc, GstCaps * caps);
123 
124 /* static guint gst_audio_base_src_signals[LAST_SIGNAL] = { 0 }; */
125 
126 static void
gst_audio_base_src_class_init(GstAudioBaseSrcClass * klass)127 gst_audio_base_src_class_init (GstAudioBaseSrcClass * klass)
128 {
129   GObjectClass *gobject_class;
130   GstElementClass *gstelement_class;
131   GstBaseSrcClass *gstbasesrc_class;
132 
133   gobject_class = (GObjectClass *) klass;
134   gstelement_class = (GstElementClass *) klass;
135   gstbasesrc_class = (GstBaseSrcClass *) klass;
136 
137   gobject_class->set_property = gst_audio_base_src_set_property;
138   gobject_class->get_property = gst_audio_base_src_get_property;
139   gobject_class->dispose = gst_audio_base_src_dispose;
140 
141   /* FIXME: 2.0, handle BUFFER_TIME and LATENCY in nanoseconds */
142   g_object_class_install_property (gobject_class, PROP_BUFFER_TIME,
143       g_param_spec_int64 ("buffer-time", "Buffer Time",
144           "Size of audio buffer in microseconds. This is the maximum amount "
145           "of data that is buffered in the device and the maximum latency that "
146           "the source reports. This value might be ignored by the element if "
147           "necessary; see \"actual-buffer-time\"",
148           1, G_MAXINT64, DEFAULT_BUFFER_TIME,
149           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
150 
151   g_object_class_install_property (gobject_class, PROP_LATENCY_TIME,
152       g_param_spec_int64 ("latency-time", "Latency Time",
153           "The minimum amount of data to read in each iteration in "
154           "microseconds. This is the minimum latency that the source reports. "
155           "This value might be ignored by the element if necessary; see "
156           "\"actual-latency-time\"", 1, G_MAXINT64, DEFAULT_LATENCY_TIME,
157           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
158 
159   /**
160    * GstAudioBaseSrc:actual-buffer-time:
161    *
162    * Actual configured size of audio buffer in microseconds.
163    **/
164   g_object_class_install_property (gobject_class, PROP_ACTUAL_BUFFER_TIME,
165       g_param_spec_int64 ("actual-buffer-time", "Actual Buffer Time",
166           "Actual configured size of audio buffer in microseconds",
167           DEFAULT_ACTUAL_BUFFER_TIME, G_MAXINT64, DEFAULT_ACTUAL_BUFFER_TIME,
168           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
169 
170   /**
171    * GstAudioBaseSrc:actual-latency-time:
172    *
173    * Actual configured audio latency in microseconds.
174    **/
175   g_object_class_install_property (gobject_class, PROP_ACTUAL_LATENCY_TIME,
176       g_param_spec_int64 ("actual-latency-time", "Actual Latency Time",
177           "Actual configured audio latency in microseconds",
178           DEFAULT_ACTUAL_LATENCY_TIME, G_MAXINT64, DEFAULT_ACTUAL_LATENCY_TIME,
179           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
180 
181   g_object_class_install_property (gobject_class, PROP_PROVIDE_CLOCK,
182       g_param_spec_boolean ("provide-clock", "Provide Clock",
183           "Provide a clock to be used as the global pipeline clock",
184           DEFAULT_PROVIDE_CLOCK, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
185 
186   g_object_class_install_property (gobject_class, PROP_SLAVE_METHOD,
187       g_param_spec_enum ("slave-method", "Slave Method",
188           "Algorithm used to match the rate of the masterclock",
189           GST_TYPE_AUDIO_BASE_SRC_SLAVE_METHOD, DEFAULT_SLAVE_METHOD,
190           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
191 
192   gstelement_class->change_state =
193       GST_DEBUG_FUNCPTR (gst_audio_base_src_change_state);
194   gstelement_class->provide_clock =
195       GST_DEBUG_FUNCPTR (gst_audio_base_src_provide_clock);
196   gstelement_class->post_message =
197       GST_DEBUG_FUNCPTR (gst_audio_base_src_post_message);
198 
199   gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_audio_base_src_setcaps);
200   gstbasesrc_class->event = GST_DEBUG_FUNCPTR (gst_audio_base_src_event);
201   gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_audio_base_src_query);
202   gstbasesrc_class->get_times =
203       GST_DEBUG_FUNCPTR (gst_audio_base_src_get_times);
204   gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_audio_base_src_create);
205   gstbasesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_audio_base_src_fixate);
206 
207   /* ref class from a thread-safe context to work around missing bit of
208    * thread-safety in GObject */
209   g_type_class_ref (GST_TYPE_AUDIO_CLOCK);
210   g_type_class_ref (GST_TYPE_AUDIO_RING_BUFFER);
211 }
212 
213 static void
gst_audio_base_src_init(GstAudioBaseSrc * audiobasesrc)214 gst_audio_base_src_init (GstAudioBaseSrc * audiobasesrc)
215 {
216   audiobasesrc->priv = gst_audio_base_src_get_instance_private (audiobasesrc);
217 
218   audiobasesrc->buffer_time = DEFAULT_BUFFER_TIME;
219   audiobasesrc->latency_time = DEFAULT_LATENCY_TIME;
220   if (DEFAULT_PROVIDE_CLOCK)
221     GST_OBJECT_FLAG_SET (audiobasesrc, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
222   else
223     GST_OBJECT_FLAG_UNSET (audiobasesrc, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
224   audiobasesrc->priv->slave_method = DEFAULT_SLAVE_METHOD;
225   /* reset blocksize we use latency time to calculate a more useful
226    * value based on negotiated format. */
227   GST_BASE_SRC (audiobasesrc)->blocksize = 0;
228 
229   audiobasesrc->clock = gst_audio_clock_new ("GstAudioSrcClock",
230       (GstAudioClockGetTimeFunc) gst_audio_base_src_get_time, audiobasesrc,
231       NULL);
232 
233 
234   /* we are always a live source */
235   gst_base_src_set_live (GST_BASE_SRC (audiobasesrc), TRUE);
236   /* we operate in time */
237   gst_base_src_set_format (GST_BASE_SRC (audiobasesrc), GST_FORMAT_TIME);
238 }
239 
240 static void
gst_audio_base_src_dispose(GObject * object)241 gst_audio_base_src_dispose (GObject * object)
242 {
243   GstAudioBaseSrc *src;
244 
245   src = GST_AUDIO_BASE_SRC (object);
246 
247   GST_OBJECT_LOCK (src);
248   if (src->clock) {
249     gst_audio_clock_invalidate (GST_AUDIO_CLOCK (src->clock));
250     gst_object_unref (src->clock);
251     src->clock = NULL;
252   }
253 
254   if (src->ringbuffer) {
255     gst_object_unparent (GST_OBJECT_CAST (src->ringbuffer));
256     src->ringbuffer = NULL;
257   }
258   GST_OBJECT_UNLOCK (src);
259 
260   G_OBJECT_CLASS (parent_class)->dispose (object);
261 }
262 
263 static GstClock *
gst_audio_base_src_provide_clock(GstElement * elem)264 gst_audio_base_src_provide_clock (GstElement * elem)
265 {
266   GstAudioBaseSrc *src;
267   GstClock *clock;
268 
269   src = GST_AUDIO_BASE_SRC (elem);
270 
271   /* we have no ringbuffer (must be NULL state) */
272   if (src->ringbuffer == NULL)
273     goto wrong_state;
274 
275   if (gst_audio_ring_buffer_is_flushing (src->ringbuffer))
276     goto wrong_state;
277 
278   GST_OBJECT_LOCK (src);
279 
280   if (!GST_OBJECT_FLAG_IS_SET (src, GST_ELEMENT_FLAG_PROVIDE_CLOCK))
281     goto clock_disabled;
282 
283   clock = GST_CLOCK_CAST (gst_object_ref (src->clock));
284   GST_OBJECT_UNLOCK (src);
285 
286   return clock;
287 
288   /* ERRORS */
289 wrong_state:
290   {
291     GST_DEBUG_OBJECT (src, "ringbuffer is flushing");
292     return NULL;
293   }
294 clock_disabled:
295   {
296     GST_DEBUG_OBJECT (src, "clock provide disabled");
297     GST_OBJECT_UNLOCK (src);
298     return NULL;
299   }
300 }
301 
302 static GstClockTime
gst_audio_base_src_get_time(GstClock * clock,GstAudioBaseSrc * src)303 gst_audio_base_src_get_time (GstClock * clock, GstAudioBaseSrc * src)
304 {
305   guint64 raw, samples;
306   guint delay;
307   GstClockTime result;
308 
309   if (G_UNLIKELY (src->ringbuffer == NULL
310           || src->ringbuffer->spec.info.rate == 0))
311     return GST_CLOCK_TIME_NONE;
312 
313   raw = samples = gst_audio_ring_buffer_samples_done (src->ringbuffer);
314 
315   /* the number of samples not yet processed, this is still queued in the
316    * device (not yet read for capture). */
317   delay = gst_audio_ring_buffer_delay (src->ringbuffer);
318 
319   samples += delay;
320 
321   result = gst_util_uint64_scale_int (samples, GST_SECOND,
322       src->ringbuffer->spec.info.rate);
323 
324   GST_DEBUG_OBJECT (src,
325       "processed samples: raw %" G_GUINT64_FORMAT ", delay %u, real %"
326       G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT, raw, delay, samples,
327       GST_TIME_ARGS (result));
328 
329   return result;
330 }
331 
332 /**
333  * gst_audio_base_src_set_provide_clock:
334  * @src: a #GstAudioBaseSrc
335  * @provide: new state
336  *
337  * Controls whether @src will provide a clock or not. If @provide is %TRUE,
338  * gst_element_provide_clock() will return a clock that reflects the datarate
339  * of @src. If @provide is %FALSE, gst_element_provide_clock() will return NULL.
340  */
341 void
gst_audio_base_src_set_provide_clock(GstAudioBaseSrc * src,gboolean provide)342 gst_audio_base_src_set_provide_clock (GstAudioBaseSrc * src, gboolean provide)
343 {
344   g_return_if_fail (GST_IS_AUDIO_BASE_SRC (src));
345 
346   GST_OBJECT_LOCK (src);
347   if (provide)
348     GST_OBJECT_FLAG_SET (src, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
349   else
350     GST_OBJECT_FLAG_UNSET (src, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
351   GST_OBJECT_UNLOCK (src);
352 }
353 
354 /**
355  * gst_audio_base_src_get_provide_clock:
356  * @src: a #GstAudioBaseSrc
357  *
358  * Queries whether @src will provide a clock or not. See also
359  * gst_audio_base_src_set_provide_clock.
360  *
361  * Returns: %TRUE if @src will provide a clock.
362  */
363 gboolean
gst_audio_base_src_get_provide_clock(GstAudioBaseSrc * src)364 gst_audio_base_src_get_provide_clock (GstAudioBaseSrc * src)
365 {
366   gboolean result;
367 
368   g_return_val_if_fail (GST_IS_AUDIO_BASE_SRC (src), FALSE);
369 
370   GST_OBJECT_LOCK (src);
371   result = GST_OBJECT_FLAG_IS_SET (src, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
372   GST_OBJECT_UNLOCK (src);
373 
374   return result;
375 }
376 
377 /**
378  * gst_audio_base_src_set_slave_method:
379  * @src: a #GstAudioBaseSrc
380  * @method: the new slave method
381  *
382  * Controls how clock slaving will be performed in @src.
383  */
384 void
gst_audio_base_src_set_slave_method(GstAudioBaseSrc * src,GstAudioBaseSrcSlaveMethod method)385 gst_audio_base_src_set_slave_method (GstAudioBaseSrc * src,
386     GstAudioBaseSrcSlaveMethod method)
387 {
388   g_return_if_fail (GST_IS_AUDIO_BASE_SRC (src));
389 
390   GST_OBJECT_LOCK (src);
391   src->priv->slave_method = method;
392   GST_OBJECT_UNLOCK (src);
393 }
394 
395 /**
396  * gst_audio_base_src_get_slave_method:
397  * @src: a #GstAudioBaseSrc
398  *
399  * Get the current slave method used by @src.
400  *
401  * Returns: The current slave method used by @src.
402  */
403 GstAudioBaseSrcSlaveMethod
gst_audio_base_src_get_slave_method(GstAudioBaseSrc * src)404 gst_audio_base_src_get_slave_method (GstAudioBaseSrc * src)
405 {
406   GstAudioBaseSrcSlaveMethod result;
407 
408   g_return_val_if_fail (GST_IS_AUDIO_BASE_SRC (src), -1);
409 
410   GST_OBJECT_LOCK (src);
411   result = src->priv->slave_method;
412   GST_OBJECT_UNLOCK (src);
413 
414   return result;
415 }
416 
417 static void
gst_audio_base_src_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)418 gst_audio_base_src_set_property (GObject * object, guint prop_id,
419     const GValue * value, GParamSpec * pspec)
420 {
421   GstAudioBaseSrc *src;
422 
423   src = GST_AUDIO_BASE_SRC (object);
424 
425   switch (prop_id) {
426     case PROP_BUFFER_TIME:
427       src->buffer_time = g_value_get_int64 (value);
428       break;
429     case PROP_LATENCY_TIME:
430       src->latency_time = g_value_get_int64 (value);
431       break;
432     case PROP_PROVIDE_CLOCK:
433       gst_audio_base_src_set_provide_clock (src, g_value_get_boolean (value));
434       break;
435     case PROP_SLAVE_METHOD:
436       gst_audio_base_src_set_slave_method (src, g_value_get_enum (value));
437       break;
438     default:
439       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
440       break;
441   }
442 }
443 
444 static void
gst_audio_base_src_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)445 gst_audio_base_src_get_property (GObject * object, guint prop_id,
446     GValue * value, GParamSpec * pspec)
447 {
448   GstAudioBaseSrc *src;
449 
450   src = GST_AUDIO_BASE_SRC (object);
451 
452   switch (prop_id) {
453     case PROP_BUFFER_TIME:
454       g_value_set_int64 (value, src->buffer_time);
455       break;
456     case PROP_LATENCY_TIME:
457       g_value_set_int64 (value, src->latency_time);
458       break;
459     case PROP_ACTUAL_BUFFER_TIME:
460       GST_OBJECT_LOCK (src);
461       if (src->ringbuffer && src->ringbuffer->acquired)
462         g_value_set_int64 (value, src->ringbuffer->spec.buffer_time);
463       else
464         g_value_set_int64 (value, DEFAULT_ACTUAL_BUFFER_TIME);
465       GST_OBJECT_UNLOCK (src);
466       break;
467     case PROP_ACTUAL_LATENCY_TIME:
468       GST_OBJECT_LOCK (src);
469       if (src->ringbuffer && src->ringbuffer->acquired)
470         g_value_set_int64 (value, src->ringbuffer->spec.latency_time);
471       else
472         g_value_set_int64 (value, DEFAULT_ACTUAL_LATENCY_TIME);
473       GST_OBJECT_UNLOCK (src);
474       break;
475     case PROP_PROVIDE_CLOCK:
476       g_value_set_boolean (value, gst_audio_base_src_get_provide_clock (src));
477       break;
478     case PROP_SLAVE_METHOD:
479       g_value_set_enum (value, gst_audio_base_src_get_slave_method (src));
480       break;
481     default:
482       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
483       break;
484   }
485 }
486 
487 static GstCaps *
gst_audio_base_src_fixate(GstBaseSrc * bsrc,GstCaps * caps)488 gst_audio_base_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
489 {
490   GstStructure *s;
491 
492   caps = gst_caps_make_writable (caps);
493 
494   s = gst_caps_get_structure (caps, 0);
495 
496   /* fields for all formats */
497   gst_structure_fixate_field_nearest_int (s, "rate", GST_AUDIO_DEF_RATE);
498   gst_structure_fixate_field_nearest_int (s, "channels",
499       GST_AUDIO_DEF_CHANNELS);
500   gst_structure_fixate_field_string (s, "format", GST_AUDIO_DEF_FORMAT);
501 
502   caps = GST_BASE_SRC_CLASS (parent_class)->fixate (bsrc, caps);
503 
504   return caps;
505 }
506 
507 static gboolean
gst_audio_base_src_setcaps(GstBaseSrc * bsrc,GstCaps * caps)508 gst_audio_base_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
509 {
510   GstAudioBaseSrc *src = GST_AUDIO_BASE_SRC (bsrc);
511   GstAudioRingBufferSpec *spec;
512   gint bpf, rate;
513 
514   spec = &src->ringbuffer->spec;
515 
516   if (G_UNLIKELY (spec->caps && gst_caps_is_equal (spec->caps, caps))) {
517     GST_DEBUG_OBJECT (src,
518         "Ringbuffer caps haven't changed, skipping reconfiguration");
519     return TRUE;
520   }
521 
522   GST_DEBUG ("release old ringbuffer");
523   gst_audio_ring_buffer_release (src->ringbuffer);
524 
525   spec->buffer_time = src->buffer_time;
526   spec->latency_time = src->latency_time;
527 
528   GST_OBJECT_LOCK (src);
529   if (!gst_audio_ring_buffer_parse_caps (spec, caps)) {
530     GST_OBJECT_UNLOCK (src);
531     goto parse_error;
532   }
533 
534   bpf = GST_AUDIO_INFO_BPF (&spec->info);
535   rate = GST_AUDIO_INFO_RATE (&spec->info);
536 
537   /* calculate suggested segsize and segtotal */
538   spec->segsize = rate * bpf * spec->latency_time / GST_MSECOND;
539   /* Round to an integer number of samples */
540   spec->segsize -= spec->segsize % bpf;
541   spec->segtotal = spec->buffer_time / spec->latency_time;
542 
543   GST_OBJECT_UNLOCK (src);
544 
545   gst_audio_ring_buffer_debug_spec_buff (spec);
546 
547   GST_DEBUG ("acquire new ringbuffer");
548 
549   if (!gst_audio_ring_buffer_acquire (src->ringbuffer, spec))
550     goto acquire_error;
551 
552   /* calculate actual latency and buffer times */
553   spec->latency_time = spec->segsize * GST_MSECOND / (rate * bpf);
554   spec->buffer_time =
555       spec->segtotal * spec->segsize * GST_MSECOND / (rate * bpf);
556 
557   gst_audio_ring_buffer_debug_spec_buff (spec);
558 
559   g_object_notify (G_OBJECT (src), "actual-buffer-time");
560   g_object_notify (G_OBJECT (src), "actual-latency-time");
561 
562   gst_element_post_message (GST_ELEMENT_CAST (bsrc),
563       gst_message_new_latency (GST_OBJECT (bsrc)));
564 
565   return TRUE;
566 
567   /* ERRORS */
568 parse_error:
569   {
570     GST_DEBUG ("could not parse caps");
571     return FALSE;
572   }
573 acquire_error:
574   {
575     GST_DEBUG ("could not acquire ringbuffer");
576     return FALSE;
577   }
578 }
579 
580 static void
gst_audio_base_src_get_times(GstBaseSrc * bsrc,GstBuffer * buffer,GstClockTime * start,GstClockTime * end)581 gst_audio_base_src_get_times (GstBaseSrc * bsrc, GstBuffer * buffer,
582     GstClockTime * start, GstClockTime * end)
583 {
584   /* No need to sync to a clock here. We schedule the samples based
585    * on our own clock for the moment. */
586   *start = GST_CLOCK_TIME_NONE;
587   *end = GST_CLOCK_TIME_NONE;
588 }
589 
590 static gboolean
gst_audio_base_src_query(GstBaseSrc * bsrc,GstQuery * query)591 gst_audio_base_src_query (GstBaseSrc * bsrc, GstQuery * query)
592 {
593   GstAudioBaseSrc *src = GST_AUDIO_BASE_SRC (bsrc);
594   gboolean res = FALSE;
595 
596   switch (GST_QUERY_TYPE (query)) {
597     case GST_QUERY_LATENCY:
598     {
599       GstClockTime min_latency, max_latency;
600       GstAudioRingBufferSpec *spec;
601       gint bpf, rate;
602 
603       GST_OBJECT_LOCK (src);
604       if (G_UNLIKELY (src->ringbuffer == NULL
605               || src->ringbuffer->spec.info.rate == 0)) {
606         GST_OBJECT_UNLOCK (src);
607         goto done;
608       }
609 
610       spec = &src->ringbuffer->spec;
611       rate = GST_AUDIO_INFO_RATE (&spec->info);
612       bpf = GST_AUDIO_INFO_BPF (&spec->info);
613 
614       /* we have at least 1 segment of latency */
615       min_latency =
616           gst_util_uint64_scale_int (spec->segsize, GST_SECOND, rate * bpf);
617       /* we cannot delay more than the buffersize else we lose data */
618       max_latency =
619           gst_util_uint64_scale_int (spec->segtotal * spec->segsize, GST_SECOND,
620           rate * bpf);
621       GST_OBJECT_UNLOCK (src);
622 
623       GST_DEBUG_OBJECT (src,
624           "report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
625           GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
626 
627       /* we are always live, the min latency is 1 segment and the max latency is
628        * the complete buffer of segments. */
629       gst_query_set_latency (query, TRUE, min_latency, max_latency);
630 
631       res = TRUE;
632       break;
633     }
634     case GST_QUERY_SCHEDULING:
635     {
636       /* We allow limited pull base operation. Basically, pulling can be
637        * done on any number of bytes as long as the offset is -1 or
638        * sequentially increasing. */
639       gst_query_set_scheduling (query, GST_SCHEDULING_FLAG_SEQUENTIAL, 1, -1,
640           0);
641       gst_query_add_scheduling_mode (query, GST_PAD_MODE_PULL);
642       gst_query_add_scheduling_mode (query, GST_PAD_MODE_PUSH);
643 
644       res = TRUE;
645       break;
646     }
647     default:
648       res = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query);
649       break;
650   }
651 done:
652   return res;
653 }
654 
655 static gboolean
gst_audio_base_src_event(GstBaseSrc * bsrc,GstEvent * event)656 gst_audio_base_src_event (GstBaseSrc * bsrc, GstEvent * event)
657 {
658   GstAudioBaseSrc *src = GST_AUDIO_BASE_SRC (bsrc);
659   gboolean res, forward;
660 
661   res = FALSE;
662   forward = TRUE;
663 
664   switch (GST_EVENT_TYPE (event)) {
665     case GST_EVENT_FLUSH_START:
666       GST_DEBUG_OBJECT (bsrc, "flush-start");
667       gst_audio_ring_buffer_pause (src->ringbuffer);
668       gst_audio_ring_buffer_clear_all (src->ringbuffer);
669       break;
670     case GST_EVENT_FLUSH_STOP:
671       GST_DEBUG_OBJECT (bsrc, "flush-stop");
672       /* always resync on sample after a flush */
673       src->next_sample = -1;
674       gst_audio_ring_buffer_clear_all (src->ringbuffer);
675       break;
676     case GST_EVENT_SEEK:
677       GST_DEBUG_OBJECT (bsrc, "refuse to seek");
678       forward = FALSE;
679       break;
680     default:
681       GST_DEBUG_OBJECT (bsrc, "forward event %p", event);
682       break;
683   }
684   if (forward)
685     res = GST_BASE_SRC_CLASS (parent_class)->event (bsrc, event);
686 
687   return res;
688 }
689 
690 /* Get the next offset in the ringbuffer for reading samples.
691  * If the next sample is too far away, this function will position itself to the
692  * next most recent sample, creating discontinuity */
693 static guint64
gst_audio_base_src_get_offset(GstAudioBaseSrc * src)694 gst_audio_base_src_get_offset (GstAudioBaseSrc * src)
695 {
696   guint64 sample;
697   gint readseg, segdone, segtotal, sps;
698   gint diff;
699 
700   /* assume we can append to the previous sample */
701   sample = src->next_sample;
702 
703   sps = src->ringbuffer->samples_per_seg;
704   segtotal = src->ringbuffer->spec.segtotal;
705 
706   /* get the currently processed segment */
707   segdone = g_atomic_int_get (&src->ringbuffer->segdone)
708       - src->ringbuffer->segbase;
709 
710   if (sample != -1) {
711     GST_DEBUG_OBJECT (src, "at segment %d and sample %" G_GUINT64_FORMAT,
712         segdone, sample);
713     /* figure out the segment and the offset inside the segment where
714      * the sample should be read from. */
715     readseg = sample / sps;
716 
717     /* See how far away it is from the read segment. Normally, segdone (where
718      * new data is written in the ringbuffer) is bigger than readseg
719      * (where we are reading). */
720     diff = segdone - readseg;
721     if (diff >= segtotal) {
722       GST_DEBUG_OBJECT (src, "dropped, align to segment %d", segdone);
723       /* sample would be dropped, position to next playable position */
724       sample = ((guint64) (segdone)) * sps;
725     }
726   } else {
727     /* no previous sample, go to the current position */
728     GST_DEBUG_OBJECT (src, "first sample, align to current %d", segdone);
729     sample = ((guint64) (segdone)) * sps;
730     readseg = segdone;
731   }
732 
733   GST_DEBUG_OBJECT (src,
734       "reading from %d, we are at %d, sample %" G_GUINT64_FORMAT, readseg,
735       segdone, sample);
736 
737   return sample;
738 }
739 
740 static GstFlowReturn
gst_audio_base_src_create(GstBaseSrc * bsrc,guint64 offset,guint length,GstBuffer ** outbuf)741 gst_audio_base_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
742     GstBuffer ** outbuf)
743 {
744   GstFlowReturn ret;
745   GstAudioBaseSrc *src = GST_AUDIO_BASE_SRC (bsrc);
746   GstBuffer *buf;
747   GstMapInfo info;
748   guint8 *ptr;
749   guint samples, total_samples;
750   guint64 sample;
751   gint bpf, rate;
752   GstAudioRingBuffer *ringbuffer;
753   GstAudioRingBufferSpec *spec;
754   guint read;
755   GstClockTime timestamp, duration;
756   GstClockTime rb_timestamp = GST_CLOCK_TIME_NONE;
757   GstClock *clock;
758   gboolean first;
759   gboolean first_sample = src->next_sample == -1;
760 
761   ringbuffer = src->ringbuffer;
762   spec = &ringbuffer->spec;
763 
764   if (G_UNLIKELY (!gst_audio_ring_buffer_is_acquired (ringbuffer)))
765     goto wrong_state;
766 
767   bpf = GST_AUDIO_INFO_BPF (&spec->info);
768   rate = GST_AUDIO_INFO_RATE (&spec->info);
769 
770   if ((length == 0 && bsrc->blocksize == 0) || length == -1)
771     /* no length given, use the default segment size */
772     length = spec->segsize;
773   else
774     /* make sure we round down to an integral number of samples */
775     length -= length % bpf;
776 
777   /* figure out the offset in the ringbuffer */
778   if (G_UNLIKELY (offset != -1)) {
779     sample = offset / bpf;
780     /* if a specific offset was given it must be the next sequential
781      * offset we expect or we fail for now. */
782     if (src->next_sample != -1 && sample != src->next_sample)
783       goto wrong_offset;
784   } else {
785     /* Calculate the sequentially-next sample we need to read. This can jump and
786      * create a DISCONT. */
787     sample = gst_audio_base_src_get_offset (src);
788   }
789 
790   GST_DEBUG_OBJECT (src, "reading from sample %" G_GUINT64_FORMAT " length %u",
791       sample, length);
792 
793   /* get the number of samples to read */
794   total_samples = samples = length / bpf;
795 
796   /* use the basesrc allocation code to use bufferpools or custom allocators */
797   ret = GST_BASE_SRC_CLASS (parent_class)->alloc (bsrc, offset, length, &buf);
798   if (G_UNLIKELY (ret != GST_FLOW_OK))
799     goto alloc_failed;
800 
801   gst_buffer_map (buf, &info, GST_MAP_WRITE);
802   ptr = info.data;
803   first = TRUE;
804   do {
805     GstClockTime tmp_ts = GST_CLOCK_TIME_NONE;
806 
807     read =
808         gst_audio_ring_buffer_read (ringbuffer, sample, ptr, samples, &tmp_ts);
809     if (first && GST_CLOCK_TIME_IS_VALID (tmp_ts)) {
810       first = FALSE;
811       rb_timestamp = tmp_ts;
812     }
813     GST_DEBUG_OBJECT (src, "read %u of %u", read, samples);
814     /* if we read all, we're done */
815     if (read == samples)
816       break;
817 
818     if (g_atomic_int_get (&ringbuffer->state) ==
819         GST_AUDIO_RING_BUFFER_STATE_ERROR)
820       goto got_error;
821 
822     /* else something interrupted us and we wait for playing again. */
823     GST_DEBUG_OBJECT (src, "wait playing");
824     if (gst_base_src_wait_playing (bsrc) != GST_FLOW_OK)
825       goto stopped;
826 
827     GST_DEBUG_OBJECT (src, "continue playing");
828 
829     /* read next samples */
830     sample += read;
831     samples -= read;
832     ptr += read * bpf;
833   } while (TRUE);
834   gst_buffer_unmap (buf, &info);
835 
836   /* mark discontinuity if needed */
837   if (G_UNLIKELY (sample != src->next_sample) && src->next_sample != -1) {
838     GST_WARNING_OBJECT (src,
839         "create DISCONT of %" G_GUINT64_FORMAT " samples at sample %"
840         G_GUINT64_FORMAT, sample - src->next_sample, sample);
841     GST_ELEMENT_WARNING (src, CORE, CLOCK,
842         (_("Can't record audio fast enough")),
843         ("Dropped %" G_GUINT64_FORMAT " samples. This is most likely because "
844             "downstream can't keep up and is consuming samples too slowly.",
845             sample - src->next_sample));
846     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
847   }
848 
849   src->next_sample = sample + samples;
850 
851   /* get the normal timestamp to get the duration. */
852   timestamp = gst_util_uint64_scale_int (sample, GST_SECOND, rate);
853   duration = gst_util_uint64_scale_int (src->next_sample, GST_SECOND,
854       rate) - timestamp;
855 
856   GST_OBJECT_LOCK (src);
857   if (!(clock = GST_ELEMENT_CLOCK (src)))
858     goto no_sync;
859 
860   if (!GST_CLOCK_TIME_IS_VALID (rb_timestamp) && clock != src->clock) {
861     /* we are slaved, check how to handle this */
862     switch (src->priv->slave_method) {
863       case GST_AUDIO_BASE_SRC_SLAVE_RESAMPLE:
864         /* Not implemented, use skew algorithm. This algorithm should
865          * work on the readout pointer and produce more or less samples based
866          * on the clock drift */
867       case GST_AUDIO_BASE_SRC_SLAVE_SKEW:
868       {
869         GstClockTime running_time;
870         GstClockTime base_time;
871         GstClockTime current_time;
872         guint64 running_time_sample;
873         gint running_time_segment;
874         gint last_read_segment;
875         gint segment_skew;
876         gint sps;
877         gint segments_written;
878         gint last_written_segment;
879 
880         /* get the amount of segments written from the device by now */
881         segments_written = g_atomic_int_get (&ringbuffer->segdone);
882 
883         /* subtract the base to segments_written to get the number of the
884          * last written segment in the ringbuffer
885          * (one segment written = segment 0) */
886         last_written_segment = segments_written - ringbuffer->segbase - 1;
887 
888         /* samples per segment */
889         sps = ringbuffer->samples_per_seg;
890 
891         /* get the current time */
892         current_time = gst_clock_get_time (clock);
893 
894         /* get the basetime */
895         base_time = GST_ELEMENT_CAST (src)->base_time;
896 
897         /* get the running_time */
898         running_time = current_time - base_time;
899 
900         /* the running_time converted to a sample
901          * (relative to the ringbuffer) */
902         running_time_sample =
903             gst_util_uint64_scale_int (running_time, rate, GST_SECOND);
904 
905         /* the segmentnr corresponding to running_time, round down */
906         running_time_segment = running_time_sample / sps;
907 
908         /* the segment currently read from the ringbuffer */
909         last_read_segment = sample / sps;
910 
911         /* the skew we have between running_time and the ringbuffertime
912          * (last written to) */
913         segment_skew = running_time_segment - last_written_segment;
914 
915         GST_DEBUG_OBJECT (bsrc,
916             "\n running_time                                              = %"
917             GST_TIME_FORMAT
918             "\n timestamp                                                  = %"
919             GST_TIME_FORMAT
920             "\n running_time_segment                                       = %d"
921             "\n last_written_segment                                       = %d"
922             "\n segment_skew (running time segment - last_written_segment) = %d"
923             "\n last_read_segment                                          = %d",
924             GST_TIME_ARGS (running_time), GST_TIME_ARGS (timestamp),
925             running_time_segment, last_written_segment, segment_skew,
926             last_read_segment);
927 
928         /* Resync the ringbuffer if:
929          *
930          * 1. We are more than the length of the ringbuffer behind.
931          *    The length of the ringbuffer then gets to dictate
932          *    the threshold for what is considered "too late"
933          *
934          * 2. If this is our first buffer.
935          *    We know that we should catch up to running_time
936          *    the first time we are ran.
937          */
938         if ((segment_skew >= ringbuffer->spec.segtotal) ||
939             (last_read_segment == 0) || first_sample) {
940           gint new_read_segment;
941           gint segment_diff;
942           guint64 new_sample;
943 
944           /* the difference between running_time and the last written segment */
945           segment_diff = running_time_segment - last_written_segment;
946 
947           /* advance the ringbuffer */
948           gst_audio_ring_buffer_advance (ringbuffer, segment_diff);
949 
950           /* we move the  new read segment to the last known written segment */
951           new_read_segment =
952               g_atomic_int_get (&ringbuffer->segdone) - ringbuffer->segbase;
953 
954           /* we calculate the new sample value */
955           new_sample = ((guint64) new_read_segment) * sps;
956 
957           /* and get the relative time to this -> our new timestamp */
958           timestamp = gst_util_uint64_scale_int (new_sample, GST_SECOND, rate);
959 
960           /* we update the next sample accordingly */
961           src->next_sample = new_sample + samples;
962 
963           GST_DEBUG_OBJECT (bsrc,
964               "Timeshifted the ringbuffer with %d segments: "
965               "Updating the timestamp to %" GST_TIME_FORMAT ", "
966               "and src->next_sample to %" G_GUINT64_FORMAT, segment_diff,
967               GST_TIME_ARGS (timestamp), src->next_sample);
968         }
969         break;
970       }
971       case GST_AUDIO_BASE_SRC_SLAVE_RE_TIMESTAMP:
972       {
973         GstClockTime base_time, latency;
974 
975         /* We are slaved to another clock. Take running time of the pipeline
976          * clock and timestamp against it. Somebody else in the pipeline should
977          * figure out the clock drift. We keep the duration we calculated
978          * above. */
979         timestamp = gst_clock_get_time (clock);
980         base_time = GST_ELEMENT_CAST (src)->base_time;
981 
982         if (GST_CLOCK_DIFF (timestamp, base_time) < 0)
983           timestamp -= base_time;
984         else
985           timestamp = 0;
986 
987         /* subtract latency */
988         latency = gst_util_uint64_scale_int (total_samples, GST_SECOND, rate);
989         if (timestamp > latency)
990           timestamp -= latency;
991         else
992           timestamp = 0;
993       }
994       case GST_AUDIO_BASE_SRC_SLAVE_NONE:
995         break;
996     }
997   } else {
998     GstClockTime base_time;
999 
1000     if (GST_CLOCK_TIME_IS_VALID (rb_timestamp)) {
1001       /* the read method returned a timestamp so we use this instead */
1002       timestamp = rb_timestamp;
1003     } else {
1004       /* to get the timestamp against the clock we also need to add our
1005        * offset */
1006       timestamp = gst_audio_clock_adjust (GST_AUDIO_CLOCK (clock), timestamp);
1007     }
1008 
1009     /* we are not slaved, subtract base_time */
1010     base_time = GST_ELEMENT_CAST (src)->base_time;
1011 
1012     if (GST_CLOCK_DIFF (timestamp, base_time) < 0) {
1013       timestamp -= base_time;
1014       GST_LOG_OBJECT (src,
1015           "buffer timestamp %" GST_TIME_FORMAT " (base_time %" GST_TIME_FORMAT
1016           ")", GST_TIME_ARGS (timestamp), GST_TIME_ARGS (base_time));
1017     } else {
1018       GST_LOG_OBJECT (src,
1019           "buffer timestamp 0, ts %" GST_TIME_FORMAT " <= base_time %"
1020           GST_TIME_FORMAT, GST_TIME_ARGS (timestamp),
1021           GST_TIME_ARGS (base_time));
1022       timestamp = 0;
1023     }
1024   }
1025 
1026 no_sync:
1027   GST_OBJECT_UNLOCK (src);
1028 
1029   GST_BUFFER_TIMESTAMP (buf) = timestamp;
1030   GST_BUFFER_DURATION (buf) = duration;
1031   GST_BUFFER_OFFSET (buf) = sample;
1032   GST_BUFFER_OFFSET_END (buf) = sample + samples;
1033 
1034   *outbuf = buf;
1035 
1036   GST_LOG_OBJECT (src, "Pushed buffer timestamp %" GST_TIME_FORMAT,
1037       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
1038 
1039   return GST_FLOW_OK;
1040 
1041   /* ERRORS */
1042 wrong_state:
1043   {
1044     GST_DEBUG_OBJECT (src, "ringbuffer in wrong state");
1045     return GST_FLOW_FLUSHING;
1046   }
1047 wrong_offset:
1048   {
1049     GST_ELEMENT_ERROR (src, RESOURCE, SEEK,
1050         (NULL), ("resource can only be operated on sequentially but offset %"
1051             G_GUINT64_FORMAT " was given", offset));
1052     return GST_FLOW_ERROR;
1053   }
1054 alloc_failed:
1055   {
1056     GST_DEBUG_OBJECT (src, "alloc failed: %s", gst_flow_get_name (ret));
1057     return ret;
1058   }
1059 stopped:
1060   {
1061     gst_buffer_unmap (buf, &info);
1062     gst_buffer_unref (buf);
1063     GST_DEBUG_OBJECT (src, "ringbuffer stopped");
1064     return GST_FLOW_FLUSHING;
1065   }
1066 got_error:
1067   {
1068     gst_buffer_unmap (buf, &info);
1069     gst_buffer_unref (buf);
1070     GST_DEBUG_OBJECT (src, "ringbuffer was in error state, bailing out");
1071     return GST_FLOW_ERROR;
1072   }
1073 }
1074 
1075 /**
1076  * gst_audio_base_src_create_ringbuffer:
1077  * @src: a #GstAudioBaseSrc.
1078  *
1079  * Create and return the #GstAudioRingBuffer for @src. This function will call
1080  * the ::create_ringbuffer vmethod and will set @src as the parent of the
1081  * returned buffer (see gst_object_set_parent()).
1082  *
1083  * Returns: (transfer none): The new ringbuffer of @src.
1084  */
1085 GstAudioRingBuffer *
gst_audio_base_src_create_ringbuffer(GstAudioBaseSrc * src)1086 gst_audio_base_src_create_ringbuffer (GstAudioBaseSrc * src)
1087 {
1088   GstAudioBaseSrcClass *bclass;
1089   GstAudioRingBuffer *buffer = NULL;
1090 
1091   bclass = GST_AUDIO_BASE_SRC_GET_CLASS (src);
1092   if (bclass->create_ringbuffer)
1093     buffer = bclass->create_ringbuffer (src);
1094 
1095   if (G_LIKELY (buffer))
1096     gst_object_set_parent (GST_OBJECT_CAST (buffer), GST_OBJECT_CAST (src));
1097 
1098   return buffer;
1099 }
1100 
1101 static GstStateChangeReturn
gst_audio_base_src_change_state(GstElement * element,GstStateChange transition)1102 gst_audio_base_src_change_state (GstElement * element,
1103     GstStateChange transition)
1104 {
1105   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
1106   GstAudioBaseSrc *src = GST_AUDIO_BASE_SRC (element);
1107 
1108   switch (transition) {
1109     case GST_STATE_CHANGE_NULL_TO_READY:{
1110       GstAudioRingBuffer *rb;
1111 
1112       GST_DEBUG_OBJECT (src, "NULL->READY");
1113       gst_audio_clock_reset (GST_AUDIO_CLOCK (src->clock), 0);
1114       rb = gst_audio_base_src_create_ringbuffer (src);
1115       if (rb == NULL)
1116         goto create_failed;
1117 
1118       GST_OBJECT_LOCK (src);
1119       src->ringbuffer = rb;
1120       GST_OBJECT_UNLOCK (src);
1121 
1122       if (!gst_audio_ring_buffer_open_device (src->ringbuffer)) {
1123         GST_OBJECT_LOCK (src);
1124         gst_object_unparent (GST_OBJECT_CAST (src->ringbuffer));
1125         src->ringbuffer = NULL;
1126         GST_OBJECT_UNLOCK (src);
1127         goto open_failed;
1128       }
1129       break;
1130     }
1131     case GST_STATE_CHANGE_READY_TO_PAUSED:
1132       GST_DEBUG_OBJECT (src, "READY->PAUSED");
1133       src->next_sample = -1;
1134       gst_audio_ring_buffer_set_flushing (src->ringbuffer, FALSE);
1135       gst_audio_ring_buffer_may_start (src->ringbuffer, FALSE);
1136       /* Only post clock-provide messages if this is the clock that
1137        * we've created. If the subclass has overriden it the subclass
1138        * should post this messages whenever necessary */
1139       if (src->clock && GST_IS_AUDIO_CLOCK (src->clock) &&
1140           GST_AUDIO_CLOCK_CAST (src->clock)->func ==
1141           (GstAudioClockGetTimeFunc) gst_audio_base_src_get_time)
1142         gst_element_post_message (element,
1143             gst_message_new_clock_provide (GST_OBJECT_CAST (element),
1144                 src->clock, TRUE));
1145       break;
1146     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1147       GST_DEBUG_OBJECT (src, "PAUSED->PLAYING");
1148       gst_audio_ring_buffer_may_start (src->ringbuffer, TRUE);
1149       break;
1150     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1151       GST_DEBUG_OBJECT (src, "PLAYING->PAUSED");
1152       gst_audio_ring_buffer_may_start (src->ringbuffer, FALSE);
1153       gst_audio_ring_buffer_pause (src->ringbuffer);
1154       break;
1155     case GST_STATE_CHANGE_PAUSED_TO_READY:
1156       GST_DEBUG_OBJECT (src, "PAUSED->READY");
1157       /* Only post clock-lost messages if this is the clock that
1158        * we've created. If the subclass has overriden it the subclass
1159        * should post this messages whenever necessary */
1160       if (src->clock && GST_IS_AUDIO_CLOCK (src->clock) &&
1161           GST_AUDIO_CLOCK_CAST (src->clock)->func ==
1162           (GstAudioClockGetTimeFunc) gst_audio_base_src_get_time)
1163         gst_element_post_message (element,
1164             gst_message_new_clock_lost (GST_OBJECT_CAST (element), src->clock));
1165       gst_audio_ring_buffer_set_flushing (src->ringbuffer, TRUE);
1166       break;
1167     default:
1168       break;
1169   }
1170 
1171   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1172 
1173   switch (transition) {
1174     case GST_STATE_CHANGE_PAUSED_TO_READY:
1175       GST_DEBUG_OBJECT (src, "PAUSED->READY");
1176       gst_audio_ring_buffer_release (src->ringbuffer);
1177       break;
1178     case GST_STATE_CHANGE_READY_TO_NULL:
1179       GST_DEBUG_OBJECT (src, "READY->NULL");
1180       gst_audio_ring_buffer_close_device (src->ringbuffer);
1181       GST_OBJECT_LOCK (src);
1182       gst_object_unparent (GST_OBJECT_CAST (src->ringbuffer));
1183       src->ringbuffer = NULL;
1184       GST_OBJECT_UNLOCK (src);
1185       break;
1186     default:
1187       break;
1188   }
1189 
1190   return ret;
1191 
1192   /* ERRORS */
1193 create_failed:
1194   {
1195     /* subclass must post a meaningful error message */
1196     GST_DEBUG_OBJECT (src, "create failed");
1197     return GST_STATE_CHANGE_FAILURE;
1198   }
1199 open_failed:
1200   {
1201     /* subclass must post a meaningful error message */
1202     GST_DEBUG_OBJECT (src, "open failed");
1203     return GST_STATE_CHANGE_FAILURE;
1204   }
1205 
1206 }
1207 
1208 static gboolean
gst_audio_base_src_post_message(GstElement * element,GstMessage * message)1209 gst_audio_base_src_post_message (GstElement * element, GstMessage * message)
1210 {
1211   GstAudioBaseSrc *src = GST_AUDIO_BASE_SRC (element);
1212   gboolean ret;
1213 
1214   if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR && src->ringbuffer) {
1215     GstAudioRingBuffer *ringbuffer;
1216 
1217     GST_INFO_OBJECT (element, "subclass posted error");
1218 
1219     ringbuffer = gst_object_ref (src->ringbuffer);
1220 
1221     /* post message first before signalling the error to the ringbuffer, to
1222      * make sure it ends up on the bus before the generic basesrc internal
1223      * flow error message */
1224     ret = GST_ELEMENT_CLASS (parent_class)->post_message (element, message);
1225 
1226     g_atomic_int_set (&ringbuffer->state, GST_AUDIO_RING_BUFFER_STATE_ERROR);
1227     GST_AUDIO_RING_BUFFER_SIGNAL (ringbuffer);
1228     gst_object_unref (ringbuffer);
1229   } else {
1230     ret = GST_ELEMENT_CLASS (parent_class)->post_message (element, message);
1231   }
1232   return ret;
1233 }
1234