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