Added gst-plugins-base-subtitles0.10-0.10.34 for Meego Harmattan 1.2
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / gst-libs / gst / audio / gstringbuffer.c
1 /* GStreamer
2  * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /**
21  * SECTION:gstringbuffer
22  * @short_description: Base class for audio ringbuffer implementations
23  * @see_also: #GstBaseAudioSink, #GstAudioSink
24  *
25  * <refsect2>
26  * <para>
27  * This object is the base class for audio ringbuffers used by the base
28  * audio source and sink classes.
29  * </para>
30  * <para>
31  * The ringbuffer abstracts a circular buffer of data. One reader and
32  * one writer can operate on the data from different threads in a lockfree
33  * manner. The base class is sufficiently flexible to be used as an
34  * abstraction for DMA based ringbuffers as well as a pure software
35  * implementations.
36  * </para>
37  * </refsect2>
38  *
39  * Last reviewed on 2006-02-02 (0.10.4)
40  */
41
42 #include <string.h>
43
44 #include "gstringbuffer.h"
45
46 GST_DEBUG_CATEGORY_STATIC (gst_ring_buffer_debug);
47 #define GST_CAT_DEFAULT gst_ring_buffer_debug
48
49 static void gst_ring_buffer_dispose (GObject * object);
50 static void gst_ring_buffer_finalize (GObject * object);
51
52 static gboolean gst_ring_buffer_pause_unlocked (GstRingBuffer * buf);
53 static void default_clear_all (GstRingBuffer * buf);
54 static guint default_commit (GstRingBuffer * buf, guint64 * sample,
55     guchar * data, gint in_samples, gint out_samples, gint * accum);
56
57 /* ringbuffer abstract base class */
58 G_DEFINE_ABSTRACT_TYPE (GstRingBuffer, gst_ring_buffer, GST_TYPE_OBJECT);
59
60 static void
61 gst_ring_buffer_class_init (GstRingBufferClass * klass)
62 {
63   GObjectClass *gobject_class;
64   GstRingBufferClass *gstringbuffer_class;
65
66   gobject_class = (GObjectClass *) klass;
67   gstringbuffer_class = (GstRingBufferClass *) klass;
68
69   GST_DEBUG_CATEGORY_INIT (gst_ring_buffer_debug, "ringbuffer", 0,
70       "ringbuffer class");
71
72   gobject_class->dispose = gst_ring_buffer_dispose;
73   gobject_class->finalize = gst_ring_buffer_finalize;
74
75   gstringbuffer_class->clear_all = GST_DEBUG_FUNCPTR (default_clear_all);
76   gstringbuffer_class->commit = GST_DEBUG_FUNCPTR (default_commit);
77 }
78
79 static void
80 gst_ring_buffer_init (GstRingBuffer * ringbuffer)
81 {
82   ringbuffer->open = FALSE;
83   ringbuffer->acquired = FALSE;
84   ringbuffer->state = GST_RING_BUFFER_STATE_STOPPED;
85   ringbuffer->cond = g_cond_new ();
86   ringbuffer->waiting = 0;
87   ringbuffer->empty_seg = NULL;
88   ringbuffer->abidata.ABI.flushing = TRUE;
89 }
90
91 static void
92 gst_ring_buffer_dispose (GObject * object)
93 {
94   GstRingBuffer *ringbuffer = GST_RING_BUFFER (object);
95
96   gst_caps_replace (&ringbuffer->spec.caps, NULL);
97
98   G_OBJECT_CLASS (gst_ring_buffer_parent_class)->dispose (G_OBJECT
99       (ringbuffer));
100 }
101
102 static void
103 gst_ring_buffer_finalize (GObject * object)
104 {
105   GstRingBuffer *ringbuffer = GST_RING_BUFFER (object);
106
107   g_cond_free (ringbuffer->cond);
108   g_free (ringbuffer->empty_seg);
109
110   G_OBJECT_CLASS (gst_ring_buffer_parent_class)->finalize (G_OBJECT
111       (ringbuffer));
112 }
113
114 typedef struct
115 {
116   const GstBufferFormat format;
117   const guint8 silence[4];
118 } FormatDef;
119
120 static const FormatDef linear_defs[4 * 2 * 2] = {
121   {GST_S8, {0x00, 0x00, 0x00, 0x00}},
122   {GST_S8, {0x00, 0x00, 0x00, 0x00}},
123   {GST_U8, {0x80, 0x80, 0x80, 0x80}},
124   {GST_U8, {0x80, 0x80, 0x80, 0x80}},
125   {GST_S16_LE, {0x00, 0x00, 0x00, 0x00}},
126   {GST_S16_BE, {0x00, 0x00, 0x00, 0x00}},
127   {GST_U16_LE, {0x00, 0x80, 0x00, 0x80}},
128   {GST_U16_BE, {0x80, 0x00, 0x80, 0x00}},
129   {GST_S24_LE, {0x00, 0x00, 0x00, 0x00}},
130   {GST_S24_BE, {0x00, 0x00, 0x00, 0x00}},
131   {GST_U24_LE, {0x00, 0x00, 0x80, 0x00}},
132   {GST_U24_BE, {0x80, 0x00, 0x00, 0x00}},
133   {GST_S32_LE, {0x00, 0x00, 0x00, 0x00}},
134   {GST_S32_BE, {0x00, 0x00, 0x00, 0x00}},
135   {GST_U32_LE, {0x00, 0x00, 0x00, 0x80}},
136   {GST_U32_BE, {0x80, 0x00, 0x00, 0x00}}
137 };
138
139 static const FormatDef linear24_defs[3 * 2 * 2] = {
140   {GST_S24_3LE, {0x00, 0x00, 0x00, 0x00}},
141   {GST_S24_3BE, {0x00, 0x00, 0x00, 0x00}},
142   {GST_U24_3LE, {0x00, 0x00, 0x80, 0x00}},
143   {GST_U24_3BE, {0x80, 0x00, 0x00, 0x00}},
144   {GST_S20_3LE, {0x00, 0x00, 0x00, 0x00}},
145   {GST_S20_3BE, {0x00, 0x00, 0x00, 0x00}},
146   {GST_U20_3LE, {0x00, 0x00, 0x08, 0x00}},
147   {GST_U20_3BE, {0x08, 0x00, 0x00, 0x00}},
148   {GST_S18_3LE, {0x00, 0x00, 0x00, 0x00}},
149   {GST_S18_3BE, {0x00, 0x00, 0x00, 0x00}},
150   {GST_U18_3LE, {0x00, 0x00, 0x02, 0x00}},
151   {GST_U18_3BE, {0x02, 0x00, 0x00, 0x00}}
152 };
153
154 static const FormatDef *
155 build_linear_format (int depth, int width, int unsignd, int big_endian)
156 {
157   const FormatDef *formats;
158
159   if (width == 24) {
160     switch (depth) {
161       case 24:
162         formats = &linear24_defs[0];
163         break;
164       case 20:
165         formats = &linear24_defs[4];
166         break;
167       case 18:
168         formats = &linear24_defs[8];
169         break;
170       default:
171         return NULL;
172     }
173   } else {
174     switch (depth) {
175       case 8:
176         formats = &linear_defs[0];
177         break;
178       case 16:
179         formats = &linear_defs[4];
180         break;
181       case 24:
182         formats = &linear_defs[8];
183         break;
184       case 32:
185         formats = &linear_defs[12];
186         break;
187       default:
188         return NULL;
189     }
190   }
191   if (unsignd)
192     formats += 2;
193   if (big_endian)
194     formats += 1;
195
196   return formats;
197 }
198
199 #ifndef GST_DISABLE_GST_DEBUG
200 static const gchar *format_type_names[] = {
201   "linear",
202   "float",
203   "mu law",
204   "a law",
205   "ima adpcm",
206   "mpeg",
207   "gsm",
208   "iec958",
209   "ac3",
210   "eac3",
211   "dts"
212 };
213
214 static const gchar *format_names[] = {
215   "unknown",
216   "s8",
217   "u8",
218   "s16_le",
219   "s16_be",
220   "u16_le",
221   "u16_be",
222   "s24_le",
223   "s24_be",
224   "u24_le",
225   "u24_be",
226   "s32_le",
227   "s32_be",
228   "u32_le",
229   "u32_be",
230   "s24_3le",
231   "s24_3be",
232   "u24_3le",
233   "u24_3be",
234   "s20_3le",
235   "s20_3be",
236   "u20_3le",
237   "u20_3be",
238   "s18_3le",
239   "s18_3be",
240   "u18_3le",
241   "u18_3be",
242   "float32_le",
243   "float32_be",
244   "float64_le",
245   "float64_be",
246   "mu_law",
247   "a_law",
248   "ima_adpcm",
249   "mpeg",
250   "gsm",
251   "iec958",
252   "ac3",
253   "eac3",
254   "dts"
255 };
256 #endif
257
258 /**
259  * gst_ring_buffer_debug_spec_caps:
260  * @spec: the spec to debug
261  *
262  * Print debug info about the parsed caps in @spec to the debug log.
263  */
264 void
265 gst_ring_buffer_debug_spec_caps (GstRingBufferSpec * spec)
266 {
267   gint i, bytes;
268
269   GST_DEBUG ("spec caps: %p %" GST_PTR_FORMAT, spec->caps, spec->caps);
270   GST_DEBUG ("parsed caps: type:         %d, '%s'", spec->type,
271       format_type_names[spec->type]);
272   GST_DEBUG ("parsed caps: format:       %d, '%s'", spec->format,
273       format_names[spec->format]);
274   GST_DEBUG ("parsed caps: width:        %d", spec->width);
275   GST_DEBUG ("parsed caps: depth:        %d", spec->depth);
276   GST_DEBUG ("parsed caps: sign:         %d", spec->sign);
277   GST_DEBUG ("parsed caps: bigend:       %d", spec->bigend);
278   GST_DEBUG ("parsed caps: rate:         %d", spec->rate);
279   GST_DEBUG ("parsed caps: channels:     %d", spec->channels);
280   GST_DEBUG ("parsed caps: sample bytes: %d", spec->bytes_per_sample);
281   bytes = (spec->width >> 3) * spec->channels;
282   for (i = 0; i < bytes; i++) {
283     GST_DEBUG ("silence byte %d: %02x", i, spec->silence_sample[i]);
284   }
285 }
286
287 /**
288  * gst_ring_buffer_debug_spec_buff:
289  * @spec: the spec to debug
290  *
291  * Print debug info about the buffer sized in @spec to the debug log.
292  */
293 void
294 gst_ring_buffer_debug_spec_buff (GstRingBufferSpec * spec)
295 {
296   GST_DEBUG ("acquire ringbuffer: buffer time: %" G_GINT64_FORMAT " usec",
297       spec->buffer_time);
298   GST_DEBUG ("acquire ringbuffer: latency time: %" G_GINT64_FORMAT " usec",
299       spec->latency_time);
300   GST_DEBUG ("acquire ringbuffer: total segments: %d", spec->segtotal);
301   GST_DEBUG ("acquire ringbuffer: latency segments: %d", spec->seglatency);
302   GST_DEBUG ("acquire ringbuffer: segment size: %d bytes = %d samples",
303       spec->segsize, spec->segsize / spec->bytes_per_sample);
304   GST_DEBUG ("acquire ringbuffer: buffer size: %d bytes = %d samples",
305       spec->segsize * spec->segtotal,
306       spec->segsize * spec->segtotal / spec->bytes_per_sample);
307 }
308
309 /**
310  * gst_ring_buffer_parse_caps:
311  * @spec: a spec
312  * @caps: a #GstCaps
313  *
314  * Parse @caps into @spec.
315  *
316  * Returns: TRUE if the caps could be parsed.
317  */
318 gboolean
319 gst_ring_buffer_parse_caps (GstRingBufferSpec * spec, GstCaps * caps)
320 {
321   const gchar *mimetype;
322   GstStructure *structure;
323   gint i;
324
325   structure = gst_caps_get_structure (caps, 0);
326
327   /* we have to differentiate between int and float formats */
328   mimetype = gst_structure_get_name (structure);
329
330   if (!strncmp (mimetype, "audio/x-raw-int", 15)) {
331     gint endianness;
332     const FormatDef *def;
333     gint j, bytes;
334
335     spec->type = GST_BUFTYPE_LINEAR;
336
337     /* extract the needed information from the cap */
338     if (!(gst_structure_get_int (structure, "rate", &spec->rate) &&
339             gst_structure_get_int (structure, "channels", &spec->channels) &&
340             gst_structure_get_int (structure, "width", &spec->width) &&
341             gst_structure_get_int (structure, "depth", &spec->depth) &&
342             gst_structure_get_boolean (structure, "signed", &spec->sign)))
343       goto parse_error;
344
345     /* extract endianness if needed */
346     if (spec->width > 8) {
347       if (!gst_structure_get_int (structure, "endianness", &endianness))
348         goto parse_error;
349     } else {
350       endianness = G_BYTE_ORDER;
351     }
352
353     spec->bigend = endianness == G_LITTLE_ENDIAN ? FALSE : TRUE;
354
355     def = build_linear_format (spec->depth, spec->width, spec->sign ? 0 : 1,
356         spec->bigend ? 1 : 0);
357
358     if (def == NULL)
359       goto parse_error;
360
361     spec->format = def->format;
362
363     bytes = spec->width >> 3;
364
365     for (i = 0; i < spec->channels; i++) {
366       for (j = 0; j < bytes; j++) {
367         spec->silence_sample[i * bytes + j] = def->silence[j];
368       }
369     }
370   } else if (!strncmp (mimetype, "audio/x-raw-float", 17)) {
371
372     spec->type = GST_BUFTYPE_FLOAT;
373
374     /* extract the needed information from the cap */
375     if (!(gst_structure_get_int (structure, "rate", &spec->rate) &&
376             gst_structure_get_int (structure, "channels", &spec->channels) &&
377             gst_structure_get_int (structure, "width", &spec->width)))
378       goto parse_error;
379
380     /* match layout to format wrt to endianness */
381     switch (spec->width) {
382       case 32:
383         spec->format =
384             G_BYTE_ORDER == G_LITTLE_ENDIAN ? GST_FLOAT32_LE : GST_FLOAT32_BE;
385         break;
386       case 64:
387         spec->format =
388             G_BYTE_ORDER == G_LITTLE_ENDIAN ? GST_FLOAT64_LE : GST_FLOAT64_BE;
389         break;
390       default:
391         goto parse_error;
392     }
393     /* float silence is all zeros.. */
394     memset (spec->silence_sample, 0, 32);
395   } else if (!strncmp (mimetype, "audio/x-alaw", 12)) {
396     /* extract the needed information from the cap */
397     if (!(gst_structure_get_int (structure, "rate", &spec->rate) &&
398             gst_structure_get_int (structure, "channels", &spec->channels)))
399       goto parse_error;
400
401     spec->type = GST_BUFTYPE_A_LAW;
402     spec->format = GST_A_LAW;
403     spec->width = 8;
404     spec->depth = 8;
405     for (i = 0; i < spec->channels; i++)
406       spec->silence_sample[i] = 0xd5;
407   } else if (!strncmp (mimetype, "audio/x-mulaw", 13)) {
408     /* extract the needed information from the cap */
409     if (!(gst_structure_get_int (structure, "rate", &spec->rate) &&
410             gst_structure_get_int (structure, "channels", &spec->channels)))
411       goto parse_error;
412
413     spec->type = GST_BUFTYPE_MU_LAW;
414     spec->format = GST_MU_LAW;
415     spec->width = 8;
416     spec->depth = 8;
417     for (i = 0; i < spec->channels; i++)
418       spec->silence_sample[i] = 0xff;
419   } else if (!strncmp (mimetype, "audio/x-iec958", 14)) {
420     /* extract the needed information from the cap */
421     if (!(gst_structure_get_int (structure, "rate", &spec->rate)))
422       goto parse_error;
423
424     spec->type = GST_BUFTYPE_IEC958;
425     spec->format = GST_IEC958;
426     spec->width = 16;
427     spec->depth = 16;
428     spec->channels = 2;
429   } else if (!strncmp (mimetype, "audio/x-ac3", 11)) {
430     /* extract the needed information from the cap */
431     if (!(gst_structure_get_int (structure, "rate", &spec->rate)))
432       goto parse_error;
433
434     spec->type = GST_BUFTYPE_AC3;
435     spec->format = GST_AC3;
436     spec->width = 16;
437     spec->depth = 16;
438     spec->channels = 2;
439   } else {
440     goto parse_error;
441   }
442
443   spec->bytes_per_sample = (spec->width >> 3) * spec->channels;
444
445   gst_caps_replace (&spec->caps, caps);
446
447   g_return_val_if_fail (spec->latency_time != 0, FALSE);
448
449   /* calculate suggested segsize and segtotal. segsize should be one unit
450    * of 'latency_time' samples, scaling for the fact that latency_time is
451    * currently stored in microseconds (FIXME: in 0.11) */
452   spec->segsize = gst_util_uint64_scale (spec->rate * spec->bytes_per_sample,
453       spec->latency_time, GST_SECOND / GST_USECOND);
454   /* Round to an integer number of samples */
455   spec->segsize -= spec->segsize % spec->bytes_per_sample;
456
457   spec->segtotal = spec->buffer_time / spec->latency_time;
458   /* leave the latency undefined now, implementations can change it but if it's
459    * not changed, we assume the same value as segtotal */
460   spec->seglatency = -1;
461
462   gst_ring_buffer_debug_spec_caps (spec);
463   gst_ring_buffer_debug_spec_buff (spec);
464
465   return TRUE;
466
467   /* ERRORS */
468 parse_error:
469   {
470     GST_DEBUG ("could not parse caps");
471     return FALSE;
472   }
473 }
474
475 /**
476  * gst_ring_buffer_convert:
477  * @buf: the #GstRingBuffer
478  * @src_fmt: the source format
479  * @src_val: the source value
480  * @dest_fmt: the destination format
481  * @dest_val: a location to store the converted value
482  *
483  * Convert @src_val in @src_fmt to the equivalent value in @dest_fmt. The result
484  * will be put in @dest_val.
485  *
486  * Returns: TRUE if the conversion succeeded.
487  *
488  * Since: 0.10.22.
489  */
490 gboolean
491 gst_ring_buffer_convert (GstRingBuffer * buf,
492     GstFormat src_fmt, gint64 src_val, GstFormat dest_fmt, gint64 * dest_val)
493 {
494   gboolean res = TRUE;
495   gint bps, rate;
496
497   GST_DEBUG ("converting value %" G_GINT64_FORMAT " from %s (%d) to %s (%d)",
498       src_val, gst_format_get_name (src_fmt), src_fmt,
499       gst_format_get_name (dest_fmt), dest_fmt);
500
501   if (src_fmt == dest_fmt || src_val == -1) {
502     *dest_val = src_val;
503     goto done;
504   }
505
506   /* get important info */
507   GST_OBJECT_LOCK (buf);
508   bps = buf->spec.bytes_per_sample;
509   rate = buf->spec.rate;
510   GST_OBJECT_UNLOCK (buf);
511
512   if (bps == 0 || rate == 0) {
513     GST_DEBUG ("no rate or bps configured");
514     res = FALSE;
515     goto done;
516   }
517
518   switch (src_fmt) {
519     case GST_FORMAT_BYTES:
520       switch (dest_fmt) {
521         case GST_FORMAT_TIME:
522           *dest_val = gst_util_uint64_scale_int (src_val / bps, GST_SECOND,
523               rate);
524           break;
525         case GST_FORMAT_DEFAULT:
526           *dest_val = src_val / bps;
527           break;
528         default:
529           res = FALSE;
530           break;
531       }
532       break;
533     case GST_FORMAT_DEFAULT:
534       switch (dest_fmt) {
535         case GST_FORMAT_TIME:
536           *dest_val = gst_util_uint64_scale_int (src_val, GST_SECOND, rate);
537           break;
538         case GST_FORMAT_BYTES:
539           *dest_val = src_val * bps;
540           break;
541         default:
542           res = FALSE;
543           break;
544       }
545       break;
546     case GST_FORMAT_TIME:
547       switch (dest_fmt) {
548         case GST_FORMAT_DEFAULT:
549           *dest_val = gst_util_uint64_scale_int (src_val, rate, GST_SECOND);
550           break;
551         case GST_FORMAT_BYTES:
552           *dest_val = gst_util_uint64_scale_int (src_val, rate, GST_SECOND);
553           *dest_val *= bps;
554           break;
555         default:
556           res = FALSE;
557           break;
558       }
559       break;
560     default:
561       res = FALSE;
562       break;
563   }
564 done:
565   GST_DEBUG ("ret=%d result %" G_GINT64_FORMAT, res, *dest_val);
566
567   return res;
568 }
569
570 /**
571  * gst_ring_buffer_set_callback:
572  * @buf: the #GstRingBuffer to set the callback on
573  * @cb: the callback to set
574  * @user_data: user data passed to the callback
575  *
576  * Sets the given callback function on the buffer. This function
577  * will be called every time a segment has been written to a device.
578  *
579  * MT safe.
580  */
581 void
582 gst_ring_buffer_set_callback (GstRingBuffer * buf, GstRingBufferCallback cb,
583     gpointer user_data)
584 {
585   g_return_if_fail (GST_IS_RING_BUFFER (buf));
586
587   GST_OBJECT_LOCK (buf);
588   buf->callback = cb;
589   buf->cb_data = user_data;
590   GST_OBJECT_UNLOCK (buf);
591 }
592
593
594 /**
595  * gst_ring_buffer_open_device:
596  * @buf: the #GstRingBuffer
597  *
598  * Open the audio device associated with the ring buffer. Does not perform any
599  * setup on the device. You must open the device before acquiring the ring
600  * buffer.
601  *
602  * Returns: TRUE if the device could be opened, FALSE on error.
603  *
604  * MT safe.
605  */
606 gboolean
607 gst_ring_buffer_open_device (GstRingBuffer * buf)
608 {
609   gboolean res = TRUE;
610   GstRingBufferClass *rclass;
611
612   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
613
614   GST_DEBUG_OBJECT (buf, "opening device");
615
616   GST_OBJECT_LOCK (buf);
617   if (G_UNLIKELY (buf->open))
618     goto was_opened;
619
620   buf->open = TRUE;
621
622   /* if this fails, something is wrong in this file */
623   g_assert (!buf->acquired);
624
625   rclass = GST_RING_BUFFER_GET_CLASS (buf);
626   if (G_LIKELY (rclass->open_device))
627     res = rclass->open_device (buf);
628
629   if (G_UNLIKELY (!res))
630     goto open_failed;
631
632   GST_DEBUG_OBJECT (buf, "opened device");
633
634 done:
635   GST_OBJECT_UNLOCK (buf);
636
637   return res;
638
639   /* ERRORS */
640 was_opened:
641   {
642     GST_DEBUG_OBJECT (buf, "Device for ring buffer already open");
643     g_warning ("Device for ring buffer %p already open, fix your code", buf);
644     res = TRUE;
645     goto done;
646   }
647 open_failed:
648   {
649     buf->open = FALSE;
650     GST_DEBUG_OBJECT (buf, "failed opening device");
651     goto done;
652   }
653 }
654
655 /**
656  * gst_ring_buffer_close_device:
657  * @buf: the #GstRingBuffer
658  *
659  * Close the audio device associated with the ring buffer. The ring buffer
660  * should already have been released via gst_ring_buffer_release().
661  *
662  * Returns: TRUE if the device could be closed, FALSE on error.
663  *
664  * MT safe.
665  */
666 gboolean
667 gst_ring_buffer_close_device (GstRingBuffer * buf)
668 {
669   gboolean res = TRUE;
670   GstRingBufferClass *rclass;
671
672   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
673
674   GST_DEBUG_OBJECT (buf, "closing device");
675
676   GST_OBJECT_LOCK (buf);
677   if (G_UNLIKELY (!buf->open))
678     goto was_closed;
679
680   if (G_UNLIKELY (buf->acquired))
681     goto was_acquired;
682
683   buf->open = FALSE;
684
685   rclass = GST_RING_BUFFER_GET_CLASS (buf);
686   if (G_LIKELY (rclass->close_device))
687     res = rclass->close_device (buf);
688
689   if (G_UNLIKELY (!res))
690     goto close_error;
691
692   GST_DEBUG_OBJECT (buf, "closed device");
693
694 done:
695   GST_OBJECT_UNLOCK (buf);
696
697   return res;
698
699   /* ERRORS */
700 was_closed:
701   {
702     GST_DEBUG_OBJECT (buf, "Device for ring buffer already closed");
703     g_warning ("Device for ring buffer %p already closed, fix your code", buf);
704     res = TRUE;
705     goto done;
706   }
707 was_acquired:
708   {
709     GST_DEBUG_OBJECT (buf, "Resources for ring buffer still acquired");
710     g_critical ("Resources for ring buffer %p still acquired", buf);
711     res = FALSE;
712     goto done;
713   }
714 close_error:
715   {
716     buf->open = TRUE;
717     GST_DEBUG_OBJECT (buf, "error closing device");
718     goto done;
719   }
720 }
721
722 /**
723  * gst_ring_buffer_device_is_open:
724  * @buf: the #GstRingBuffer
725  *
726  * Checks the status of the device associated with the ring buffer.
727  *
728  * Returns: TRUE if the device was open, FALSE if it was closed.
729  *
730  * MT safe.
731  */
732 gboolean
733 gst_ring_buffer_device_is_open (GstRingBuffer * buf)
734 {
735   gboolean res = TRUE;
736
737   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
738
739   GST_OBJECT_LOCK (buf);
740   res = buf->open;
741   GST_OBJECT_UNLOCK (buf);
742
743   return res;
744 }
745
746 /**
747  * gst_ring_buffer_acquire:
748  * @buf: the #GstRingBuffer to acquire
749  * @spec: the specs of the buffer
750  *
751  * Allocate the resources for the ringbuffer. This function fills
752  * in the data pointer of the ring buffer with a valid #GstBuffer
753  * to which samples can be written.
754  *
755  * Returns: TRUE if the device could be acquired, FALSE on error.
756  *
757  * MT safe.
758  */
759 gboolean
760 gst_ring_buffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
761 {
762   gboolean res = FALSE;
763   GstRingBufferClass *rclass;
764   gint i, j;
765   gint segsize, bps;
766
767   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
768
769   GST_DEBUG_OBJECT (buf, "acquiring device %p", buf);
770
771   GST_OBJECT_LOCK (buf);
772   if (G_UNLIKELY (!buf->open))
773     goto not_opened;
774
775   if (G_UNLIKELY (buf->acquired))
776     goto was_acquired;
777
778   buf->acquired = TRUE;
779
780   rclass = GST_RING_BUFFER_GET_CLASS (buf);
781   if (G_LIKELY (rclass->acquire))
782     res = rclass->acquire (buf, spec);
783
784   if (G_UNLIKELY (!res))
785     goto acquire_failed;
786
787   if (G_UNLIKELY ((bps = buf->spec.bytes_per_sample) == 0))
788     goto invalid_bps;
789
790   /* if the seglatency was overwritten with something else than -1, use it, else
791    * assume segtotal as the latency */
792   if (buf->spec.seglatency == -1)
793     buf->spec.seglatency = buf->spec.segtotal;
794
795   segsize = buf->spec.segsize;
796
797   buf->samples_per_seg = segsize / bps;
798
799   /* create an empty segment */
800   g_free (buf->empty_seg);
801   buf->empty_seg = g_malloc (segsize);
802
803   /* FIXME, we only have 32 silence samples, which might not be enough to
804    * represent silence in all channels */
805   bps = MIN (bps, 32);
806   for (i = 0, j = 0; i < segsize; i++) {
807     buf->empty_seg[i] = buf->spec.silence_sample[j];
808     j = (j + 1) % bps;
809   }
810   GST_DEBUG_OBJECT (buf, "acquired device");
811
812 done:
813   GST_OBJECT_UNLOCK (buf);
814
815   return res;
816
817   /* ERRORS */
818 not_opened:
819   {
820     GST_DEBUG_OBJECT (buf, "device not opened");
821     g_critical ("Device for %p not opened", buf);
822     res = FALSE;
823     goto done;
824   }
825 was_acquired:
826   {
827     res = TRUE;
828     GST_DEBUG_OBJECT (buf, "device was acquired");
829     goto done;
830   }
831 acquire_failed:
832   {
833     buf->acquired = FALSE;
834     GST_DEBUG_OBJECT (buf, "failed to acquire device");
835     goto done;
836   }
837 invalid_bps:
838   {
839     g_warning
840         ("invalid bytes_per_sample from acquire ringbuffer %p, fix the element",
841         buf);
842     buf->acquired = FALSE;
843     res = FALSE;
844     goto done;
845   }
846 }
847
848 /**
849  * gst_ring_buffer_release:
850  * @buf: the #GstRingBuffer to release
851  *
852  * Free the resources of the ringbuffer.
853  *
854  * Returns: TRUE if the device could be released, FALSE on error.
855  *
856  * MT safe.
857  */
858 gboolean
859 gst_ring_buffer_release (GstRingBuffer * buf)
860 {
861   gboolean res = FALSE;
862   GstRingBufferClass *rclass;
863
864   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
865
866   GST_DEBUG_OBJECT (buf, "releasing device");
867
868   gst_ring_buffer_stop (buf);
869
870   GST_OBJECT_LOCK (buf);
871   if (G_UNLIKELY (!buf->acquired))
872     goto was_released;
873
874   buf->acquired = FALSE;
875
876   /* if this fails, something is wrong in this file */
877   g_assert (buf->open == TRUE);
878
879   rclass = GST_RING_BUFFER_GET_CLASS (buf);
880   if (G_LIKELY (rclass->release))
881     res = rclass->release (buf);
882
883   /* signal any waiters */
884   GST_DEBUG_OBJECT (buf, "signal waiter");
885   GST_RING_BUFFER_SIGNAL (buf);
886
887   if (G_UNLIKELY (!res))
888     goto release_failed;
889
890   g_free (buf->empty_seg);
891   buf->empty_seg = NULL;
892   GST_DEBUG_OBJECT (buf, "released device");
893
894 done:
895   GST_OBJECT_UNLOCK (buf);
896
897   return res;
898
899   /* ERRORS */
900 was_released:
901   {
902     res = TRUE;
903     GST_DEBUG_OBJECT (buf, "device was released");
904     goto done;
905   }
906 release_failed:
907   {
908     buf->acquired = TRUE;
909     GST_DEBUG_OBJECT (buf, "failed to release device");
910     goto done;
911   }
912 }
913
914 /**
915  * gst_ring_buffer_is_acquired:
916  * @buf: the #GstRingBuffer to check
917  *
918  * Check if the ringbuffer is acquired and ready to use.
919  *
920  * Returns: TRUE if the ringbuffer is acquired, FALSE on error.
921  *
922  * MT safe.
923  */
924 gboolean
925 gst_ring_buffer_is_acquired (GstRingBuffer * buf)
926 {
927   gboolean res;
928
929   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
930
931   GST_OBJECT_LOCK (buf);
932   res = buf->acquired;
933   GST_OBJECT_UNLOCK (buf);
934
935   return res;
936 }
937
938 /**
939  * gst_ring_buffer_activate:
940  * @buf: the #GstRingBuffer to activate
941  * @active: the new mode
942  *
943  * Activate @buf to start or stop pulling data.
944  *
945  * MT safe.
946  *
947  * Returns: TRUE if the device could be activated in the requested mode,
948  * FALSE on error.
949  *
950  * Since: 0.10.22.
951  */
952 gboolean
953 gst_ring_buffer_activate (GstRingBuffer * buf, gboolean active)
954 {
955   gboolean res = FALSE;
956   GstRingBufferClass *rclass;
957
958   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
959
960   GST_DEBUG_OBJECT (buf, "activate device");
961
962   GST_OBJECT_LOCK (buf);
963   if (G_UNLIKELY (active && !buf->acquired))
964     goto not_acquired;
965
966   if (G_UNLIKELY (buf->abidata.ABI.active == active))
967     goto was_active;
968
969   rclass = GST_RING_BUFFER_GET_CLASS (buf);
970   /* if there is no activate function we assume it was started/released
971    * in the acquire method */
972   if (G_LIKELY (rclass->activate))
973     res = rclass->activate (buf, active);
974   else
975     res = TRUE;
976
977   if (G_UNLIKELY (!res))
978     goto activate_failed;
979
980   buf->abidata.ABI.active = active;
981
982 done:
983   GST_OBJECT_UNLOCK (buf);
984
985   return res;
986
987   /* ERRORS */
988 not_acquired:
989   {
990     GST_DEBUG_OBJECT (buf, "device not acquired");
991     g_critical ("Device for %p not acquired", buf);
992     res = FALSE;
993     goto done;
994   }
995 was_active:
996   {
997     res = TRUE;
998     GST_DEBUG_OBJECT (buf, "device was active in mode %d", active);
999     goto done;
1000   }
1001 activate_failed:
1002   {
1003     GST_DEBUG_OBJECT (buf, "failed to activate device");
1004     goto done;
1005   }
1006 }
1007
1008 /**
1009  * gst_ring_buffer_is_active:
1010  * @buf: the #GstRingBuffer
1011  *
1012  * Check if @buf is activated.
1013  *
1014  * MT safe.
1015  *
1016  * Returns: TRUE if the device is active.
1017  *
1018  * Since: 0.10.22.
1019  */
1020 gboolean
1021 gst_ring_buffer_is_active (GstRingBuffer * buf)
1022 {
1023   gboolean res;
1024
1025   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
1026
1027   GST_OBJECT_LOCK (buf);
1028   res = buf->abidata.ABI.active;
1029   GST_OBJECT_UNLOCK (buf);
1030
1031   return res;
1032 }
1033
1034
1035 /**
1036  * gst_ring_buffer_set_flushing:
1037  * @buf: the #GstRingBuffer to flush
1038  * @flushing: the new mode
1039  *
1040  * Set the ringbuffer to flushing mode or normal mode.
1041  *
1042  * MT safe.
1043  */
1044 void
1045 gst_ring_buffer_set_flushing (GstRingBuffer * buf, gboolean flushing)
1046 {
1047   g_return_if_fail (GST_IS_RING_BUFFER (buf));
1048
1049   GST_OBJECT_LOCK (buf);
1050   buf->abidata.ABI.flushing = flushing;
1051
1052   if (flushing) {
1053     gst_ring_buffer_pause_unlocked (buf);
1054   } else {
1055     gst_ring_buffer_clear_all (buf);
1056   }
1057   GST_OBJECT_UNLOCK (buf);
1058 }
1059
1060 /**
1061  * gst_ring_buffer_start:
1062  * @buf: the #GstRingBuffer to start
1063  *
1064  * Start processing samples from the ringbuffer.
1065  *
1066  * Returns: TRUE if the device could be started, FALSE on error.
1067  *
1068  * MT safe.
1069  */
1070 gboolean
1071 gst_ring_buffer_start (GstRingBuffer * buf)
1072 {
1073   gboolean res = FALSE;
1074   GstRingBufferClass *rclass;
1075   gboolean resume = FALSE;
1076
1077   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
1078
1079   GST_DEBUG_OBJECT (buf, "starting ringbuffer");
1080
1081   GST_OBJECT_LOCK (buf);
1082   if (G_UNLIKELY (buf->abidata.ABI.flushing))
1083     goto flushing;
1084
1085   if (G_UNLIKELY (!buf->acquired))
1086     goto not_acquired;
1087
1088   if (G_UNLIKELY (g_atomic_int_get (&buf->abidata.ABI.may_start) == FALSE))
1089     goto may_not_start;
1090
1091   /* if stopped, set to started */
1092   res = g_atomic_int_compare_and_exchange (&buf->state,
1093       GST_RING_BUFFER_STATE_STOPPED, GST_RING_BUFFER_STATE_STARTED);
1094
1095   if (!res) {
1096     GST_DEBUG_OBJECT (buf, "was not stopped, try paused");
1097     /* was not stopped, try from paused */
1098     res = g_atomic_int_compare_and_exchange (&buf->state,
1099         GST_RING_BUFFER_STATE_PAUSED, GST_RING_BUFFER_STATE_STARTED);
1100     if (!res) {
1101       /* was not paused either, must be started then */
1102       res = TRUE;
1103       GST_DEBUG_OBJECT (buf, "was not paused, must have been started");
1104       goto done;
1105     }
1106     resume = TRUE;
1107     GST_DEBUG_OBJECT (buf, "resuming");
1108   }
1109
1110   rclass = GST_RING_BUFFER_GET_CLASS (buf);
1111   if (resume) {
1112     if (G_LIKELY (rclass->resume))
1113       res = rclass->resume (buf);
1114   } else {
1115     if (G_LIKELY (rclass->start))
1116       res = rclass->start (buf);
1117   }
1118
1119   if (G_UNLIKELY (!res)) {
1120     buf->state = GST_RING_BUFFER_STATE_PAUSED;
1121     GST_DEBUG_OBJECT (buf, "failed to start");
1122   } else {
1123     GST_DEBUG_OBJECT (buf, "started");
1124   }
1125
1126 done:
1127   GST_OBJECT_UNLOCK (buf);
1128
1129   return res;
1130
1131 flushing:
1132   {
1133     GST_DEBUG_OBJECT (buf, "we are flushing");
1134     GST_OBJECT_UNLOCK (buf);
1135     return FALSE;
1136   }
1137 not_acquired:
1138   {
1139     GST_DEBUG_OBJECT (buf, "we are not acquired");
1140     GST_OBJECT_UNLOCK (buf);
1141     return FALSE;
1142   }
1143 may_not_start:
1144   {
1145     GST_DEBUG_OBJECT (buf, "we may not start");
1146     GST_OBJECT_UNLOCK (buf);
1147     return FALSE;
1148   }
1149 }
1150
1151 static gboolean
1152 gst_ring_buffer_pause_unlocked (GstRingBuffer * buf)
1153 {
1154   gboolean res = FALSE;
1155   GstRingBufferClass *rclass;
1156
1157   GST_DEBUG_OBJECT (buf, "pausing ringbuffer");
1158
1159   /* if started, set to paused */
1160   res = g_atomic_int_compare_and_exchange (&buf->state,
1161       GST_RING_BUFFER_STATE_STARTED, GST_RING_BUFFER_STATE_PAUSED);
1162
1163   if (!res)
1164     goto not_started;
1165
1166   /* signal any waiters */
1167   GST_DEBUG_OBJECT (buf, "signal waiter");
1168   GST_RING_BUFFER_SIGNAL (buf);
1169
1170   rclass = GST_RING_BUFFER_GET_CLASS (buf);
1171   if (G_LIKELY (rclass->pause))
1172     res = rclass->pause (buf);
1173
1174   if (G_UNLIKELY (!res)) {
1175     buf->state = GST_RING_BUFFER_STATE_STARTED;
1176     GST_DEBUG_OBJECT (buf, "failed to pause");
1177   } else {
1178     GST_DEBUG_OBJECT (buf, "paused");
1179   }
1180
1181   return res;
1182
1183 not_started:
1184   {
1185     /* was not started */
1186     GST_DEBUG_OBJECT (buf, "was not started");
1187     return TRUE;
1188   }
1189 }
1190
1191 /**
1192  * gst_ring_buffer_pause:
1193  * @buf: the #GstRingBuffer to pause
1194  *
1195  * Pause processing samples from the ringbuffer.
1196  *
1197  * Returns: TRUE if the device could be paused, FALSE on error.
1198  *
1199  * MT safe.
1200  */
1201 gboolean
1202 gst_ring_buffer_pause (GstRingBuffer * buf)
1203 {
1204   gboolean res = FALSE;
1205
1206   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
1207
1208   GST_OBJECT_LOCK (buf);
1209   if (G_UNLIKELY (buf->abidata.ABI.flushing))
1210     goto flushing;
1211
1212   if (G_UNLIKELY (!buf->acquired))
1213     goto not_acquired;
1214
1215   res = gst_ring_buffer_pause_unlocked (buf);
1216   GST_OBJECT_UNLOCK (buf);
1217
1218   return res;
1219
1220   /* ERRORS */
1221 flushing:
1222   {
1223     GST_DEBUG_OBJECT (buf, "we are flushing");
1224     GST_OBJECT_UNLOCK (buf);
1225     return FALSE;
1226   }
1227 not_acquired:
1228   {
1229     GST_DEBUG_OBJECT (buf, "not acquired");
1230     GST_OBJECT_UNLOCK (buf);
1231     return FALSE;
1232   }
1233 }
1234
1235 /**
1236  * gst_ring_buffer_stop:
1237  * @buf: the #GstRingBuffer to stop
1238  *
1239  * Stop processing samples from the ringbuffer.
1240  *
1241  * Returns: TRUE if the device could be stopped, FALSE on error.
1242  *
1243  * MT safe.
1244  */
1245 gboolean
1246 gst_ring_buffer_stop (GstRingBuffer * buf)
1247 {
1248   gboolean res = FALSE;
1249   GstRingBufferClass *rclass;
1250
1251   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
1252
1253   GST_DEBUG_OBJECT (buf, "stopping");
1254
1255   GST_OBJECT_LOCK (buf);
1256
1257   /* if started, set to stopped */
1258   res = g_atomic_int_compare_and_exchange (&buf->state,
1259       GST_RING_BUFFER_STATE_STARTED, GST_RING_BUFFER_STATE_STOPPED);
1260
1261   if (!res) {
1262     GST_DEBUG_OBJECT (buf, "was not started, try paused");
1263     /* was not started, try from paused */
1264     res = g_atomic_int_compare_and_exchange (&buf->state,
1265         GST_RING_BUFFER_STATE_PAUSED, GST_RING_BUFFER_STATE_STOPPED);
1266     if (!res) {
1267       /* was not paused either, must have been stopped then */
1268       res = TRUE;
1269       GST_DEBUG_OBJECT (buf, "was not paused, must have been stopped");
1270       goto done;
1271     }
1272   }
1273
1274   /* signal any waiters */
1275   GST_DEBUG_OBJECT (buf, "signal waiter");
1276   GST_RING_BUFFER_SIGNAL (buf);
1277
1278   rclass = GST_RING_BUFFER_GET_CLASS (buf);
1279   if (G_LIKELY (rclass->stop))
1280     res = rclass->stop (buf);
1281
1282   if (G_UNLIKELY (!res)) {
1283     buf->state = GST_RING_BUFFER_STATE_STARTED;
1284     GST_DEBUG_OBJECT (buf, "failed to stop");
1285   } else {
1286     GST_DEBUG_OBJECT (buf, "stopped");
1287   }
1288 done:
1289   GST_OBJECT_UNLOCK (buf);
1290
1291   return res;
1292 }
1293
1294 /**
1295  * gst_ring_buffer_delay:
1296  * @buf: the #GstRingBuffer to query
1297  *
1298  * Get the number of samples queued in the audio device. This is
1299  * usually less than the segment size but can be bigger when the
1300  * implementation uses another internal buffer between the audio
1301  * device.
1302  *
1303  * For playback ringbuffers this is the amount of samples transfered from the
1304  * ringbuffer to the device but still not played.
1305  *
1306  * For capture ringbuffers this is the amount of samples in the device that are
1307  * not yet transfered to the ringbuffer.
1308  *
1309  * Returns: The number of samples queued in the audio device.
1310  *
1311  * MT safe.
1312  */
1313 guint
1314 gst_ring_buffer_delay (GstRingBuffer * buf)
1315 {
1316   GstRingBufferClass *rclass;
1317   guint res;
1318
1319   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), 0);
1320
1321   /* buffer must be acquired */
1322   if (G_UNLIKELY (!gst_ring_buffer_is_acquired (buf)))
1323     goto not_acquired;
1324
1325   rclass = GST_RING_BUFFER_GET_CLASS (buf);
1326   if (G_LIKELY (rclass->delay))
1327     res = rclass->delay (buf);
1328   else
1329     res = 0;
1330
1331   return res;
1332
1333 not_acquired:
1334   {
1335     GST_DEBUG_OBJECT (buf, "not acquired");
1336     return 0;
1337   }
1338 }
1339
1340 /**
1341  * gst_ring_buffer_samples_done:
1342  * @buf: the #GstRingBuffer to query
1343  *
1344  * Get the number of samples that were processed by the ringbuffer
1345  * since it was last started. This does not include the number of samples not
1346  * yet processed (see gst_ring_buffer_delay()).
1347  *
1348  * Returns: The number of samples processed by the ringbuffer.
1349  *
1350  * MT safe.
1351  */
1352 guint64
1353 gst_ring_buffer_samples_done (GstRingBuffer * buf)
1354 {
1355   gint segdone;
1356   guint64 samples;
1357
1358   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), 0);
1359
1360   /* get the amount of segments we processed */
1361   segdone = g_atomic_int_get (&buf->segdone);
1362
1363   /* convert to samples */
1364   samples = ((guint64) segdone) * buf->samples_per_seg;
1365
1366   return samples;
1367 }
1368
1369 /**
1370  * gst_ring_buffer_set_sample:
1371  * @buf: the #GstRingBuffer to use
1372  * @sample: the sample number to set
1373  *
1374  * Make sure that the next sample written to the device is
1375  * accounted for as being the @sample sample written to the
1376  * device. This value will be used in reporting the current
1377  * sample position of the ringbuffer.
1378  *
1379  * This function will also clear the buffer with silence.
1380  *
1381  * MT safe.
1382  */
1383 void
1384 gst_ring_buffer_set_sample (GstRingBuffer * buf, guint64 sample)
1385 {
1386   g_return_if_fail (GST_IS_RING_BUFFER (buf));
1387
1388   if (sample == -1)
1389     sample = 0;
1390
1391   if (G_UNLIKELY (buf->samples_per_seg == 0))
1392     return;
1393
1394   /* FIXME, we assume the ringbuffer can restart at a random 
1395    * position, round down to the beginning and keep track of
1396    * offset when calculating the processed samples. */
1397   buf->segbase = buf->segdone - sample / buf->samples_per_seg;
1398
1399   gst_ring_buffer_clear_all (buf);
1400
1401   GST_DEBUG_OBJECT (buf, "set sample to %" G_GUINT64_FORMAT ", segbase %d",
1402       sample, buf->segbase);
1403 }
1404
1405 static void
1406 default_clear_all (GstRingBuffer * buf)
1407 {
1408   gint i;
1409
1410   /* not fatal, we just are not negotiated yet */
1411   if (G_UNLIKELY (buf->spec.segtotal <= 0))
1412     return;
1413
1414   GST_DEBUG_OBJECT (buf, "clear all segments");
1415
1416   for (i = 0; i < buf->spec.segtotal; i++) {
1417     gst_ring_buffer_clear (buf, i);
1418   }
1419 }
1420
1421 /**
1422  * gst_ring_buffer_clear_all:
1423  * @buf: the #GstRingBuffer to clear
1424  *
1425  * Fill the ringbuffer with silence.
1426  *
1427  * MT safe.
1428  */
1429 void
1430 gst_ring_buffer_clear_all (GstRingBuffer * buf)
1431 {
1432   GstRingBufferClass *rclass;
1433
1434   g_return_if_fail (GST_IS_RING_BUFFER (buf));
1435
1436   rclass = GST_RING_BUFFER_GET_CLASS (buf);
1437
1438   if (G_LIKELY (rclass->clear_all))
1439     rclass->clear_all (buf);
1440 }
1441
1442
1443 static gboolean
1444 wait_segment (GstRingBuffer * buf)
1445 {
1446   gint segments;
1447   gboolean wait = TRUE;
1448
1449   /* buffer must be started now or we deadlock since nobody is reading */
1450   if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1451           GST_RING_BUFFER_STATE_STARTED)) {
1452     /* see if we are allowed to start it */
1453     if (G_UNLIKELY (g_atomic_int_get (&buf->abidata.ABI.may_start) == FALSE))
1454       goto no_start;
1455
1456     GST_DEBUG_OBJECT (buf, "start!");
1457     segments = g_atomic_int_get (&buf->segdone);
1458     gst_ring_buffer_start (buf);
1459
1460     /* After starting, the writer may have wrote segments already and then we
1461      * don't need to wait anymore */
1462     if (G_LIKELY (g_atomic_int_get (&buf->segdone) != segments))
1463       wait = FALSE;
1464   }
1465
1466   /* take lock first, then update our waiting flag */
1467   GST_OBJECT_LOCK (buf);
1468   if (G_UNLIKELY (buf->abidata.ABI.flushing))
1469     goto flushing;
1470
1471   if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1472           GST_RING_BUFFER_STATE_STARTED))
1473     goto not_started;
1474
1475   if (G_LIKELY (wait)) {
1476     if (g_atomic_int_compare_and_exchange (&buf->waiting, 0, 1)) {
1477       GST_DEBUG_OBJECT (buf, "waiting..");
1478       GST_RING_BUFFER_WAIT (buf);
1479
1480       if (G_UNLIKELY (buf->abidata.ABI.flushing))
1481         goto flushing;
1482
1483       if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1484               GST_RING_BUFFER_STATE_STARTED))
1485         goto not_started;
1486     }
1487   }
1488   GST_OBJECT_UNLOCK (buf);
1489
1490   return TRUE;
1491
1492   /* ERROR */
1493 not_started:
1494   {
1495     g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0);
1496     GST_DEBUG_OBJECT (buf, "stopped processing");
1497     GST_OBJECT_UNLOCK (buf);
1498     return FALSE;
1499   }
1500 flushing:
1501   {
1502     g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0);
1503     GST_DEBUG_OBJECT (buf, "flushing");
1504     GST_OBJECT_UNLOCK (buf);
1505     return FALSE;
1506   }
1507 no_start:
1508   {
1509     GST_DEBUG_OBJECT (buf, "not allowed to start");
1510     return FALSE;
1511   }
1512 }
1513
1514 #define FWD_SAMPLES(s,se,d,de)                  \
1515 G_STMT_START {                                  \
1516   /* no rate conversion */                      \
1517   guint towrite = MIN (se + bps - s, de - d);   \
1518   /* simple copy */                             \
1519   if (!skip)                                    \
1520     memcpy (d, s, towrite);                     \
1521   in_samples -= towrite / bps;                  \
1522   out_samples -= towrite / bps;                 \
1523   s += towrite;                                 \
1524   GST_DEBUG ("copy %u bytes", towrite);         \
1525 } G_STMT_END
1526
1527 /* in_samples >= out_samples, rate > 1.0 */
1528 #define FWD_UP_SAMPLES(s,se,d,de)               \
1529 G_STMT_START {                                  \
1530   guint8 *sb = s, *db = d;                      \
1531   while (s <= se && d < de) {                   \
1532     if (!skip)                                  \
1533       memcpy (d, s, bps);                       \
1534     s += bps;                                   \
1535     *accum += outr;                             \
1536     if ((*accum << 1) >= inr) {                 \
1537       *accum -= inr;                            \
1538       d += bps;                                 \
1539     }                                           \
1540   }                                             \
1541   in_samples -= (s - sb)/bps;                   \
1542   out_samples -= (d - db)/bps;                  \
1543   GST_DEBUG ("fwd_up end %d/%d",*accum,*toprocess);     \
1544 } G_STMT_END
1545
1546 /* out_samples > in_samples, for rates smaller than 1.0 */
1547 #define FWD_DOWN_SAMPLES(s,se,d,de)             \
1548 G_STMT_START {                                  \
1549   guint8 *sb = s, *db = d;                      \
1550   while (s <= se && d < de) {                   \
1551     if (!skip)                                  \
1552       memcpy (d, s, bps);                       \
1553     d += bps;                                   \
1554     *accum += inr;                              \
1555     if ((*accum << 1) >= outr) {                \
1556       *accum -= outr;                           \
1557       s += bps;                                 \
1558     }                                           \
1559   }                                             \
1560   in_samples -= (s - sb)/bps;                   \
1561   out_samples -= (d - db)/bps;                  \
1562   GST_DEBUG ("fwd_down end %d/%d",*accum,*toprocess);   \
1563 } G_STMT_END
1564
1565 #define REV_UP_SAMPLES(s,se,d,de)               \
1566 G_STMT_START {                                  \
1567   guint8 *sb = se, *db = d;                     \
1568   while (s <= se && d < de) {                   \
1569     if (!skip)                                  \
1570       memcpy (d, se, bps);                      \
1571     se -= bps;                                  \
1572     *accum += outr;                             \
1573     while (d < de && (*accum << 1) >= inr) {    \
1574       *accum -= inr;                            \
1575       d += bps;                                 \
1576     }                                           \
1577   }                                             \
1578   in_samples -= (sb - se)/bps;                  \
1579   out_samples -= (d - db)/bps;                  \
1580   GST_DEBUG ("rev_up end %d/%d",*accum,*toprocess);     \
1581 } G_STMT_END
1582
1583 #define REV_DOWN_SAMPLES(s,se,d,de)             \
1584 G_STMT_START {                                  \
1585   guint8 *sb = se, *db = d;                     \
1586   while (s <= se && d < de) {                   \
1587     if (!skip)                                  \
1588       memcpy (d, se, bps);                      \
1589     d += bps;                                   \
1590     *accum += inr;                              \
1591     while (s <= se && (*accum << 1) >= outr) {  \
1592       *accum -= outr;                           \
1593       se -= bps;                                \
1594     }                                           \
1595   }                                             \
1596   in_samples -= (sb - se)/bps;                  \
1597   out_samples -= (d - db)/bps;                  \
1598   GST_DEBUG ("rev_down end %d/%d",*accum,*toprocess);   \
1599 } G_STMT_END
1600
1601 static guint
1602 default_commit (GstRingBuffer * buf, guint64 * sample,
1603     guchar * data, gint in_samples, gint out_samples, gint * accum)
1604 {
1605   gint segdone;
1606   gint segsize, segtotal, bps, sps;
1607   guint8 *dest, *data_end;
1608   gint writeseg, sampleoff;
1609   gint *toprocess;
1610   gint inr, outr;
1611   gboolean reverse;
1612
1613   g_return_val_if_fail (buf->data != NULL, -1);
1614   g_return_val_if_fail (data != NULL, -1);
1615
1616   dest = GST_BUFFER_DATA (buf->data);
1617   segsize = buf->spec.segsize;
1618   segtotal = buf->spec.segtotal;
1619   bps = buf->spec.bytes_per_sample;
1620   sps = buf->samples_per_seg;
1621
1622   reverse = out_samples < 0;
1623   out_samples = ABS (out_samples);
1624
1625   if (in_samples >= out_samples)
1626     toprocess = &in_samples;
1627   else
1628     toprocess = &out_samples;
1629
1630   inr = in_samples - 1;
1631   outr = out_samples - 1;
1632
1633   /* data_end points to the last sample we have to write, not past it. This is
1634    * needed to properly handle reverse playback: it points to the last sample. */
1635   data_end = data + (bps * inr);
1636
1637   /* figure out the segment and the offset inside the segment where
1638    * the first sample should be written. */
1639   writeseg = *sample / sps;
1640   sampleoff = (*sample % sps) * bps;
1641
1642   /* write out all samples */
1643   while (*toprocess > 0) {
1644     gint avail;
1645     guint8 *d, *d_end;
1646     gint ws;
1647     gboolean skip;
1648
1649     while (TRUE) {
1650       gint diff;
1651
1652       /* get the currently processed segment */
1653       segdone = g_atomic_int_get (&buf->segdone) - buf->segbase;
1654
1655       /* see how far away it is from the write segment */
1656       diff = writeseg - segdone;
1657
1658       GST_DEBUG
1659           ("pointer at %d, write to %d-%d, diff %d, segtotal %d, segsize %d, base %d",
1660           segdone, writeseg, sampleoff, diff, segtotal, segsize, buf->segbase);
1661
1662       /* segment too far ahead, writer too slow, we need to drop, hopefully UNLIKELY */
1663       if (G_UNLIKELY (diff < 0)) {
1664         /* we need to drop one segment at a time, pretend we wrote a
1665          * segment. */
1666         skip = TRUE;
1667         break;
1668       }
1669
1670       /* write segment is within writable range, we can break the loop and
1671        * start writing the data. */
1672       if (diff < segtotal) {
1673         skip = FALSE;
1674         break;
1675       }
1676
1677       /* else we need to wait for the segment to become writable. */
1678       if (!wait_segment (buf))
1679         goto not_started;
1680     }
1681
1682     /* we can write now */
1683     ws = writeseg % segtotal;
1684     avail = MIN (segsize - sampleoff, bps * out_samples);
1685
1686     d = dest + (ws * segsize) + sampleoff;
1687     d_end = d + avail;
1688     *sample += avail / bps;
1689
1690     GST_DEBUG_OBJECT (buf, "write @%p seg %d, sps %d, off %d, avail %d",
1691         dest + ws * segsize, ws, sps, sampleoff, avail);
1692
1693     if (G_LIKELY (inr == outr && !reverse)) {
1694       /* no rate conversion, simply copy samples */
1695       FWD_SAMPLES (data, data_end, d, d_end);
1696     } else if (!reverse) {
1697       if (inr >= outr)
1698         /* forward speed up */
1699         FWD_UP_SAMPLES (data, data_end, d, d_end);
1700       else
1701         /* forward slow down */
1702         FWD_DOWN_SAMPLES (data, data_end, d, d_end);
1703     } else {
1704       if (inr >= outr)
1705         /* reverse speed up */
1706         REV_UP_SAMPLES (data, data_end, d, d_end);
1707       else
1708         /* reverse slow down */
1709         REV_DOWN_SAMPLES (data, data_end, d, d_end);
1710     }
1711
1712     /* for the next iteration we write to the next segment at the beginning. */
1713     writeseg++;
1714     sampleoff = 0;
1715   }
1716   /* we consumed all samples here */
1717   data = data_end + bps;
1718
1719 done:
1720   return inr - ((data_end - data) / bps);
1721
1722   /* ERRORS */
1723 not_started:
1724   {
1725     GST_DEBUG_OBJECT (buf, "stopped processing");
1726     goto done;
1727   }
1728 }
1729
1730 /**
1731  * gst_ring_buffer_commit_full:
1732  * @buf: the #GstRingBuffer to commit
1733  * @sample: the sample position of the data
1734  * @data: the data to commit
1735  * @in_samples: the number of samples in the data to commit
1736  * @out_samples: the number of samples to write to the ringbuffer
1737  * @accum: accumulator for rate conversion.
1738  *
1739  * Commit @in_samples samples pointed to by @data to the ringbuffer @buf. 
1740  *
1741  * @in_samples and @out_samples define the rate conversion to perform on the the
1742  * samples in @data. For negative rates, @out_samples must be negative and
1743  * @in_samples positive.
1744  *
1745  * When @out_samples is positive, the first sample will be written at position @sample
1746  * in the ringbuffer. When @out_samples is negative, the last sample will be written to
1747  * @sample in reverse order.
1748  *
1749  * @out_samples does not need to be a multiple of the segment size of the ringbuffer
1750  * although it is recommended for optimal performance. 
1751  *
1752  * @accum will hold a temporary accumulator used in rate conversion and should be
1753  * set to 0 when this function is first called. In case the commit operation is
1754  * interrupted, one can resume the processing by passing the previously returned
1755  * @accum value back to this function.
1756  *
1757  * MT safe.
1758  *
1759  * Returns: The number of samples written to the ringbuffer or -1 on error. The
1760  * number of samples written can be less than @out_samples when @buf was interrupted
1761  * with a flush or stop.
1762  *
1763  * Since: 0.10.11.
1764  */
1765 guint
1766 gst_ring_buffer_commit_full (GstRingBuffer * buf, guint64 * sample,
1767     guchar * data, gint in_samples, gint out_samples, gint * accum)
1768 {
1769   GstRingBufferClass *rclass;
1770   guint res = -1;
1771
1772   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), -1);
1773
1774   if (G_UNLIKELY (in_samples == 0 || out_samples == 0))
1775     return in_samples;
1776
1777   rclass = GST_RING_BUFFER_GET_CLASS (buf);
1778
1779   if (G_LIKELY (rclass->commit))
1780     res = rclass->commit (buf, sample, data, in_samples, out_samples, accum);
1781
1782   return res;
1783 }
1784
1785 /**
1786  * gst_ring_buffer_commit:
1787  * @buf: the #GstRingBuffer to commit
1788  * @sample: the sample position of the data
1789  * @data: the data to commit
1790  * @len: the number of samples in the data to commit
1791  *
1792  * Same as gst_ring_buffer_commit_full() but with a in_samples and out_samples
1793  * equal to @len, ignoring accum.
1794  *
1795  * Returns: The number of samples written to the ringbuffer or -1 on
1796  * error.
1797  *
1798  * MT safe.
1799  */
1800 guint
1801 gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
1802     guint len)
1803 {
1804   guint res;
1805   guint64 samplep = sample;
1806
1807   res = gst_ring_buffer_commit_full (buf, &samplep, data, len, len, NULL);
1808
1809   return res;
1810 }
1811
1812 /**
1813  * gst_ring_buffer_read:
1814  * @buf: the #GstRingBuffer to read from
1815  * @sample: the sample position of the data
1816  * @data: where the data should be read
1817  * @len: the number of samples in data to read
1818  *
1819  * Read @len samples from the ringbuffer into the memory pointed 
1820  * to by @data.
1821  * The first sample should be read from position @sample in
1822  * the ringbuffer.
1823  *
1824  * @len should not be a multiple of the segment size of the ringbuffer
1825  * although it is recommended.
1826  *
1827  * Returns: The number of samples read from the ringbuffer or -1 on
1828  * error.
1829  *
1830  * MT safe.
1831  */
1832 guint
1833 gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data,
1834     guint len)
1835 {
1836   gint segdone;
1837   gint segsize, segtotal, bps, sps;
1838   guint8 *dest;
1839   guint to_read;
1840
1841   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), -1);
1842   g_return_val_if_fail (buf->data != NULL, -1);
1843   g_return_val_if_fail (data != NULL, -1);
1844
1845   dest = GST_BUFFER_DATA (buf->data);
1846   segsize = buf->spec.segsize;
1847   segtotal = buf->spec.segtotal;
1848   bps = buf->spec.bytes_per_sample;
1849   sps = buf->samples_per_seg;
1850
1851   to_read = len;
1852   /* read enough samples */
1853   while (to_read > 0) {
1854     gint sampleslen;
1855     gint readseg, sampleoff;
1856
1857     /* figure out the segment and the offset inside the segment where
1858      * the sample should be read from. */
1859     readseg = sample / sps;
1860     sampleoff = (sample % sps);
1861
1862     while (TRUE) {
1863       gint diff;
1864
1865       /* get the currently processed segment */
1866       segdone = g_atomic_int_get (&buf->segdone) - buf->segbase;
1867
1868       /* see how far away it is from the read segment, normally segdone (where
1869        * the hardware is writing) is bigger than readseg (where software is
1870        * reading) */
1871       diff = segdone - readseg;
1872
1873       GST_DEBUG
1874           ("pointer at %d, sample %" G_GUINT64_FORMAT
1875           ", read from %d-%d, to_read %d, diff %d, segtotal %d, segsize %d",
1876           segdone, sample, readseg, sampleoff, to_read, diff, segtotal,
1877           segsize);
1878
1879       /* segment too far ahead, reader too slow */
1880       if (G_UNLIKELY (diff >= segtotal)) {
1881         /* pretend we read an empty segment. */
1882         sampleslen = MIN (sps, to_read);
1883         memcpy (data, buf->empty_seg, sampleslen * bps);
1884         goto next;
1885       }
1886
1887       /* read segment is within readable range, we can break the loop and
1888        * start reading the data. */
1889       if (diff > 0)
1890         break;
1891
1892       /* else we need to wait for the segment to become readable. */
1893       if (!wait_segment (buf))
1894         goto not_started;
1895     }
1896
1897     /* we can read now */
1898     readseg = readseg % segtotal;
1899     sampleslen = MIN (sps - sampleoff, to_read);
1900
1901     GST_DEBUG_OBJECT (buf, "read @%p seg %d, off %d, sampleslen %d",
1902         dest + readseg * segsize, readseg, sampleoff, sampleslen);
1903
1904     memcpy (data, dest + (readseg * segsize) + (sampleoff * bps),
1905         (sampleslen * bps));
1906
1907   next:
1908     to_read -= sampleslen;
1909     sample += sampleslen;
1910     data += sampleslen * bps;
1911   }
1912
1913   return len - to_read;
1914
1915   /* ERRORS */
1916 not_started:
1917   {
1918     GST_DEBUG_OBJECT (buf, "stopped processing");
1919     return len - to_read;
1920   }
1921 }
1922
1923 /**
1924  * gst_ring_buffer_prepare_read:
1925  * @buf: the #GstRingBuffer to read from
1926  * @segment: the segment to read
1927  * @readptr: the pointer to the memory where samples can be read
1928  * @len: the number of bytes to read
1929  *
1930  * Returns a pointer to memory where the data from segment @segment
1931  * can be found. This function is mostly used by subclasses.
1932  *
1933  * Returns: FALSE if the buffer is not started.
1934  *
1935  * MT safe.
1936  */
1937 gboolean
1938 gst_ring_buffer_prepare_read (GstRingBuffer * buf, gint * segment,
1939     guint8 ** readptr, gint * len)
1940 {
1941   guint8 *data;
1942   gint segdone;
1943
1944   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
1945
1946   if (buf->callback == NULL) {
1947     /* push mode, fail when nothing is started */
1948     if (g_atomic_int_get (&buf->state) != GST_RING_BUFFER_STATE_STARTED)
1949       return FALSE;
1950   }
1951
1952   g_return_val_if_fail (buf->data != NULL, FALSE);
1953   g_return_val_if_fail (segment != NULL, FALSE);
1954   g_return_val_if_fail (readptr != NULL, FALSE);
1955   g_return_val_if_fail (len != NULL, FALSE);
1956
1957   data = GST_BUFFER_DATA (buf->data);
1958
1959   /* get the position of the pointer */
1960   segdone = g_atomic_int_get (&buf->segdone);
1961
1962   *segment = segdone % buf->spec.segtotal;
1963   *len = buf->spec.segsize;
1964   *readptr = data + *segment * *len;
1965
1966   GST_LOG ("prepare read from segment %d (real %d) @%p",
1967       *segment, segdone, *readptr);
1968
1969   /* callback to fill the memory with data, for pull based
1970    * scheduling. */
1971   if (buf->callback)
1972     buf->callback (buf, *readptr, *len, buf->cb_data);
1973
1974   return TRUE;
1975 }
1976
1977 /**
1978  * gst_ring_buffer_advance:
1979  * @buf: the #GstRingBuffer to advance
1980  * @advance: the number of segments written
1981  *
1982  * Subclasses should call this function to notify the fact that 
1983  * @advance segments are now processed by the device.
1984  *
1985  * MT safe.
1986  */
1987 void
1988 gst_ring_buffer_advance (GstRingBuffer * buf, guint advance)
1989 {
1990   g_return_if_fail (GST_IS_RING_BUFFER (buf));
1991
1992   /* update counter */
1993   g_atomic_int_add (&buf->segdone, advance);
1994
1995   /* the lock is already taken when the waiting flag is set,
1996    * we grab the lock as well to make sure the waiter is actually
1997    * waiting for the signal */
1998   if (g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0)) {
1999     GST_OBJECT_LOCK (buf);
2000     GST_DEBUG_OBJECT (buf, "signal waiter");
2001     GST_RING_BUFFER_SIGNAL (buf);
2002     GST_OBJECT_UNLOCK (buf);
2003   }
2004 }
2005
2006 /**
2007  * gst_ring_buffer_clear:
2008  * @buf: the #GstRingBuffer to clear
2009  * @segment: the segment to clear
2010  *
2011  * Clear the given segment of the buffer with silence samples.
2012  * This function is used by subclasses.
2013  *
2014  * MT safe.
2015  */
2016 void
2017 gst_ring_buffer_clear (GstRingBuffer * buf, gint segment)
2018 {
2019   guint8 *data;
2020
2021   g_return_if_fail (GST_IS_RING_BUFFER (buf));
2022
2023   /* no data means it's already cleared */
2024   if (G_UNLIKELY (buf->data == NULL))
2025     return;
2026
2027   /* no empty_seg means it's not opened */
2028   if (G_UNLIKELY (buf->empty_seg == NULL))
2029     return;
2030
2031   segment %= buf->spec.segtotal;
2032
2033   data = GST_BUFFER_DATA (buf->data);
2034   data += segment * buf->spec.segsize;
2035
2036   GST_LOG ("clear segment %d @%p", segment, data);
2037
2038   memcpy (data, buf->empty_seg, buf->spec.segsize);
2039 }
2040
2041 /**
2042  * gst_ring_buffer_may_start:
2043  * @buf: the #GstRingBuffer
2044  * @allowed: the new value
2045  *
2046  * Tell the ringbuffer that it is allowed to start playback when
2047  * the ringbuffer is filled with samples. 
2048  *
2049  * MT safe.
2050  *
2051  * Since: 0.10.6
2052  */
2053 void
2054 gst_ring_buffer_may_start (GstRingBuffer * buf, gboolean allowed)
2055 {
2056   g_return_if_fail (GST_IS_RING_BUFFER (buf));
2057
2058   GST_LOG_OBJECT (buf, "may start: %d", allowed);
2059   g_atomic_int_set (&buf->abidata.ABI.may_start, allowed);
2060 }