2 * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
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.
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.
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., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
21 * SECTION:gstaudioringbuffer
22 * @title: GstAudioRingBuffer
23 * @short_description: Base class for audio ringbuffer implementations
24 * @see_also: #GstAudioBaseSink, #GstAudioSink
26 * This object is the base class for audio ringbuffers used by the base
27 * audio source and sink classes.
29 * The ringbuffer abstracts a circular buffer of data. One reader and
30 * one writer can operate on the data from different threads in a lockfree
31 * manner. The base class is sufficiently flexible to be used as an
32 * abstraction for DMA based ringbuffers as well as a pure software
42 #include <gst/audio/audio.h>
43 #include "gstaudioringbuffer.h"
45 GST_DEBUG_CATEGORY_STATIC (gst_audio_ring_buffer_debug);
46 #define GST_CAT_DEFAULT gst_audio_ring_buffer_debug
48 static void gst_audio_ring_buffer_dispose (GObject * object);
49 static void gst_audio_ring_buffer_finalize (GObject * object);
51 static gboolean gst_audio_ring_buffer_pause_unlocked (GstAudioRingBuffer * buf);
52 static void default_clear_all (GstAudioRingBuffer * buf);
53 static guint default_commit (GstAudioRingBuffer * buf, guint64 * sample,
54 guint8 * data, gint in_samples, gint out_samples, gint * accum);
56 /* ringbuffer abstract base class */
57 G_DEFINE_ABSTRACT_TYPE (GstAudioRingBuffer, gst_audio_ring_buffer,
61 gst_audio_ring_buffer_class_init (GstAudioRingBufferClass * klass)
63 GObjectClass *gobject_class;
64 GstAudioRingBufferClass *gstaudioringbuffer_class;
66 gobject_class = (GObjectClass *) klass;
67 gstaudioringbuffer_class = (GstAudioRingBufferClass *) klass;
69 GST_DEBUG_CATEGORY_INIT (gst_audio_ring_buffer_debug, "ringbuffer", 0,
72 gobject_class->dispose = gst_audio_ring_buffer_dispose;
73 gobject_class->finalize = gst_audio_ring_buffer_finalize;
75 gstaudioringbuffer_class->clear_all = GST_DEBUG_FUNCPTR (default_clear_all);
76 gstaudioringbuffer_class->commit = GST_DEBUG_FUNCPTR (default_commit);
80 gst_audio_ring_buffer_init (GstAudioRingBuffer * ringbuffer)
82 ringbuffer->open = FALSE;
83 ringbuffer->acquired = FALSE;
84 g_atomic_int_set (&ringbuffer->state, GST_AUDIO_RING_BUFFER_STATE_STOPPED);
85 g_cond_init (&ringbuffer->cond);
86 ringbuffer->waiting = 0;
87 ringbuffer->empty_seg = NULL;
88 ringbuffer->flushing = TRUE;
89 ringbuffer->segbase = 0;
90 ringbuffer->segdone = 0;
94 gst_audio_ring_buffer_dispose (GObject * object)
96 GstAudioRingBuffer *ringbuffer = GST_AUDIO_RING_BUFFER (object);
98 gst_caps_replace (&ringbuffer->spec.caps, NULL);
100 G_OBJECT_CLASS (gst_audio_ring_buffer_parent_class)->dispose (G_OBJECT
105 gst_audio_ring_buffer_finalize (GObject * object)
107 GstAudioRingBuffer *ringbuffer = GST_AUDIO_RING_BUFFER (object);
109 g_cond_clear (&ringbuffer->cond);
110 g_free (ringbuffer->empty_seg);
112 if (ringbuffer->cb_data_notify != NULL)
113 ringbuffer->cb_data_notify (ringbuffer->cb_data);
115 G_OBJECT_CLASS (gst_audio_ring_buffer_parent_class)->finalize (G_OBJECT
119 #ifndef GST_DISABLE_GST_DEBUG
120 static const gchar *format_type_names[] = {
140 * gst_audio_ring_buffer_debug_spec_caps:
141 * @spec: the spec to debug
143 * Print debug info about the parsed caps in @spec to the debug log.
146 gst_audio_ring_buffer_debug_spec_caps (GstAudioRingBufferSpec * spec)
152 GST_DEBUG ("spec caps: %p %" GST_PTR_FORMAT, spec->caps, spec->caps);
153 GST_DEBUG ("parsed caps: type: %d, '%s'", spec->type,
154 format_type_names[spec->type]);
156 GST_DEBUG ("parsed caps: width: %d", spec->width);
157 GST_DEBUG ("parsed caps: sign: %d", spec->sign);
158 GST_DEBUG ("parsed caps: bigend: %d", spec->bigend);
159 GST_DEBUG ("parsed caps: rate: %d", spec->rate);
160 GST_DEBUG ("parsed caps: channels: %d", spec->channels);
161 GST_DEBUG ("parsed caps: sample bytes: %d", spec->bytes_per_sample);
162 bytes = (spec->width >> 3) * spec->channels;
163 for (i = 0; i < bytes; i++) {
164 GST_DEBUG ("silence byte %d: %02x", i, spec->silence_sample[i]);
170 * gst_audio_ring_buffer_debug_spec_buff:
171 * @spec: the spec to debug
173 * Print debug info about the buffer sized in @spec to the debug log.
176 gst_audio_ring_buffer_debug_spec_buff (GstAudioRingBufferSpec * spec)
178 gint bpf = GST_AUDIO_INFO_BPF (&spec->info);
180 GST_DEBUG ("acquire ringbuffer: buffer time: %" G_GINT64_FORMAT " usec",
182 GST_DEBUG ("acquire ringbuffer: latency time: %" G_GINT64_FORMAT " usec",
184 GST_DEBUG ("acquire ringbuffer: total segments: %d", spec->segtotal);
185 GST_DEBUG ("acquire ringbuffer: latency segments: %d", spec->seglatency);
186 GST_DEBUG ("acquire ringbuffer: segment size: %d bytes = %d samples",
187 spec->segsize, (bpf != 0) ? (spec->segsize / bpf) : -1);
188 GST_DEBUG ("acquire ringbuffer: buffer size: %d bytes = %d samples",
189 spec->segsize * spec->segtotal,
190 (bpf != 0) ? (spec->segsize * spec->segtotal / bpf) : -1);
194 * gst_audio_ring_buffer_parse_caps:
198 * Parse @caps into @spec.
200 * Returns: TRUE if the caps could be parsed.
203 gst_audio_ring_buffer_parse_caps (GstAudioRingBufferSpec * spec, GstCaps * caps)
205 const gchar *mimetype;
206 GstStructure *structure;
210 structure = gst_caps_get_structure (caps, 0);
211 gst_audio_info_init (&info);
213 /* we have to differentiate between int and float formats */
214 mimetype = gst_structure_get_name (structure);
216 if (g_str_equal (mimetype, "audio/x-raw")) {
217 if (!gst_audio_info_from_caps (&info, caps))
220 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW;
221 } else if (g_str_equal (mimetype, "audio/x-alaw")) {
222 /* extract the needed information from the cap */
223 if (!(gst_structure_get_int (structure, "rate", &info.rate) &&
224 gst_structure_get_int (structure, "channels", &info.channels)))
227 if (!(gst_audio_channel_positions_from_mask (info.channels, 0,
231 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW;
232 info.bpf = info.channels;
233 } else if (g_str_equal (mimetype, "audio/x-mulaw")) {
234 /* extract the needed information from the cap */
235 if (!(gst_structure_get_int (structure, "rate", &info.rate) &&
236 gst_structure_get_int (structure, "channels", &info.channels)))
239 if (!(gst_audio_channel_positions_from_mask (info.channels, 0,
243 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW;
244 info.bpf = info.channels;
245 } else if (g_str_equal (mimetype, "audio/x-iec958")) {
246 /* extract the needed information from the cap */
247 if (!(gst_structure_get_int (structure, "rate", &info.rate)))
250 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_IEC958;
252 } else if (g_str_equal (mimetype, "audio/x-ac3")) {
253 /* extract the needed information from the cap */
254 if (!(gst_structure_get_int (structure, "rate", &info.rate)))
257 gst_structure_get_int (structure, "channels", &info.channels);
258 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_AC3;
260 } else if (g_str_equal (mimetype, "audio/x-eac3")) {
261 /* extract the needed information from the cap */
262 if (!(gst_structure_get_int (structure, "rate", &info.rate)))
265 gst_structure_get_int (structure, "channels", &info.channels);
266 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_EAC3;
268 } else if (g_str_equal (mimetype, "audio/x-dts")) {
269 /* extract the needed information from the cap */
270 if (!(gst_structure_get_int (structure, "rate", &info.rate)))
273 gst_structure_get_int (structure, "channels", &info.channels);
274 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_DTS;
276 } else if (g_str_equal (mimetype, "audio/mpeg") &&
277 gst_structure_get_int (structure, "mpegaudioversion", &i) &&
278 (i == 1 || i == 2 || i == 3)) {
279 /* Now we know this is MPEG-1, MPEG-2 or MPEG-2.5 (non AAC) */
280 /* extract the needed information from the cap */
281 if (!(gst_structure_get_int (structure, "rate", &info.rate)))
284 gst_structure_get_int (structure, "channels", &info.channels);
285 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG;
287 } else if (g_str_equal (mimetype, "audio/mpeg") &&
288 gst_structure_get_int (structure, "mpegversion", &i) &&
289 (i == 2 || i == 4) &&
290 (!g_strcmp0 (gst_structure_get_string (structure, "stream-format"),
292 || !g_strcmp0 (gst_structure_get_string (structure, "stream-format"),
294 /* MPEG-2 AAC or MPEG-4 AAC */
295 if (!(gst_structure_get_int (structure, "rate", &info.rate)))
298 gst_structure_get_int (structure, "channels", &info.channels);
299 if (!g_strcmp0 (gst_structure_get_string (structure, "stream-format"),
301 spec->type = (i == 2) ? GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG2_AAC :
302 GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG4_AAC;
304 spec->type = (i == 2) ?
305 GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG2_AAC_RAW :
306 GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG4_AAC_RAW;
308 } else if (g_str_equal (mimetype, "audio/x-flac")) {
309 /* extract the needed information from the cap */
310 if (!(gst_structure_get_int (structure, "rate", &info.rate)))
313 gst_structure_get_int (structure, "channels", &info.channels);
314 spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_FLAC;
320 gst_caps_replace (&spec->caps, caps);
322 g_return_val_if_fail (spec->latency_time != 0, FALSE);
324 /* calculate suggested segsize and segtotal. segsize should be one unit
325 * of 'latency_time' samples, scaling for the fact that latency_time is
326 * currently stored in microseconds (FIXME: in 0.11) */
327 spec->segsize = gst_util_uint64_scale (info.rate * info.bpf,
328 spec->latency_time, GST_SECOND / GST_USECOND);
329 /* Round to an integer number of samples */
330 spec->segsize -= spec->segsize % info.bpf;
332 spec->segtotal = spec->buffer_time / spec->latency_time;
333 /* leave the latency undefined now, implementations can change it but if it's
334 * not changed, we assume the same value as segtotal */
335 spec->seglatency = -1;
339 gst_audio_ring_buffer_debug_spec_caps (spec);
340 gst_audio_ring_buffer_debug_spec_buff (spec);
347 GST_DEBUG ("could not parse caps");
353 * gst_audio_ring_buffer_convert:
354 * @buf: the #GstAudioRingBuffer
355 * @src_fmt: the source format
356 * @src_val: the source value
357 * @dest_fmt: the destination format
358 * @dest_val: (out): a location to store the converted value
360 * Convert @src_val in @src_fmt to the equivalent value in @dest_fmt. The result
361 * will be put in @dest_val.
363 * Returns: TRUE if the conversion succeeded.
366 gst_audio_ring_buffer_convert (GstAudioRingBuffer * buf,
367 GstFormat src_fmt, gint64 src_val, GstFormat dest_fmt, gint64 * dest_val)
371 GST_OBJECT_LOCK (buf);
373 gst_audio_info_convert (&buf->spec.info, src_fmt, src_val, dest_fmt,
375 GST_OBJECT_UNLOCK (buf);
381 * gst_audio_ring_buffer_set_callback: (skip)
382 * @buf: the #GstAudioRingBuffer to set the callback on
383 * @cb: (allow-none): the callback to set
384 * @user_data: user data passed to the callback
386 * Sets the given callback function on the buffer. This function
387 * will be called every time a segment has been written to a device.
392 gst_audio_ring_buffer_set_callback (GstAudioRingBuffer * buf,
393 GstAudioRingBufferCallback cb, gpointer user_data)
395 gst_audio_ring_buffer_set_callback_full (buf, cb, user_data, NULL);
399 * gst_audio_ring_buffer_set_callback_full: (rename-to gst_audio_ring_buffer_set_callback)
400 * @buf: the #GstAudioRingBuffer to set the callback on
401 * @cb: (allow-none): the callback to set
402 * @user_data: user data passed to the callback
403 * @notify: function to be called when @user_data is no longer needed
405 * Sets the given callback function on the buffer. This function
406 * will be called every time a segment has been written to a device.
413 gst_audio_ring_buffer_set_callback_full (GstAudioRingBuffer * buf,
414 GstAudioRingBufferCallback cb, gpointer user_data, GDestroyNotify notify)
416 gpointer old_data = NULL;
417 GDestroyNotify old_notify;
419 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
421 GST_OBJECT_LOCK (buf);
422 old_notify = buf->cb_data_notify;
423 old_data = buf->cb_data;
426 buf->cb_data = user_data;
427 buf->cb_data_notify = notify;
428 GST_OBJECT_UNLOCK (buf);
431 old_notify (old_data);
437 * gst_audio_ring_buffer_open_device:
438 * @buf: the #GstAudioRingBuffer
440 * Open the audio device associated with the ring buffer. Does not perform any
441 * setup on the device. You must open the device before acquiring the ring
444 * Returns: TRUE if the device could be opened, FALSE on error.
449 gst_audio_ring_buffer_open_device (GstAudioRingBuffer * buf)
452 GstAudioRingBufferClass *rclass;
454 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
456 GST_DEBUG_OBJECT (buf, "opening device");
458 GST_OBJECT_LOCK (buf);
459 if (G_UNLIKELY (buf->open))
464 /* if this fails, something is wrong in this file */
465 g_assert (!buf->acquired);
467 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
468 if (G_LIKELY (rclass->open_device))
469 res = rclass->open_device (buf);
471 if (G_UNLIKELY (!res))
474 GST_DEBUG_OBJECT (buf, "opened device");
477 GST_OBJECT_UNLOCK (buf);
484 GST_DEBUG_OBJECT (buf, "Device for ring buffer already open");
485 g_warning ("Device for ring buffer %p already open, fix your code", buf);
492 GST_DEBUG_OBJECT (buf, "failed opening device");
498 * gst_audio_ring_buffer_close_device:
499 * @buf: the #GstAudioRingBuffer
501 * Close the audio device associated with the ring buffer. The ring buffer
502 * should already have been released via gst_audio_ring_buffer_release().
504 * Returns: TRUE if the device could be closed, FALSE on error.
509 gst_audio_ring_buffer_close_device (GstAudioRingBuffer * buf)
512 GstAudioRingBufferClass *rclass;
514 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
516 GST_DEBUG_OBJECT (buf, "closing device");
518 GST_OBJECT_LOCK (buf);
519 if (G_UNLIKELY (!buf->open))
522 if (G_UNLIKELY (buf->acquired))
527 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
528 if (G_LIKELY (rclass->close_device))
529 res = rclass->close_device (buf);
531 if (G_UNLIKELY (!res))
534 GST_DEBUG_OBJECT (buf, "closed device");
537 GST_OBJECT_UNLOCK (buf);
544 GST_DEBUG_OBJECT (buf, "Device for ring buffer already closed");
545 g_warning ("Device for ring buffer %p already closed, fix your code", buf);
551 GST_DEBUG_OBJECT (buf, "Resources for ring buffer still acquired");
552 g_critical ("Resources for ring buffer %p still acquired", buf);
559 GST_DEBUG_OBJECT (buf, "error closing device");
565 * gst_audio_ring_buffer_device_is_open:
566 * @buf: the #GstAudioRingBuffer
568 * Checks the status of the device associated with the ring buffer.
570 * Returns: TRUE if the device was open, FALSE if it was closed.
575 gst_audio_ring_buffer_device_is_open (GstAudioRingBuffer * buf)
579 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
581 GST_OBJECT_LOCK (buf);
583 GST_OBJECT_UNLOCK (buf);
589 * gst_audio_ring_buffer_acquire:
590 * @buf: the #GstAudioRingBuffer to acquire
591 * @spec: the specs of the buffer
593 * Allocate the resources for the ringbuffer. This function fills
594 * in the data pointer of the ring buffer with a valid #GstBuffer
595 * to which samples can be written.
597 * Returns: TRUE if the device could be acquired, FALSE on error.
602 gst_audio_ring_buffer_acquire (GstAudioRingBuffer * buf,
603 GstAudioRingBufferSpec * spec)
605 gboolean res = FALSE;
606 GstAudioRingBufferClass *rclass;
607 gint segsize, bpf, i;
609 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
611 GST_DEBUG_OBJECT (buf, "acquiring device %p", buf);
613 GST_OBJECT_LOCK (buf);
614 if (G_UNLIKELY (!buf->open))
617 if (G_UNLIKELY (buf->acquired))
620 buf->acquired = TRUE;
621 buf->need_reorder = FALSE;
623 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
624 if (G_LIKELY (rclass->acquire))
625 res = rclass->acquire (buf, spec);
627 /* Only reorder for raw audio */
628 buf->need_reorder = (buf->need_reorder
629 && buf->spec.type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW);
631 if (G_UNLIKELY (!res))
634 GST_INFO_OBJECT (buf, "Allocating an array for %d timestamps",
636 buf->timestamps = g_slice_alloc0 (sizeof (GstClockTime) * spec->segtotal);
637 /* initialize array with invalid timestamps */
638 for (i = 0; i < spec->segtotal; i++) {
639 buf->timestamps[i] = GST_CLOCK_TIME_NONE;
642 if (G_UNLIKELY ((bpf = buf->spec.info.bpf) == 0))
645 /* if the seglatency was overwritten with something else than -1, use it, else
646 * assume segtotal as the latency */
647 if (buf->spec.seglatency == -1)
648 buf->spec.seglatency = buf->spec.segtotal;
650 segsize = buf->spec.segsize;
652 buf->samples_per_seg = segsize / bpf;
654 /* create an empty segment */
655 g_free (buf->empty_seg);
656 buf->empty_seg = g_malloc (segsize);
658 if (buf->spec.type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW) {
659 gst_audio_format_info_fill_silence (buf->spec.info.finfo, buf->empty_seg,
662 /* FIXME, non-raw formats get 0 as the empty sample */
663 memset (buf->empty_seg, 0, segsize);
665 GST_DEBUG_OBJECT (buf, "acquired device");
668 GST_OBJECT_UNLOCK (buf);
675 GST_DEBUG_OBJECT (buf, "device not opened");
676 g_critical ("Device for %p not opened", buf);
683 GST_DEBUG_OBJECT (buf, "device was acquired");
688 buf->acquired = FALSE;
689 GST_DEBUG_OBJECT (buf, "failed to acquire device");
695 ("invalid bytes_per_frame from acquire ringbuffer %p, fix the element",
697 buf->acquired = FALSE;
704 * gst_audio_ring_buffer_release:
705 * @buf: the #GstAudioRingBuffer to release
707 * Free the resources of the ringbuffer.
709 * Returns: TRUE if the device could be released, FALSE on error.
714 gst_audio_ring_buffer_release (GstAudioRingBuffer * buf)
716 gboolean res = FALSE;
717 GstAudioRingBufferClass *rclass;
719 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
721 GST_DEBUG_OBJECT (buf, "releasing device");
723 gst_audio_ring_buffer_stop (buf);
725 GST_OBJECT_LOCK (buf);
727 if (G_LIKELY (buf->timestamps)) {
728 GST_INFO_OBJECT (buf, "Freeing timestamp buffer, %d entries",
730 g_slice_free1 (sizeof (GstClockTime) * buf->spec.segtotal, buf->timestamps);
731 buf->timestamps = NULL;
734 if (G_UNLIKELY (!buf->acquired))
737 buf->acquired = FALSE;
739 /* if this fails, something is wrong in this file */
740 g_assert (buf->open);
742 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
743 if (G_LIKELY (rclass->release))
744 res = rclass->release (buf);
746 /* signal any waiters */
747 GST_DEBUG_OBJECT (buf, "signal waiter");
748 GST_AUDIO_RING_BUFFER_SIGNAL (buf);
750 if (G_UNLIKELY (!res))
753 g_atomic_int_set (&buf->segdone, 0);
755 g_free (buf->empty_seg);
756 buf->empty_seg = NULL;
757 gst_caps_replace (&buf->spec.caps, NULL);
758 gst_audio_info_init (&buf->spec.info);
759 GST_DEBUG_OBJECT (buf, "released device");
762 GST_OBJECT_UNLOCK (buf);
770 GST_DEBUG_OBJECT (buf, "device was released");
775 buf->acquired = TRUE;
776 GST_DEBUG_OBJECT (buf, "failed to release device");
782 * gst_audio_ring_buffer_is_acquired:
783 * @buf: the #GstAudioRingBuffer to check
785 * Check if the ringbuffer is acquired and ready to use.
787 * Returns: TRUE if the ringbuffer is acquired, FALSE on error.
792 gst_audio_ring_buffer_is_acquired (GstAudioRingBuffer * buf)
796 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
798 GST_OBJECT_LOCK (buf);
800 GST_OBJECT_UNLOCK (buf);
806 * gst_audio_ring_buffer_activate:
807 * @buf: the #GstAudioRingBuffer to activate
808 * @active: the new mode
810 * Activate @buf to start or stop pulling data.
814 * Returns: TRUE if the device could be activated in the requested mode,
818 gst_audio_ring_buffer_activate (GstAudioRingBuffer * buf, gboolean active)
820 gboolean res = FALSE;
821 GstAudioRingBufferClass *rclass;
823 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
825 GST_DEBUG_OBJECT (buf, "activate device");
827 GST_OBJECT_LOCK (buf);
828 if (G_UNLIKELY (active && !buf->acquired))
831 if (G_UNLIKELY (buf->active == active))
834 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
835 /* if there is no activate function we assume it was started/released
836 * in the acquire method */
837 if (G_LIKELY (rclass->activate))
838 res = rclass->activate (buf, active);
842 if (G_UNLIKELY (!res))
843 goto activate_failed;
845 buf->active = active;
848 GST_OBJECT_UNLOCK (buf);
855 GST_DEBUG_OBJECT (buf, "device not acquired");
856 g_critical ("Device for %p not acquired", buf);
863 GST_DEBUG_OBJECT (buf, "device was active in mode %d", active);
868 GST_DEBUG_OBJECT (buf, "failed to activate device");
874 * gst_audio_ring_buffer_is_active:
875 * @buf: the #GstAudioRingBuffer
877 * Check if @buf is activated.
881 * Returns: TRUE if the device is active.
884 gst_audio_ring_buffer_is_active (GstAudioRingBuffer * buf)
888 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
890 GST_OBJECT_LOCK (buf);
892 GST_OBJECT_UNLOCK (buf);
899 * gst_audio_ring_buffer_set_flushing:
900 * @buf: the #GstAudioRingBuffer to flush
901 * @flushing: the new mode
903 * Set the ringbuffer to flushing mode or normal mode.
908 gst_audio_ring_buffer_set_flushing (GstAudioRingBuffer * buf, gboolean flushing)
910 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
912 GST_OBJECT_LOCK (buf);
913 buf->flushing = flushing;
916 gst_audio_ring_buffer_pause_unlocked (buf);
918 gst_audio_ring_buffer_clear_all (buf);
920 GST_OBJECT_UNLOCK (buf);
924 * gst_audio_ring_buffer_is_flushing:
925 * @buf: the #GstAudioRingBuffer
927 * Check if @buf is flushing.
931 * Returns: TRUE if the device is flushing.
934 gst_audio_ring_buffer_is_flushing (GstAudioRingBuffer * buf)
938 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), TRUE);
940 GST_OBJECT_LOCK (buf);
942 GST_OBJECT_UNLOCK (buf);
948 * gst_audio_ring_buffer_start:
949 * @buf: the #GstAudioRingBuffer to start
951 * Start processing samples from the ringbuffer.
953 * Returns: TRUE if the device could be started, FALSE on error.
958 gst_audio_ring_buffer_start (GstAudioRingBuffer * buf)
960 gboolean res = FALSE;
961 GstAudioRingBufferClass *rclass;
962 gboolean resume = FALSE;
964 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
966 GST_DEBUG_OBJECT (buf, "starting ringbuffer");
968 GST_OBJECT_LOCK (buf);
969 if (G_UNLIKELY (buf->flushing))
972 if (G_UNLIKELY (!buf->acquired))
975 if (G_UNLIKELY (!g_atomic_int_get (&buf->may_start)))
978 /* if stopped, set to started */
979 res = g_atomic_int_compare_and_exchange (&buf->state,
980 GST_AUDIO_RING_BUFFER_STATE_STOPPED, GST_AUDIO_RING_BUFFER_STATE_STARTED);
983 GST_DEBUG_OBJECT (buf, "was not stopped, try paused");
984 /* was not stopped, try from paused */
985 res = g_atomic_int_compare_and_exchange (&buf->state,
986 GST_AUDIO_RING_BUFFER_STATE_PAUSED,
987 GST_AUDIO_RING_BUFFER_STATE_STARTED);
989 /* was not paused either, must be started then */
991 GST_DEBUG_OBJECT (buf, "was not paused, must have been started");
995 GST_DEBUG_OBJECT (buf, "resuming");
998 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
1000 if (G_LIKELY (rclass->resume))
1001 res = rclass->resume (buf);
1003 if (G_LIKELY (rclass->start))
1004 res = rclass->start (buf);
1007 if (G_UNLIKELY (!res)) {
1008 g_atomic_int_set (&buf->state, GST_AUDIO_RING_BUFFER_STATE_PAUSED);
1009 GST_DEBUG_OBJECT (buf, "failed to start");
1011 GST_DEBUG_OBJECT (buf, "started");
1015 GST_OBJECT_UNLOCK (buf);
1021 GST_DEBUG_OBJECT (buf, "we are flushing");
1022 GST_OBJECT_UNLOCK (buf);
1027 GST_DEBUG_OBJECT (buf, "we are not acquired");
1028 GST_OBJECT_UNLOCK (buf);
1033 GST_DEBUG_OBJECT (buf, "we may not start");
1034 GST_OBJECT_UNLOCK (buf);
1040 void __gst_audio_ring_buffer_set_errored (GstAudioRingBuffer * buf);
1042 /* __gst_audio_ring_buffer_set_errored:
1043 * @buf: the #GstAudioRingBuffer that has encountered an error
1045 * Mark the ringbuffer as errored after it has started.
1049 * Since: 1.24 (internal in 1.22)
1052 __gst_audio_ring_buffer_set_errored (GstAudioRingBuffer * buf)
1056 /* If started set to errored */
1057 res = g_atomic_int_compare_and_exchange (&buf->state,
1058 GST_AUDIO_RING_BUFFER_STATE_STARTED, GST_AUDIO_RING_BUFFER_STATE_ERROR);
1060 GST_DEBUG_OBJECT (buf, "ringbuffer was not started, checking paused");
1061 res = g_atomic_int_compare_and_exchange (&buf->state,
1062 GST_AUDIO_RING_BUFFER_STATE_PAUSED, GST_AUDIO_RING_BUFFER_STATE_ERROR);
1065 GST_DEBUG_OBJECT (buf, "ringbuffer is errored");
1067 GST_DEBUG_OBJECT (buf,
1068 "Could not mark ringbuffer as errored. It must have been stopped or already errored (was state %d)",
1069 g_atomic_int_get (&buf->state));
1074 gst_audio_ring_buffer_pause_unlocked (GstAudioRingBuffer * buf)
1076 gboolean res = FALSE;
1077 GstAudioRingBufferClass *rclass;
1079 GST_DEBUG_OBJECT (buf, "pausing ringbuffer");
1081 /* if started, set to paused */
1082 res = g_atomic_int_compare_and_exchange (&buf->state,
1083 GST_AUDIO_RING_BUFFER_STATE_STARTED, GST_AUDIO_RING_BUFFER_STATE_PAUSED);
1088 /* signal any waiters */
1089 GST_DEBUG_OBJECT (buf, "signal waiter");
1090 GST_AUDIO_RING_BUFFER_SIGNAL (buf);
1092 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
1093 if (G_LIKELY (rclass->pause))
1094 res = rclass->pause (buf);
1096 if (G_UNLIKELY (!res)) {
1097 /* Restore started state */
1098 g_atomic_int_set (&buf->state, GST_AUDIO_RING_BUFFER_STATE_STARTED);
1099 GST_DEBUG_OBJECT (buf, "failed to pause");
1101 GST_DEBUG_OBJECT (buf, "paused");
1108 /* was not started */
1109 GST_DEBUG_OBJECT (buf, "was not started (state %d)", buf->state);
1115 * gst_audio_ring_buffer_pause:
1116 * @buf: the #GstAudioRingBuffer to pause
1118 * Pause processing samples from the ringbuffer.
1120 * Returns: TRUE if the device could be paused, FALSE on error.
1125 gst_audio_ring_buffer_pause (GstAudioRingBuffer * buf)
1127 gboolean res = FALSE;
1129 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
1131 GST_OBJECT_LOCK (buf);
1132 if (G_UNLIKELY (buf->flushing))
1135 if (G_UNLIKELY (!buf->acquired))
1138 res = gst_audio_ring_buffer_pause_unlocked (buf);
1139 GST_OBJECT_UNLOCK (buf);
1146 GST_DEBUG_OBJECT (buf, "we are flushing");
1147 GST_OBJECT_UNLOCK (buf);
1152 GST_DEBUG_OBJECT (buf, "not acquired");
1153 GST_OBJECT_UNLOCK (buf);
1159 * gst_audio_ring_buffer_stop:
1160 * @buf: the #GstAudioRingBuffer to stop
1162 * Stop processing samples from the ringbuffer.
1164 * Returns: TRUE if the device could be stopped, FALSE on error.
1169 gst_audio_ring_buffer_stop (GstAudioRingBuffer * buf)
1171 gboolean res = FALSE;
1172 GstAudioRingBufferClass *rclass;
1174 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
1176 GST_DEBUG_OBJECT (buf, "stopping");
1178 GST_OBJECT_LOCK (buf);
1180 /* if started, set to stopped */
1181 res = g_atomic_int_compare_and_exchange (&buf->state,
1182 GST_AUDIO_RING_BUFFER_STATE_STARTED, GST_AUDIO_RING_BUFFER_STATE_STOPPED);
1185 GST_DEBUG_OBJECT (buf, "was not started, try paused");
1186 /* was not started, try from paused */
1187 res = g_atomic_int_compare_and_exchange (&buf->state,
1188 GST_AUDIO_RING_BUFFER_STATE_PAUSED,
1189 GST_AUDIO_RING_BUFFER_STATE_STOPPED);
1191 GST_DEBUG_OBJECT (buf, "was not paused, try errored");
1192 res = g_atomic_int_compare_and_exchange (&buf->state,
1193 GST_AUDIO_RING_BUFFER_STATE_ERROR,
1194 GST_AUDIO_RING_BUFFER_STATE_STOPPED);
1197 /* was not paused or stopped either, must have been stopped then */
1199 GST_DEBUG_OBJECT (buf,
1200 "was not paused or errored, must have been stopped");
1205 /* signal any waiters */
1206 GST_DEBUG_OBJECT (buf, "signal waiter");
1207 GST_AUDIO_RING_BUFFER_SIGNAL (buf);
1209 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
1210 if (G_LIKELY (rclass->stop))
1211 res = rclass->stop (buf);
1213 if (G_UNLIKELY (!res)) {
1214 g_atomic_int_set (&buf->state, GST_AUDIO_RING_BUFFER_STATE_STARTED);
1215 GST_DEBUG_OBJECT (buf, "failed to stop");
1217 GST_DEBUG_OBJECT (buf, "stopped");
1220 GST_OBJECT_UNLOCK (buf);
1226 * gst_audio_ring_buffer_delay:
1227 * @buf: the #GstAudioRingBuffer to query
1229 * Get the number of samples queued in the audio device. This is
1230 * usually less than the segment size but can be bigger when the
1231 * implementation uses another internal buffer between the audio
1234 * For playback ringbuffers this is the amount of samples transferred from the
1235 * ringbuffer to the device but still not played.
1237 * For capture ringbuffers this is the amount of samples in the device that are
1238 * not yet transferred to the ringbuffer.
1240 * Returns: The number of samples queued in the audio device.
1245 gst_audio_ring_buffer_delay (GstAudioRingBuffer * buf)
1247 GstAudioRingBufferClass *rclass;
1250 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), 0);
1252 /* buffer must be acquired */
1253 if (G_UNLIKELY (!gst_audio_ring_buffer_is_acquired (buf)))
1256 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
1257 if (G_LIKELY (rclass->delay))
1258 res = rclass->delay (buf);
1266 GST_DEBUG_OBJECT (buf, "not acquired");
1272 * gst_audio_ring_buffer_samples_done:
1273 * @buf: the #GstAudioRingBuffer to query
1275 * Get the number of samples that were processed by the ringbuffer
1276 * since it was last started. This does not include the number of samples not
1277 * yet processed (see gst_audio_ring_buffer_delay()).
1279 * Returns: The number of samples processed by the ringbuffer.
1284 gst_audio_ring_buffer_samples_done (GstAudioRingBuffer * buf)
1289 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), 0);
1291 /* get the amount of segments we processed */
1292 segdone = g_atomic_int_get (&buf->segdone);
1294 /* convert to samples */
1295 samples = ((guint64) segdone) * buf->samples_per_seg;
1301 * gst_audio_ring_buffer_set_sample:
1302 * @buf: the #GstAudioRingBuffer to use
1303 * @sample: the sample number to set
1305 * Make sure that the next sample written to the device is
1306 * accounted for as being the @sample sample written to the
1307 * device. This value will be used in reporting the current
1308 * sample position of the ringbuffer.
1310 * This function will also clear the buffer with silence.
1315 gst_audio_ring_buffer_set_sample (GstAudioRingBuffer * buf, guint64 sample)
1317 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1322 if (G_UNLIKELY (buf->samples_per_seg == 0))
1325 /* FIXME, we assume the ringbuffer can restart at a random
1326 * position, round down to the beginning and keep track of
1327 * offset when calculating the processed samples. */
1328 buf->segbase = buf->segdone - sample / buf->samples_per_seg;
1330 gst_audio_ring_buffer_clear_all (buf);
1332 GST_DEBUG_OBJECT (buf, "set sample to %" G_GUINT64_FORMAT ", segbase %d",
1333 sample, buf->segbase);
1337 * default_clear_all:
1338 * @buf: the #GstAudioRingBuffer to clear
1340 * Fill the ringbuffer with silence.
1343 default_clear_all (GstAudioRingBuffer * buf)
1347 /* not fatal, we just are not negotiated yet */
1348 if (G_UNLIKELY (buf->spec.segtotal <= 0))
1351 GST_DEBUG_OBJECT (buf, "clear all segments");
1353 for (i = 0; i < buf->spec.segtotal; i++) {
1354 gst_audio_ring_buffer_clear (buf, i);
1359 * gst_audio_ring_buffer_clear_all:
1360 * @buf: the #GstAudioRingBuffer to clear
1362 * Clear all samples from the ringbuffer.
1367 gst_audio_ring_buffer_clear_all (GstAudioRingBuffer * buf)
1369 GstAudioRingBufferClass *rclass;
1371 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1373 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
1375 if (G_LIKELY (rclass->clear_all))
1376 rclass->clear_all (buf);
1381 wait_segment (GstAudioRingBuffer * buf)
1384 gboolean wait = TRUE;
1386 /* buffer must be started now or we deadlock since nobody is reading */
1387 if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1388 GST_AUDIO_RING_BUFFER_STATE_STARTED)) {
1389 /* see if we are allowed to start it */
1390 if (G_UNLIKELY (!g_atomic_int_get (&buf->may_start)))
1393 GST_DEBUG_OBJECT (buf, "start!");
1394 segments = g_atomic_int_get (&buf->segdone);
1395 gst_audio_ring_buffer_start (buf);
1397 /* After starting, the writer may have wrote segments already and then we
1398 * don't need to wait anymore */
1399 if (G_LIKELY (g_atomic_int_get (&buf->segdone) != segments))
1403 /* take lock first, then update our waiting flag */
1404 GST_OBJECT_LOCK (buf);
1405 if (G_UNLIKELY (buf->flushing))
1408 if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1409 GST_AUDIO_RING_BUFFER_STATE_STARTED))
1412 if (G_LIKELY (wait)) {
1413 if (g_atomic_int_compare_and_exchange (&buf->waiting, 0, 1)) {
1414 GST_DEBUG_OBJECT (buf, "waiting..");
1415 GST_AUDIO_RING_BUFFER_WAIT (buf);
1417 if (G_UNLIKELY (buf->flushing))
1420 if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1421 GST_AUDIO_RING_BUFFER_STATE_STARTED))
1425 GST_OBJECT_UNLOCK (buf);
1432 g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0);
1433 GST_DEBUG_OBJECT (buf, "stopped processing");
1434 GST_OBJECT_UNLOCK (buf);
1439 g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0);
1440 GST_DEBUG_OBJECT (buf, "flushing");
1441 GST_OBJECT_UNLOCK (buf);
1446 GST_DEBUG_OBJECT (buf, "not allowed to start");
1453 #define REORDER_SAMPLE(d, s, l) \
1456 for (i = 0; i < channels; i++) { \
1457 memcpy (d + reorder_map[i] * bps, s + i * bps, bps); \
1461 #define REORDER_SAMPLES(d, s, len) \
1463 gint i, len_ = len / bpf; \
1464 guint8 *d_ = d, *s_ = s; \
1465 for (i = 0; i < len_; i++) { \
1466 REORDER_SAMPLE(d_, s_, bpf); \
1472 #define FWD_SAMPLES(s,se,d,de,F) \
1474 /* no rate conversion */ \
1475 guint towrite = MIN (se + bpf - s, de - d); \
1478 F (d, s, towrite); \
1479 in_samples -= towrite / bpf; \
1480 out_samples -= towrite / bpf; \
1482 GST_DEBUG ("copy %u bytes", towrite); \
1485 /* in_samples >= out_samples, rate > 1.0 */
1486 #define FWD_UP_SAMPLES(s,se,d,de,F) \
1488 guint8 *sb = s, *db = d; \
1489 while (s <= se && d < de) { \
1494 if ((*accum << 1) >= inr) { \
1499 in_samples -= (s - sb)/bpf; \
1500 out_samples -= (d - db)/bpf; \
1501 GST_DEBUG ("fwd_up end %d/%d",*accum,*toprocess); \
1504 /* out_samples > in_samples, for rates smaller than 1.0 */
1505 #define FWD_DOWN_SAMPLES(s,se,d,de,F) \
1507 guint8 *sb = s, *db = d; \
1508 while (s <= se && d < de) { \
1513 if ((*accum << 1) >= outr) { \
1518 in_samples -= (s - sb)/bpf; \
1519 out_samples -= (d - db)/bpf; \
1520 GST_DEBUG ("fwd_down end %d/%d",*accum,*toprocess); \
1523 #define REV_UP_SAMPLES(s,se,d,de,F) \
1525 guint8 *sb = se, *db = d; \
1526 while (s <= se && d < de) { \
1531 while (d < de && (*accum << 1) >= inr) { \
1536 in_samples -= (sb - se)/bpf; \
1537 out_samples -= (d - db)/bpf; \
1538 GST_DEBUG ("rev_up end %d/%d",*accum,*toprocess); \
1541 #define REV_DOWN_SAMPLES(s,se,d,de,F) \
1543 guint8 *sb = se, *db = d; \
1544 while (s <= se && d < de) { \
1549 while (s <= se && (*accum << 1) >= outr) { \
1554 in_samples -= (sb - se)/bpf; \
1555 out_samples -= (d - db)/bpf; \
1556 GST_DEBUG ("rev_down end %d/%d",*accum,*toprocess); \
1560 default_commit (GstAudioRingBuffer * buf, guint64 * sample,
1561 guint8 * data, gint in_samples, gint out_samples, gint * accum)
1564 gint segsize, segtotal, channels, bps, bpf, sps;
1565 guint8 *dest, *data_end;
1566 gint writeseg, sampleoff;
1570 gboolean need_reorder;
1572 g_return_val_if_fail (buf->memory != NULL, -1);
1573 g_return_val_if_fail (data != NULL, -1);
1575 need_reorder = buf->need_reorder;
1577 channels = buf->spec.info.channels;
1579 segsize = buf->spec.segsize;
1580 segtotal = buf->spec.segtotal;
1581 bpf = buf->spec.info.bpf;
1582 bps = bpf / channels;
1583 sps = buf->samples_per_seg;
1585 reverse = out_samples < 0;
1586 out_samples = ABS (out_samples);
1588 if (in_samples >= out_samples)
1589 toprocess = &in_samples;
1591 toprocess = &out_samples;
1593 inr = in_samples - 1;
1594 outr = out_samples - 1;
1596 /* data_end points to the last sample we have to write, not past it. This is
1597 * needed to properly handle reverse playback: it points to the last sample. */
1598 data_end = data + (bpf * inr);
1600 /* figure out the segment and the offset inside the segment where
1601 * the first sample should be written. */
1602 writeseg = *sample / sps;
1603 sampleoff = (*sample % sps) * bpf;
1605 GST_DEBUG_OBJECT (buf, "write %d : %d", in_samples, out_samples);
1607 /* write out all samples */
1608 while (*toprocess > 0) {
1617 /* get the currently processed segment */
1618 segdone = g_atomic_int_get (&buf->segdone) - buf->segbase;
1620 /* see how far away it is from the write segment */
1621 diff = writeseg - segdone;
1623 GST_DEBUG_OBJECT (buf,
1624 "pointer at %d, write to %d-%d, diff %d, segtotal %d, segsize %d, base %d",
1625 segdone, writeseg, sampleoff, diff, segtotal, segsize, buf->segbase);
1627 /* segment too far ahead, writer too slow, we need to drop, hopefully UNLIKELY */
1628 if (G_UNLIKELY (diff < 0)) {
1629 /* we need to drop one segment at a time, pretend we wrote a segment. */
1634 /* write segment is within writable range, we can break the loop and
1635 * start writing the data. */
1636 if (diff < segtotal) {
1641 /* else we need to wait for the segment to become writable. */
1642 if (!wait_segment (buf))
1646 /* we can write now */
1647 ws = writeseg % segtotal;
1648 avail = MIN (segsize - sampleoff, bpf * out_samples);
1650 d = dest + (ws * segsize) + sampleoff;
1652 *sample += avail / bpf;
1654 GST_DEBUG_OBJECT (buf, "write @%p seg %d, sps %d, off %d, avail %d",
1655 dest + ws * segsize, ws, sps, sampleoff, avail);
1658 gint *reorder_map = buf->channel_reorder_map;
1660 if (G_LIKELY (inr == outr && !reverse)) {
1661 /* no rate conversion, simply copy samples */
1662 FWD_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLES);
1663 } else if (!reverse) {
1665 /* forward speed up */
1666 FWD_UP_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLE);
1668 /* forward slow down */
1669 FWD_DOWN_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLE);
1672 /* reverse speed up */
1673 REV_UP_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLE);
1675 /* reverse slow down */
1676 REV_DOWN_SAMPLES (data, data_end, d, d_end, REORDER_SAMPLE);
1679 if (G_LIKELY (inr == outr && !reverse)) {
1680 /* no rate conversion, simply copy samples */
1681 FWD_SAMPLES (data, data_end, d, d_end, memcpy);
1682 } else if (!reverse) {
1684 /* forward speed up */
1685 FWD_UP_SAMPLES (data, data_end, d, d_end, memcpy);
1687 /* forward slow down */
1688 FWD_DOWN_SAMPLES (data, data_end, d, d_end, memcpy);
1691 /* reverse speed up */
1692 REV_UP_SAMPLES (data, data_end, d, d_end, memcpy);
1694 /* reverse slow down */
1695 REV_DOWN_SAMPLES (data, data_end, d, d_end, memcpy);
1699 /* for the next iteration we write to the next segment at the beginning. */
1703 /* we consumed all samples here */
1704 data = data_end + bpf;
1707 return inr - ((data_end - data) / bpf);
1712 GST_DEBUG_OBJECT (buf, "stopped processing");
1718 * gst_audio_ring_buffer_commit:
1719 * @buf: the #GstAudioRingBuffer to commit
1720 * @sample: (inout): the sample position of the data
1721 * @data: (array length=in_samples): the data to commit
1722 * @in_samples: the number of samples in the data to commit
1723 * @out_samples: the number of samples to write to the ringbuffer
1724 * @accum: (inout): accumulator for rate conversion.
1726 * Commit @in_samples samples pointed to by @data to the ringbuffer @buf.
1728 * @in_samples and @out_samples define the rate conversion to perform on the
1729 * samples in @data. For negative rates, @out_samples must be negative and
1730 * @in_samples positive.
1732 * When @out_samples is positive, the first sample will be written at position @sample
1733 * in the ringbuffer. When @out_samples is negative, the last sample will be written to
1734 * @sample in reverse order.
1736 * @out_samples does not need to be a multiple of the segment size of the ringbuffer
1737 * although it is recommended for optimal performance.
1739 * @accum will hold a temporary accumulator used in rate conversion and should be
1740 * set to 0 when this function is first called. In case the commit operation is
1741 * interrupted, one can resume the processing by passing the previously returned
1742 * @accum value back to this function.
1746 * Returns: The number of samples written to the ringbuffer or -1 on error. The
1747 * number of samples written can be less than @out_samples when @buf was interrupted
1748 * with a flush or stop.
1751 gst_audio_ring_buffer_commit (GstAudioRingBuffer * buf, guint64 * sample,
1752 guint8 * data, gint in_samples, gint out_samples, gint * accum)
1754 GstAudioRingBufferClass *rclass;
1757 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), -1);
1759 if (G_UNLIKELY (in_samples == 0 || out_samples == 0))
1762 rclass = GST_AUDIO_RING_BUFFER_GET_CLASS (buf);
1764 if (G_LIKELY (rclass->commit))
1765 res = rclass->commit (buf, sample, data, in_samples, out_samples, accum);
1771 * gst_audio_ring_buffer_read:
1772 * @buf: the #GstAudioRingBuffer to read from
1773 * @sample: the sample position of the data
1774 * @data: (array length=len): where the data should be read
1775 * @len: the number of samples in data to read
1776 * @timestamp: (out): where the timestamp is returned
1778 * Read @len samples from the ringbuffer into the memory pointed
1780 * The first sample should be read from position @sample in
1783 * @len should not be a multiple of the segment size of the ringbuffer
1784 * although it is recommended.
1786 * @timestamp will return the timestamp associated with the data returned.
1788 * Returns: The number of samples read from the ringbuffer or -1 on
1794 gst_audio_ring_buffer_read (GstAudioRingBuffer * buf, guint64 sample,
1795 guint8 * data, guint len, GstClockTime * timestamp)
1798 gint segsize, segtotal, channels, bps, bpf, sps, readseg = 0;
1801 gboolean need_reorder;
1803 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), -1);
1804 g_return_val_if_fail (buf->memory != NULL, -1);
1805 g_return_val_if_fail (data != NULL, -1);
1807 need_reorder = buf->need_reorder;
1809 segsize = buf->spec.segsize;
1810 segtotal = buf->spec.segtotal;
1811 channels = buf->spec.info.channels;
1812 bpf = buf->spec.info.bpf;
1813 bps = bpf / channels;
1814 sps = buf->samples_per_seg;
1817 /* read enough samples */
1818 while (to_read > 0) {
1822 /* figure out the segment and the offset inside the segment where
1823 * the sample should be read from. */
1824 readseg = sample / sps;
1825 sampleoff = (sample % sps);
1830 /* get the currently processed segment */
1831 segdone = g_atomic_int_get (&buf->segdone) - buf->segbase;
1833 /* see how far away it is from the read segment, normally segdone (where
1834 * the hardware is writing) is bigger than readseg (where software is
1836 diff = segdone - readseg;
1839 (buf, "pointer at %d, sample %" G_GUINT64_FORMAT
1840 ", read from %d-%d, to_read %d, diff %d, segtotal %d, segsize %d",
1841 segdone, sample, readseg, sampleoff, to_read, diff, segtotal,
1844 /* segment too far ahead, reader too slow */
1845 if (G_UNLIKELY (diff >= segtotal)) {
1846 /* pretend we read an empty segment. */
1847 sampleslen = MIN (sps, to_read);
1848 memcpy (data, buf->empty_seg, sampleslen * bpf);
1852 /* read segment is within readable range, we can break the loop and
1853 * start reading the data. */
1857 /* else we need to wait for the segment to become readable. */
1858 if (!wait_segment (buf))
1862 /* we can read now */
1863 readseg = readseg % segtotal;
1864 sampleslen = MIN (sps - sampleoff, to_read);
1866 GST_DEBUG_OBJECT (buf, "read @%p seg %d, off %d, sampleslen %d",
1867 dest + readseg * segsize, readseg, sampleoff, sampleslen);
1870 guint8 *ptr = dest + (readseg * segsize) + (sampleoff * bpf);
1872 gint *reorder_map = buf->channel_reorder_map;
1874 /* Reorder from device order to GStreamer order */
1875 for (i = 0; i < sampleslen; i++) {
1876 for (j = 0; j < channels; j++) {
1877 memcpy (data + i * bpf + reorder_map[j] * bps, ptr + j * bps, bps);
1882 memcpy (data, dest + (readseg * segsize) + (sampleoff * bpf),
1883 (sampleslen * bpf));
1887 to_read -= sampleslen;
1888 sample += sampleslen;
1889 data += sampleslen * bpf;
1892 if (buf->timestamps && timestamp) {
1893 *timestamp = buf->timestamps[readseg % segtotal];
1894 GST_DEBUG_OBJECT (buf, "Retrieved timestamp %" GST_TIME_FORMAT
1895 " @ %d", GST_TIME_ARGS (*timestamp), readseg % segtotal);
1898 return len - to_read;
1903 GST_DEBUG_OBJECT (buf, "stopped processing");
1904 return len - to_read;
1909 * gst_audio_ring_buffer_prepare_read:
1910 * @buf: the #GstAudioRingBuffer to read from
1911 * @segment: (out): the segment to read
1912 * @readptr: (out) (array length=len):
1913 * the pointer to the memory where samples can be read
1914 * @len: (out): the number of bytes to read
1916 * Returns a pointer to memory where the data from segment @segment
1917 * can be found. This function is mostly used by subclasses.
1919 * Returns: FALSE if the buffer is not started.
1924 gst_audio_ring_buffer_prepare_read (GstAudioRingBuffer * buf, gint * segment,
1925 guint8 ** readptr, gint * len)
1930 g_return_val_if_fail (GST_IS_AUDIO_RING_BUFFER (buf), FALSE);
1932 if (buf->callback == NULL) {
1933 /* push mode, fail when nothing is started */
1934 if (g_atomic_int_get (&buf->state) != GST_AUDIO_RING_BUFFER_STATE_STARTED)
1938 g_return_val_if_fail (buf->memory != NULL, FALSE);
1939 g_return_val_if_fail (segment != NULL, FALSE);
1940 g_return_val_if_fail (readptr != NULL, FALSE);
1941 g_return_val_if_fail (len != NULL, FALSE);
1945 /* get the position of the pointer */
1946 segdone = g_atomic_int_get (&buf->segdone);
1948 *segment = segdone % buf->spec.segtotal;
1949 *len = buf->spec.segsize;
1950 *readptr = data + *segment * *len;
1952 GST_LOG_OBJECT (buf, "prepare read from segment %d (real %d) @%p",
1953 *segment, segdone, *readptr);
1955 /* callback to fill the memory with data, for pull based
1958 buf->callback (buf, *readptr, *len, buf->cb_data);
1964 * gst_audio_ring_buffer_advance:
1965 * @buf: the #GstAudioRingBuffer to advance
1966 * @advance: the number of segments written
1968 * Subclasses should call this function to notify the fact that
1969 * @advance segments are now processed by the device.
1974 gst_audio_ring_buffer_advance (GstAudioRingBuffer * buf, guint advance)
1976 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
1978 /* update counter */
1979 g_atomic_int_add (&buf->segdone, advance);
1981 /* the lock is already taken when the waiting flag is set,
1982 * we grab the lock as well to make sure the waiter is actually
1983 * waiting for the signal */
1984 if (g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0)) {
1985 GST_OBJECT_LOCK (buf);
1986 GST_DEBUG_OBJECT (buf, "signal waiter");
1987 GST_AUDIO_RING_BUFFER_SIGNAL (buf);
1988 GST_OBJECT_UNLOCK (buf);
1993 * gst_audio_ring_buffer_clear:
1994 * @buf: the #GstAudioRingBuffer to clear
1995 * @segment: the segment to clear
1997 * Clear the given segment of the buffer with silence samples.
1998 * This function is used by subclasses.
2003 gst_audio_ring_buffer_clear (GstAudioRingBuffer * buf, gint segment)
2007 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
2009 /* no data means it's already cleared */
2010 if (G_UNLIKELY (buf->memory == NULL))
2013 /* no empty_seg means it's not opened */
2014 if (G_UNLIKELY (buf->empty_seg == NULL))
2017 segment %= buf->spec.segtotal;
2020 data += segment * buf->spec.segsize;
2022 GST_LOG_OBJECT (buf, "clear segment %d @%p", segment, data);
2024 memcpy (data, buf->empty_seg, buf->spec.segsize);
2028 * gst_audio_ring_buffer_may_start:
2029 * @buf: the #GstAudioRingBuffer
2030 * @allowed: the new value
2032 * Tell the ringbuffer that it is allowed to start playback when
2033 * the ringbuffer is filled with samples.
2038 gst_audio_ring_buffer_may_start (GstAudioRingBuffer * buf, gboolean allowed)
2040 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
2042 GST_LOG_OBJECT (buf, "may start: %d", allowed);
2043 g_atomic_int_set (&buf->may_start, allowed);
2046 /* GST_AUDIO_CHANNEL_POSITION_NONE is used for position-less
2047 * mutually exclusive channels. In this case we should not attempt
2048 * to do any reordering.
2051 position_less_channels (const GstAudioChannelPosition * pos, guint channels)
2055 for (i = 0; i < channels; i++) {
2056 if (pos[i] != GST_AUDIO_CHANNEL_POSITION_NONE)
2064 * gst_audio_ring_buffer_set_channel_positions:
2065 * @buf: the #GstAudioRingBuffer
2066 * @position: (array): the device channel positions
2068 * Tell the ringbuffer about the device's channel positions. This must
2069 * be called in when the ringbuffer is acquired.
2072 gst_audio_ring_buffer_set_channel_positions (GstAudioRingBuffer * buf,
2073 const GstAudioChannelPosition * position)
2075 const GstAudioChannelPosition *to;
2079 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
2080 g_return_if_fail (buf->acquired);
2082 channels = buf->spec.info.channels;
2083 to = buf->spec.info.position;
2085 buf->need_reorder = FALSE;
2086 if (memcmp (position, to, channels * sizeof (to[0])) == 0)
2089 if (channels == 1) {
2090 GST_LOG_OBJECT (buf, "single channel, no need to reorder");
2094 if (position_less_channels (position, channels)) {
2095 GST_LOG_OBJECT (buf, "position-less channels, no need to reorder");
2099 if (!gst_audio_get_channel_reorder_map (channels, position, to,
2100 buf->channel_reorder_map))
2101 g_return_if_reached ();
2103 for (i = 0; i < channels; i++) {
2104 if (buf->channel_reorder_map[i] != i) {
2105 #ifndef GST_DISABLE_GST_DEBUG
2109 tmp1 = gst_audio_channel_positions_to_string (position, channels);
2110 tmp2 = gst_audio_channel_positions_to_string (to, channels);
2111 GST_LOG_OBJECT (buf, "may have to reorder channels: %s -> %s", tmp1,
2116 #endif /* GST_DISABLE_GST_DEBUG */
2118 buf->need_reorder = TRUE;
2125 * gst_ring_buffer_set_timestamp:
2126 * @buf: the #GstRingBuffer
2127 * @readseg: the current data segment
2128 * @timestamp: The new timestamp of the buffer.
2130 * Set a new timestamp on the buffer.
2135 gst_audio_ring_buffer_set_timestamp (GstAudioRingBuffer * buf, gint readseg,
2136 GstClockTime timestamp)
2138 g_return_if_fail (GST_IS_AUDIO_RING_BUFFER (buf));
2140 GST_DEBUG_OBJECT (buf, "Storing timestamp %" GST_TIME_FORMAT
2141 " @ %d", GST_TIME_ARGS (timestamp), readseg);
2143 GST_OBJECT_LOCK (buf);
2144 if (G_UNLIKELY (!buf->acquired))
2147 buf->timestamps[readseg] = timestamp;
2150 GST_OBJECT_UNLOCK (buf);
2155 GST_DEBUG_OBJECT (buf, "we are not acquired");