Added gst-plugins-base-subtitles0.10-0.10.34 for Meego Harmattan 1.2
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / 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   gst_structure_fixate_field_nearest_int (s, "width", 16);
538
539   /* fields for int */
540   if (gst_structure_has_field (s, "depth")) {
541     gst_structure_get_int (s, "width", &width);
542     /* round width to nearest multiple of 8 for the depth */
543     depth = GST_ROUND_UP_8 (width);
544     gst_structure_fixate_field_nearest_int (s, "depth", depth);
545   }
546   if (gst_structure_has_field (s, "signed"))
547     gst_structure_fixate_field_boolean (s, "signed", TRUE);
548   if (gst_structure_has_field (s, "endianness"))
549     gst_structure_fixate_field_nearest_int (s, "endianness", G_BYTE_ORDER);
550 }
551
552 static gboolean
553 gst_base_audio_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
554 {
555   GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (bsrc);
556   GstRingBufferSpec *spec;
557
558   spec = &src->ringbuffer->spec;
559
560   spec->buffer_time = src->buffer_time;
561   spec->latency_time = src->latency_time;
562
563   GST_OBJECT_LOCK (src);
564   if (!gst_ring_buffer_parse_caps (spec, caps))
565   {
566     GST_OBJECT_UNLOCK (src);
567     goto parse_error;
568   }
569
570   /* calculate suggested segsize and segtotal */
571   spec->segsize =
572       spec->rate * spec->bytes_per_sample * spec->latency_time / GST_MSECOND;
573   spec->segtotal = spec->buffer_time / spec->latency_time;
574
575   GST_OBJECT_UNLOCK (src);
576
577   GST_DEBUG ("release old ringbuffer");
578
579   gst_ring_buffer_release (src->ringbuffer);
580
581   gst_ring_buffer_debug_spec_buff (spec);
582
583   GST_DEBUG ("acquire new ringbuffer");
584
585   if (!gst_ring_buffer_acquire (src->ringbuffer, spec))
586     goto acquire_error;
587
588   /* calculate actual latency and buffer times */
589   spec->latency_time =
590       spec->segsize * GST_MSECOND / (spec->rate * spec->bytes_per_sample);
591   spec->buffer_time =
592       spec->segtotal * spec->segsize * GST_MSECOND / (spec->rate *
593       spec->bytes_per_sample);
594
595   gst_ring_buffer_debug_spec_buff (spec);
596
597   g_object_notify (G_OBJECT (src), "actual-buffer-time");
598   g_object_notify (G_OBJECT (src), "actual-latency-time");
599
600   return TRUE;
601
602   /* ERRORS */
603 parse_error:
604   {
605     GST_DEBUG ("could not parse caps");
606     return FALSE;
607   }
608 acquire_error:
609   {
610     GST_DEBUG ("could not acquire ringbuffer");
611     return FALSE;
612   }
613 }
614
615 static void
616 gst_base_audio_src_get_times (GstBaseSrc * bsrc, GstBuffer * buffer,
617     GstClockTime * start, GstClockTime * end)
618 {
619   /* no need to sync to a clock here, we schedule the samples based
620    * on our own clock for the moment. */
621   *start = GST_CLOCK_TIME_NONE;
622   *end = GST_CLOCK_TIME_NONE;
623 }
624
625 static gboolean
626 gst_base_audio_src_query (GstBaseSrc * bsrc, GstQuery * query)
627 {
628   GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (bsrc);
629   gboolean res = FALSE;
630
631   switch (GST_QUERY_TYPE (query)) {
632     case GST_QUERY_LATENCY:
633     {
634       GstClockTime min_latency, max_latency;
635       GstRingBufferSpec *spec;
636
637       GST_OBJECT_LOCK (src);
638       if (G_UNLIKELY (src->ringbuffer == NULL
639               || src->ringbuffer->spec.rate == 0)) {
640         GST_OBJECT_UNLOCK (src);
641         goto done;
642       }
643
644       spec = &src->ringbuffer->spec;
645
646       /* we have at least 1 segment of latency */
647       min_latency =
648           gst_util_uint64_scale_int (spec->segsize, GST_SECOND,
649           spec->rate * spec->bytes_per_sample);
650       /* we cannot delay more than the buffersize else we lose data */
651       max_latency =
652           gst_util_uint64_scale_int (spec->segtotal * spec->segsize, GST_SECOND,
653           spec->rate * spec->bytes_per_sample);
654       GST_OBJECT_UNLOCK (src);
655
656       GST_DEBUG_OBJECT (src,
657           "report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
658           GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
659
660       /* we are always live, the min latency is 1 segment and the max latency is
661        * the complete buffer of segments. */
662       gst_query_set_latency (query, TRUE, min_latency, max_latency);
663
664       res = TRUE;
665       break;
666     }
667     default:
668       res = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query);
669       break;
670   }
671 done:
672   return res;
673 }
674
675 static gboolean
676 gst_base_audio_src_event (GstBaseSrc * bsrc, GstEvent * event)
677 {
678   GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (bsrc);
679   gboolean res;
680
681   res = TRUE;
682
683   switch (GST_EVENT_TYPE (event)) {
684     case GST_EVENT_FLUSH_START:
685       GST_DEBUG_OBJECT (bsrc, "flush-start");
686       gst_ring_buffer_pause (src->ringbuffer);
687       gst_ring_buffer_clear_all (src->ringbuffer);
688       break;
689     case GST_EVENT_FLUSH_STOP:
690       GST_DEBUG_OBJECT (bsrc, "flush-stop");
691       /* always resync on sample after a flush */
692       src->next_sample = -1;
693       gst_ring_buffer_clear_all (src->ringbuffer);
694       break;
695     case GST_EVENT_SEEK:
696       GST_DEBUG_OBJECT (bsrc, "refuse to seek");
697       res = FALSE;
698       break;
699     default:
700       GST_DEBUG_OBJECT (bsrc, "dropping event %p", event);
701       break;
702   }
703   return res;
704 }
705
706 /* get the next offset in the ringbuffer for reading samples.
707  * If the next sample is too far away, this function will position itself to the
708  * next most recent sample, creating discontinuity */
709 static guint64
710 gst_base_audio_src_get_offset (GstBaseAudioSrc * src)
711 {
712   guint64 sample;
713   gint readseg, segdone, segtotal, sps;
714   gint diff;
715
716   /* assume we can append to the previous sample */
717   sample = src->next_sample;
718
719   sps = src->ringbuffer->samples_per_seg;
720   segtotal = src->ringbuffer->spec.segtotal;
721
722   /* get the currently processed segment */
723   segdone = g_atomic_int_get (&src->ringbuffer->segdone)
724       - src->ringbuffer->segbase;
725
726   if (sample != -1) {
727     GST_DEBUG_OBJECT (src, "at segment %d and sample %" G_GUINT64_FORMAT,
728         segdone, sample);
729     /* figure out the segment and the offset inside the segment where
730      * the sample should be read from. */
731     readseg = sample / sps;
732
733     /* see how far away it is from the read segment, normally segdone (where new
734      * data is written in the ringbuffer) is bigger than readseg (where we are
735      * reading). */
736     diff = segdone - readseg;
737     if (diff >= segtotal) {
738       GST_DEBUG_OBJECT (src, "dropped, align to segment %d", segdone);
739       /* sample would be dropped, position to next playable position */
740       sample = ((guint64) (segdone)) * sps;
741     }
742   } else {
743     /* no previous sample, go to the current position */
744     GST_DEBUG_OBJECT (src, "first sample, align to current %d", segdone);
745     sample = ((guint64) (segdone)) * sps;
746     readseg = segdone;
747   }
748
749   GST_DEBUG_OBJECT (src,
750       "reading from %d, we are at %d, sample %" G_GUINT64_FORMAT, readseg,
751       segdone, sample);
752
753   return sample;
754 }
755
756 static GstFlowReturn
757 gst_base_audio_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
758     GstBuffer ** outbuf)
759 {
760   GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (bsrc);
761   GstBuffer *buf;
762   guchar *data;
763   guint samples, total_samples;
764   guint64 sample;
765   gint bps;
766   GstRingBuffer *ringbuffer;
767   GstRingBufferSpec *spec;
768   guint read;
769   GstClockTime timestamp, duration;
770   GstClock *clock;
771
772   ringbuffer = src->ringbuffer;
773   spec = &ringbuffer->spec;
774
775   if (G_UNLIKELY (!gst_ring_buffer_is_acquired (ringbuffer)))
776     goto wrong_state;
777
778   bps = spec->bytes_per_sample;
779
780   if ((length == 0 && bsrc->blocksize == 0) || length == -1)
781     /* no length given, use the default segment size */
782     length = spec->segsize;
783   else
784     /* make sure we round down to an integral number of samples */
785     length -= length % bps;
786
787   /* figure out the offset in the ringbuffer */
788   if (G_UNLIKELY (offset != -1)) {
789     sample = offset / bps;
790     /* if a specific offset was given it must be the next sequential
791      * offset we expect or we fail for now. */
792     if (src->next_sample != -1 && sample != src->next_sample)
793       goto wrong_offset;
794   } else {
795     /* calculate the sequentially next sample we need to read. This can jump and
796      * create a DISCONT. */
797     sample = gst_base_audio_src_get_offset (src);
798   }
799
800   GST_DEBUG_OBJECT (src, "reading from sample %" G_GUINT64_FORMAT, sample);
801
802   /* get the number of samples to read */
803   total_samples = samples = length / bps;
804
805   /* FIXME, using a bufferpool would be nice here */
806   buf = gst_buffer_new_and_alloc (length);
807   data = GST_BUFFER_DATA (buf);
808
809   do {
810     read = gst_ring_buffer_read (ringbuffer, sample, data, samples);
811     GST_DEBUG_OBJECT (src, "read %u of %u", read, samples);
812     /* if we read all, we're done */
813     if (read == samples)
814       break;
815
816     /* else something interrupted us and we wait for playing again. */
817     GST_DEBUG_OBJECT (src, "wait playing");
818     if (gst_base_src_wait_playing (bsrc) != GST_FLOW_OK)
819       goto stopped;
820
821     GST_DEBUG_OBJECT (src, "continue playing");
822
823     /* read next samples */
824     sample += read;
825     samples -= read;
826     data += read * bps;
827   } while (TRUE);
828
829   /* mark discontinuity if needed */
830   if (G_UNLIKELY (sample != src->next_sample) && src->next_sample != -1) {
831     GST_WARNING_OBJECT (src,
832         "create DISCONT of %" G_GUINT64_FORMAT " samples at sample %"
833         G_GUINT64_FORMAT, sample - src->next_sample, sample);
834     GST_ELEMENT_WARNING (src, CORE, CLOCK,
835         (_("Can't record audio fast enough")),
836         ("Dropped %" G_GUINT64_FORMAT " samples. This is most likely because "
837             "downstream can't keep up and is consuming samples too slowly.",
838             sample - src->next_sample));
839     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
840   }
841
842   src->next_sample = sample + samples;
843
844   /* get the normal timestamp to get the duration. */
845   timestamp = gst_util_uint64_scale_int (sample, GST_SECOND, spec->rate);
846   duration = gst_util_uint64_scale_int (src->next_sample, GST_SECOND,
847       spec->rate) - timestamp;
848
849   GST_OBJECT_LOCK (src);
850   if (!(clock = GST_ELEMENT_CLOCK (src)))
851     goto no_sync;
852
853   if (clock != src->clock) {
854     /* we are slaved, check how to handle this */
855     switch (src->priv->slave_method) {
856       case GST_BASE_AUDIO_SRC_SLAVE_RESAMPLE:
857         /* not implemented, use skew algorithm. This algorithm should
858          * work on the readout pointer and produces more or less samples based
859          * on the clock drift */
860       case GST_BASE_AUDIO_SRC_SLAVE_SKEW:
861       {
862         GstClockTime running_time;
863         GstClockTime base_time;
864         GstClockTime current_time;
865         guint64 running_time_sample;
866         gint running_time_segment;
867         gint last_read_segment;
868         gint segment_skew;
869         gint sps;
870         gint segments_written;
871         gint last_written_segment;
872
873         /* get the amount of segments written from the device by now */
874         segments_written = g_atomic_int_get (&ringbuffer->segdone);
875
876         /* subtract the base to segments_written to get the number of the
877            last written segment in the ringbuffer (one segment written = segment 0) */
878         last_written_segment = segments_written - ringbuffer->segbase - 1;
879
880         /* samples per segment */
881         sps = ringbuffer->samples_per_seg;
882
883         /* get the current time */
884         current_time = gst_clock_get_time (clock);
885
886         /* get the basetime */
887         base_time = GST_ELEMENT_CAST (src)->base_time;
888
889         /* get the running_time */
890         running_time = current_time - base_time;
891
892         /* the running_time converted to a sample (relative to the ringbuffer) */
893         running_time_sample =
894             gst_util_uint64_scale_int (running_time, spec->rate, GST_SECOND);
895
896         /* the segmentnr corrensponding to running_time, round down */
897         running_time_segment = running_time_sample / sps;
898
899         /* the segment currently read from the ringbuffer */
900         last_read_segment = sample / sps;
901
902         /* the skew we have between running_time and the ringbuffertime (last written to) */
903         segment_skew = running_time_segment - last_written_segment;
904
905         GST_DEBUG_OBJECT (bsrc,
906             "\n running_time                                              = %"
907             GST_TIME_FORMAT
908             "\n timestamp                                                  = %"
909             GST_TIME_FORMAT
910             "\n running_time_segment                                       = %d"
911             "\n last_written_segment                                       = %d"
912             "\n segment_skew (running time segment - last_written_segment) = %d"
913             "\n last_read_segment                                          = %d",
914             GST_TIME_ARGS (running_time), GST_TIME_ARGS (timestamp),
915             running_time_segment, last_written_segment, segment_skew,
916             last_read_segment);
917
918         /* Resync the ringbuffer if:
919          *
920          * 1. We are more than the length of the ringbuffer behind.
921          *    The length of the ringbuffer then gets to dictate
922          *    the threshold for what is concidered "too late"
923          *
924          * 2. If this is our first buffer.
925          *    We know that we should catch up to running_time
926          *    the first time we are ran.
927          */
928         if ((segment_skew >= ringbuffer->spec.segtotal) ||
929             (last_read_segment == 0)) {
930           gint new_read_segment;
931           gint segment_diff;
932           guint64 new_sample;
933
934           /* the difference between running_time and the last written segment */
935           segment_diff = running_time_segment - last_written_segment;
936
937           /* advance the ringbuffer */
938           gst_ring_buffer_advance (ringbuffer, segment_diff);
939
940           /* we move the  new read segment to the last known written segment */
941           new_read_segment =
942               g_atomic_int_get (&ringbuffer->segdone) - ringbuffer->segbase;
943
944           /* we calculate the new sample value */
945           new_sample = ((guint64) new_read_segment) * sps;
946
947           /* and get the relative time to this -> our new timestamp */
948           timestamp =
949               gst_util_uint64_scale_int (new_sample, GST_SECOND, spec->rate);
950
951           /* we update the next sample accordingly */
952           src->next_sample = new_sample + samples;
953
954           GST_DEBUG_OBJECT (bsrc,
955               "Timeshifted the ringbuffer with %d segments: "
956               "Updating the timestamp to %" GST_TIME_FORMAT ", "
957               "and src->next_sample to %" G_GUINT64_FORMAT, segment_diff,
958               GST_TIME_ARGS (timestamp), src->next_sample);
959         }
960         break;
961       }
962       case GST_BASE_AUDIO_SRC_SLAVE_RETIMESTAMP:
963       {
964         GstClockTime base_time, latency;
965
966         /* We are slaved to another clock, take running time of the pipeline clock and
967          * timestamp against it. Somebody else in the pipeline should figure out the
968          * clock drift. We keep the duration we calculated above. */
969         timestamp = gst_clock_get_time (clock);
970         base_time = GST_ELEMENT_CAST (src)->base_time;
971
972         if (GST_CLOCK_DIFF (timestamp, base_time) < 0)
973           timestamp -= base_time;
974         else
975           timestamp = 0;
976
977         /* subtract latency */
978         latency =
979             gst_util_uint64_scale_int (total_samples, GST_SECOND, spec->rate);
980         if (timestamp > latency)
981           timestamp -= latency;
982         else
983           timestamp = 0;
984       }
985       case GST_BASE_AUDIO_SRC_SLAVE_NONE:
986         break;
987     }
988   } else {
989     GstClockTime base_time;
990
991     /* to get the timestamp against the clock we also need to add our offset */
992     timestamp = gst_audio_clock_adjust (clock, timestamp);
993
994     /* we are not slaved, subtract base_time */
995     base_time = GST_ELEMENT_CAST (src)->base_time;
996
997     if (GST_CLOCK_DIFF (timestamp, base_time) < 0) {
998       timestamp -= base_time;
999       GST_LOG_OBJECT (src,
1000           "buffer timestamp %" GST_TIME_FORMAT " (base_time %" GST_TIME_FORMAT
1001           ")", GST_TIME_ARGS (timestamp), GST_TIME_ARGS (base_time));
1002     } else {
1003       GST_LOG_OBJECT (src,
1004           "buffer timestamp 0, ts %" GST_TIME_FORMAT " <= base_time %"
1005           GST_TIME_FORMAT, GST_TIME_ARGS (timestamp),
1006           GST_TIME_ARGS (base_time));
1007       timestamp = 0;
1008     }
1009   }
1010
1011 no_sync:
1012   GST_OBJECT_UNLOCK (src);
1013
1014   GST_BUFFER_TIMESTAMP (buf) = timestamp;
1015   GST_BUFFER_DURATION (buf) = duration;
1016   GST_BUFFER_OFFSET (buf) = sample;
1017   GST_BUFFER_OFFSET_END (buf) = sample + samples;
1018
1019   *outbuf = buf;
1020
1021   return GST_FLOW_OK;
1022
1023   /* ERRORS */
1024 wrong_state:
1025   {
1026     GST_DEBUG_OBJECT (src, "ringbuffer in wrong state");
1027     return GST_FLOW_WRONG_STATE;
1028   }
1029 wrong_offset:
1030   {
1031     GST_ELEMENT_ERROR (src, RESOURCE, SEEK,
1032         (NULL), ("resource can only be operated on sequentially but offset %"
1033             G_GUINT64_FORMAT " was given", offset));
1034     return GST_FLOW_ERROR;
1035   }
1036 stopped:
1037   {
1038     gst_buffer_unref (buf);
1039     GST_DEBUG_OBJECT (src, "ringbuffer stopped");
1040     return GST_FLOW_WRONG_STATE;
1041   }
1042 }
1043
1044 /**
1045  * gst_base_audio_src_create_ringbuffer:
1046  * @src: a #GstBaseAudioSrc.
1047  *
1048  * Create and return the #GstRingBuffer for @src. This function will call the
1049  * ::create_ringbuffer vmethod and will set @src as the parent of the returned
1050  * buffer (see gst_object_set_parent()).
1051  *
1052  * Returns: The new ringbuffer of @src.
1053  */
1054 GstRingBuffer *
1055 gst_base_audio_src_create_ringbuffer (GstBaseAudioSrc * src)
1056 {
1057   GstBaseAudioSrcClass *bclass;
1058   GstRingBuffer *buffer = NULL;
1059
1060   bclass = GST_BASE_AUDIO_SRC_GET_CLASS (src);
1061   if (bclass->create_ringbuffer)
1062     buffer = bclass->create_ringbuffer (src);
1063
1064   if (G_LIKELY (buffer))
1065     gst_object_set_parent (GST_OBJECT_CAST (buffer), GST_OBJECT_CAST (src));
1066
1067   return buffer;
1068 }
1069
1070 static GstStateChangeReturn
1071 gst_base_audio_src_change_state (GstElement * element,
1072     GstStateChange transition)
1073 {
1074   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
1075   GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (element);
1076
1077   switch (transition) {
1078     case GST_STATE_CHANGE_NULL_TO_READY:
1079       GST_DEBUG_OBJECT (src, "NULL->READY");
1080       GST_OBJECT_LOCK (src);
1081       if (src->ringbuffer == NULL) {
1082         gst_audio_clock_reset (GST_AUDIO_CLOCK (src->clock), 0);
1083         src->ringbuffer = gst_base_audio_src_create_ringbuffer (src);
1084       }
1085       GST_OBJECT_UNLOCK (src);
1086       if (!gst_ring_buffer_open_device (src->ringbuffer))
1087         goto open_failed;
1088       break;
1089     case GST_STATE_CHANGE_READY_TO_PAUSED:
1090       GST_DEBUG_OBJECT (src, "READY->PAUSED");
1091       src->next_sample = -1;
1092       gst_ring_buffer_set_flushing (src->ringbuffer, FALSE);
1093       gst_ring_buffer_may_start (src->ringbuffer, FALSE);
1094       /* Only post clock-provide messages if this is the clock that
1095        * we've created. If the subclass has overriden it the subclass
1096        * should post this messages whenever necessary */
1097       if (src->clock && GST_IS_AUDIO_CLOCK (src->clock) &&
1098           GST_AUDIO_CLOCK_CAST (src->clock)->func ==
1099           (GstAudioClockGetTimeFunc) gst_base_audio_src_get_time)
1100         gst_element_post_message (element,
1101             gst_message_new_clock_provide (GST_OBJECT_CAST (element),
1102                 src->clock, TRUE));
1103       break;
1104     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1105       GST_DEBUG_OBJECT (src, "PAUSED->PLAYING");
1106       gst_ring_buffer_may_start (src->ringbuffer, TRUE);
1107       break;
1108     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1109       GST_DEBUG_OBJECT (src, "PLAYING->PAUSED");
1110       gst_ring_buffer_may_start (src->ringbuffer, FALSE);
1111       gst_ring_buffer_pause (src->ringbuffer);
1112       break;
1113     case GST_STATE_CHANGE_PAUSED_TO_READY:
1114       GST_DEBUG_OBJECT (src, "PAUSED->READY");
1115       /* Only post clock-lost messages if this is the clock that
1116        * we've created. If the subclass has overriden it the subclass
1117        * should post this messages whenever necessary */
1118       if (src->clock && GST_IS_AUDIO_CLOCK (src->clock) &&
1119           GST_AUDIO_CLOCK_CAST (src->clock)->func ==
1120           (GstAudioClockGetTimeFunc) gst_base_audio_src_get_time)
1121         gst_element_post_message (element,
1122             gst_message_new_clock_lost (GST_OBJECT_CAST (element), src->clock));
1123       gst_ring_buffer_set_flushing (src->ringbuffer, TRUE);
1124       break;
1125     default:
1126       break;
1127   }
1128
1129   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1130
1131   switch (transition) {
1132     case GST_STATE_CHANGE_PAUSED_TO_READY:
1133       GST_DEBUG_OBJECT (src, "PAUSED->READY");
1134       gst_ring_buffer_release (src->ringbuffer);
1135       break;
1136     case GST_STATE_CHANGE_READY_TO_NULL:
1137       GST_DEBUG_OBJECT (src, "READY->NULL");
1138       gst_ring_buffer_close_device (src->ringbuffer);
1139       GST_OBJECT_LOCK (src);
1140       gst_object_unparent (GST_OBJECT_CAST (src->ringbuffer));
1141       src->ringbuffer = NULL;
1142       GST_OBJECT_UNLOCK (src);
1143       break;
1144     default:
1145       break;
1146   }
1147
1148   return ret;
1149
1150   /* ERRORS */
1151 open_failed:
1152   {
1153     /* subclass must post a meaningfull error message */
1154     GST_DEBUG_OBJECT (src, "open failed");
1155     return GST_STATE_CHANGE_FAILURE;
1156   }
1157
1158 }