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., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * SECTION:gstringbuffer
22 * @short_description: Base class for audio ringbuffer implementations
23 * @see_also: gstbaseaudiosink
27 * This object is the base class for audio ringbuffers used by the base
28 * audio source and sink classes.
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
39 * Last reviewed on 2006-02-02 (0.10.4)
44 #include "gstringbuffer.h"
46 GST_DEBUG_CATEGORY_STATIC (gst_ring_buffer_debug);
47 #define GST_CAT_DEFAULT gst_ring_buffer_debug
49 static void gst_ring_buffer_class_init (GstRingBufferClass * klass);
50 static void gst_ring_buffer_init (GstRingBuffer * ringbuffer);
51 static void gst_ring_buffer_dispose (GObject * object);
52 static void gst_ring_buffer_finalize (GObject * object);
54 static gboolean gst_ring_buffer_pause_unlocked (GstRingBuffer * buf);
56 static GstObjectClass *parent_class = NULL;
58 /* ringbuffer abstract base class */
60 gst_ring_buffer_get_type (void)
62 static GType ringbuffer_type = 0;
64 if (G_UNLIKELY (!ringbuffer_type)) {
65 static const GTypeInfo ringbuffer_info = {
66 sizeof (GstRingBufferClass),
69 (GClassInitFunc) gst_ring_buffer_class_init,
72 sizeof (GstRingBuffer),
74 (GInstanceInitFunc) gst_ring_buffer_init,
78 ringbuffer_type = g_type_register_static (GST_TYPE_OBJECT, "GstRingBuffer",
79 &ringbuffer_info, G_TYPE_FLAG_ABSTRACT);
81 GST_DEBUG_CATEGORY_INIT (gst_ring_buffer_debug, "ringbuffer", 0,
84 return ringbuffer_type;
88 gst_ring_buffer_class_init (GstRingBufferClass * klass)
90 GObjectClass *gobject_class;
91 GstObjectClass *gstobject_class;
93 gobject_class = (GObjectClass *) klass;
94 gstobject_class = (GstObjectClass *) klass;
96 parent_class = g_type_class_peek_parent (klass);
98 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ring_buffer_dispose);
99 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_ring_buffer_finalize);
103 gst_ring_buffer_init (GstRingBuffer * ringbuffer)
105 ringbuffer->open = FALSE;
106 ringbuffer->acquired = FALSE;
107 ringbuffer->state = GST_RING_BUFFER_STATE_STOPPED;
108 ringbuffer->cond = g_cond_new ();
109 ringbuffer->waiting = 0;
110 ringbuffer->empty_seg = NULL;
111 ringbuffer->abidata.ABI.flushing = TRUE;
115 gst_ring_buffer_dispose (GObject * object)
117 GstRingBuffer *ringbuffer = GST_RING_BUFFER (object);
119 G_OBJECT_CLASS (parent_class)->dispose (G_OBJECT (ringbuffer));
123 gst_ring_buffer_finalize (GObject * object)
125 GstRingBuffer *ringbuffer = GST_RING_BUFFER (object);
127 g_cond_free (ringbuffer->cond);
128 g_free (ringbuffer->empty_seg);
130 G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (ringbuffer));
133 static const int linear_formats[4 * 2 * 2] = {
152 static const int linear24_formats[3 * 2 * 2] = {
167 static GstBufferFormat
168 build_linear_format (int depth, int width, int unsignd, int big_endian)
175 formats = &linear24_formats[0];
178 formats = &linear24_formats[4];
181 formats = &linear24_formats[8];
189 formats = &linear_formats[0];
192 formats = &linear_formats[4];
195 formats = &linear_formats[8];
198 formats = &linear_formats[12];
208 return (GstBufferFormat) * formats;
212 * gst_ring_buffer_debug_spec_caps:
213 * @spec: the spec to debug
215 * Print debug info about the parsed caps in @spec to the debug log.
218 gst_ring_buffer_debug_spec_caps (GstRingBufferSpec * spec)
220 GST_DEBUG ("spec caps: %p %" GST_PTR_FORMAT, spec->caps, spec->caps);
221 GST_DEBUG ("parsed caps: type: %d", spec->type);
222 GST_DEBUG ("parsed caps: format: %d", spec->format);
223 GST_DEBUG ("parsed caps: width: %d", spec->width);
224 GST_DEBUG ("parsed caps: depth: %d", spec->depth);
225 GST_DEBUG ("parsed caps: sign: %d", spec->sign);
226 GST_DEBUG ("parsed caps: bigend: %d", spec->bigend);
227 GST_DEBUG ("parsed caps: rate: %d", spec->rate);
228 GST_DEBUG ("parsed caps: channels: %d", spec->channels);
229 GST_DEBUG ("parsed caps: sample bytes: %d", spec->bytes_per_sample);
233 * gst_ring_buffer_debug_spec_buff:
234 * @spec: the spec to debug
236 * Print debug info about the buffer sized in @spec to the debug log.
239 gst_ring_buffer_debug_spec_buff (GstRingBufferSpec * spec)
241 GST_DEBUG ("acquire ringbuffer: buffer time: %" G_GINT64_FORMAT " usec",
243 GST_DEBUG ("acquire ringbuffer: latency time: %" G_GINT64_FORMAT " usec",
245 GST_DEBUG ("acquire ringbuffer: total segments: %d", spec->segtotal);
246 GST_DEBUG ("acquire ringbuffer: segment size: %d bytes = %d samples",
247 spec->segsize, spec->segsize / spec->bytes_per_sample);
248 GST_DEBUG ("acquire ringbuffer: buffer size: %d bytes = %d samples",
249 spec->segsize * spec->segtotal,
250 spec->segsize * spec->segtotal / spec->bytes_per_sample);
254 * gst_ring_buffer_parse_caps:
258 * Parse @caps into @spec.
260 * Returns: TRUE if the caps could be parsed.
263 gst_ring_buffer_parse_caps (GstRingBufferSpec * spec, GstCaps * caps)
265 const gchar *mimetype;
266 GstStructure *structure;
268 structure = gst_caps_get_structure (caps, 0);
270 /* we have to differentiate between int and float formats */
271 mimetype = gst_structure_get_name (structure);
273 if (!strncmp (mimetype, "audio/x-raw-int", 15)) {
276 spec->type = GST_BUFTYPE_LINEAR;
278 /* extract the needed information from the cap */
279 if (!(gst_structure_get_int (structure, "width", &spec->width) &&
280 gst_structure_get_int (structure, "depth", &spec->depth) &&
281 gst_structure_get_boolean (structure, "signed", &spec->sign)))
284 /* extract endianness if needed */
285 if (spec->width > 8) {
286 if (!gst_structure_get_int (structure, "endianness", &endianness))
289 endianness = G_BYTE_ORDER;
292 spec->bigend = endianness == G_LITTLE_ENDIAN ? FALSE : TRUE;
295 build_linear_format (spec->depth, spec->width, spec->sign ? 0 : 1,
296 spec->bigend ? 1 : 0);
297 } else if (!strncmp (mimetype, "audio/x-raw-float", 17)) {
299 spec->type = GST_BUFTYPE_FLOAT;
302 if (!gst_structure_get_int (structure, "width", &spec->width))
305 /* match layout to format wrt to endianness */
306 switch (spec->width) {
309 G_BYTE_ORDER == G_LITTLE_ENDIAN ? GST_FLOAT32_LE : GST_FLOAT32_BE;
313 G_BYTE_ORDER == G_LITTLE_ENDIAN ? GST_FLOAT64_LE : GST_FLOAT64_BE;
318 } else if (!strncmp (mimetype, "audio/x-alaw", 12)) {
319 spec->type = GST_BUFTYPE_A_LAW;
320 spec->format = GST_A_LAW;
323 } else if (!strncmp (mimetype, "audio/x-mulaw", 13)) {
324 spec->type = GST_BUFTYPE_MU_LAW;
325 spec->format = GST_MU_LAW;
332 /* get rate and channels */
333 if (!(gst_structure_get_int (structure, "rate", &spec->rate) &&
334 gst_structure_get_int (structure, "channels", &spec->channels)))
337 spec->bytes_per_sample = (spec->width >> 3) * spec->channels;
339 gst_caps_replace (&spec->caps, caps);
341 g_return_val_if_fail (spec->latency_time != 0, FALSE);
343 /* calculate suggested segsize and segtotal. segsize should be one unit
344 * of 'latency_time' samples, scaling for the fact that latency_time is
345 * currently stored in microseconds (FIXME: in 0.11) */
346 spec->segsize = gst_util_uint64_scale (spec->rate * spec->bytes_per_sample,
347 spec->latency_time, GST_SECOND / GST_USECOND);
348 /* Round to an integer number of samples */
349 spec->segsize -= spec->segsize % spec->bytes_per_sample;
351 spec->segtotal = spec->buffer_time / spec->latency_time;
353 gst_ring_buffer_debug_spec_caps (spec);
354 gst_ring_buffer_debug_spec_buff (spec);
361 GST_DEBUG ("could not parse caps");
367 * gst_ring_buffer_set_callback:
368 * @buf: the #GstRingBuffer to set the callback on
369 * @cb: the callback to set
370 * @user_data: user data passed to the callback
372 * Sets the given callback function on the buffer. This function
373 * will be called every time a segment has been written to a device.
378 gst_ring_buffer_set_callback (GstRingBuffer * buf, GstRingBufferCallback cb,
381 g_return_if_fail (GST_IS_RING_BUFFER (buf));
383 GST_OBJECT_LOCK (buf);
385 buf->cb_data = user_data;
386 GST_OBJECT_UNLOCK (buf);
391 * gst_ring_buffer_open_device:
392 * @buf: the #GstRingBuffer
394 * Open the audio device associated with the ring buffer. Does not perform any
395 * setup on the device. You must open the device before acquiring the ring
398 * Returns: TRUE if the device could be opened, FALSE on error.
403 gst_ring_buffer_open_device (GstRingBuffer * buf)
406 GstRingBufferClass *rclass;
408 g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
410 GST_DEBUG_OBJECT (buf, "opening device");
412 GST_OBJECT_LOCK (buf);
413 if (G_UNLIKELY (buf->open))
418 /* if this fails, something is wrong in this file */
419 g_assert (!buf->acquired);
421 rclass = GST_RING_BUFFER_GET_CLASS (buf);
422 if (G_LIKELY (rclass->open_device))
423 res = rclass->open_device (buf);
425 if (G_UNLIKELY (!res))
428 GST_DEBUG_OBJECT (buf, "opened device");
431 GST_OBJECT_UNLOCK (buf);
438 GST_DEBUG_OBJECT (buf, "Device for ring buffer already open");
439 g_warning ("Device for ring buffer %p already open, fix your code", buf);
446 GST_DEBUG_OBJECT (buf, "failed opening device");
452 * gst_ring_buffer_close_device:
453 * @buf: the #GstRingBuffer
455 * Close the audio device associated with the ring buffer. The ring buffer
456 * should already have been released via gst_ring_buffer_release().
458 * Returns: TRUE if the device could be closed, FALSE on error.
463 gst_ring_buffer_close_device (GstRingBuffer * buf)
466 GstRingBufferClass *rclass;
468 g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
470 GST_DEBUG_OBJECT (buf, "closing device");
472 GST_OBJECT_LOCK (buf);
473 if (G_UNLIKELY (!buf->open))
476 if (G_UNLIKELY (buf->acquired))
481 rclass = GST_RING_BUFFER_GET_CLASS (buf);
482 if (G_LIKELY (rclass->close_device))
483 res = rclass->close_device (buf);
485 if (G_UNLIKELY (!res))
488 GST_DEBUG_OBJECT (buf, "closed device");
491 GST_OBJECT_UNLOCK (buf);
498 GST_DEBUG_OBJECT (buf, "Device for ring buffer already closed");
499 g_warning ("Device for ring buffer %p already closed, fix your code", buf);
505 GST_DEBUG_OBJECT (buf, "Resources for ring buffer still acquired");
506 g_critical ("Resources for ring buffer %p still acquired", buf);
513 GST_DEBUG_OBJECT (buf, "error closing device");
519 * gst_ring_buffer_device_is_open:
520 * @buf: the #GstRingBuffer
522 * Checks the status of the device associated with the ring buffer.
524 * Returns: TRUE if the device was open, FALSE if it was closed.
529 gst_ring_buffer_device_is_open (GstRingBuffer * buf)
533 g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
535 GST_OBJECT_LOCK (buf);
537 GST_OBJECT_UNLOCK (buf);
544 * gst_ring_buffer_acquire:
545 * @buf: the #GstRingBuffer to acquire
546 * @spec: the specs of the buffer
548 * Allocate the resources for the ringbuffer. This function fills
549 * in the data pointer of the ring buffer with a valid #GstBuffer
550 * to which samples can be written.
552 * Returns: TRUE if the device could be acquired, FALSE on error.
557 gst_ring_buffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
559 gboolean res = FALSE;
560 GstRingBufferClass *rclass;
564 g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
566 GST_DEBUG_OBJECT (buf, "acquiring device");
568 GST_OBJECT_LOCK (buf);
569 if (G_UNLIKELY (!buf->open))
572 if (G_UNLIKELY (buf->acquired))
575 buf->acquired = TRUE;
577 rclass = GST_RING_BUFFER_GET_CLASS (buf);
578 if (G_LIKELY (rclass->acquire))
579 res = rclass->acquire (buf, spec);
581 if (G_UNLIKELY (!res))
584 if (G_UNLIKELY ((bps = buf->spec.bytes_per_sample) == 0))
587 segsize = buf->spec.segsize;
589 buf->samples_per_seg = segsize / bps;
591 /* create an empty segment */
592 g_free (buf->empty_seg);
593 buf->empty_seg = g_malloc (segsize);
594 for (i = 0, j = 0; i < segsize; i++) {
595 buf->empty_seg[i] = buf->spec.silence_sample[j];
598 GST_DEBUG_OBJECT (buf, "acquired device");
601 GST_OBJECT_UNLOCK (buf);
608 GST_DEBUG_OBJECT (buf, "device not opened");
609 g_critical ("Device for %p not opened", buf);
616 GST_DEBUG_OBJECT (buf, "device was acquired");
621 buf->acquired = FALSE;
622 GST_DEBUG_OBJECT (buf, "failed to acquire device");
628 ("invalid bytes_per_sample from acquire ringbuffer, fix the element");
629 buf->acquired = FALSE;
636 * gst_ring_buffer_release:
637 * @buf: the #GstRingBuffer to release
639 * Free the resources of the ringbuffer.
641 * Returns: TRUE if the device could be released, FALSE on error.
646 gst_ring_buffer_release (GstRingBuffer * buf)
648 gboolean res = FALSE;
649 GstRingBufferClass *rclass;
651 g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
653 GST_DEBUG_OBJECT (buf, "releasing device");
655 gst_ring_buffer_stop (buf);
657 GST_OBJECT_LOCK (buf);
658 if (G_UNLIKELY (!buf->acquired))
661 buf->acquired = FALSE;
663 /* if this fails, something is wrong in this file */
664 g_assert (buf->open == TRUE);
666 rclass = GST_RING_BUFFER_GET_CLASS (buf);
667 if (G_LIKELY (rclass->release))
668 res = rclass->release (buf);
670 /* signal any waiters */
671 GST_DEBUG_OBJECT (buf, "signal waiter");
672 GST_RING_BUFFER_SIGNAL (buf);
674 if (G_UNLIKELY (!res))
677 g_free (buf->empty_seg);
678 buf->empty_seg = NULL;
679 GST_DEBUG_OBJECT (buf, "released device");
682 GST_OBJECT_UNLOCK (buf);
690 GST_DEBUG_OBJECT (buf, "device was released");
695 buf->acquired = TRUE;
696 GST_DEBUG_OBJECT (buf, "failed to release device");
702 * gst_ring_buffer_is_acquired:
703 * @buf: the #GstRingBuffer to check
705 * Check if the ringbuffer is acquired and ready to use.
707 * Returns: TRUE if the ringbuffer is acquired, FALSE on error.
712 gst_ring_buffer_is_acquired (GstRingBuffer * buf)
716 g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
718 GST_OBJECT_LOCK (buf);
720 GST_OBJECT_UNLOCK (buf);
726 * gst_ring_buffer_set_flushing:
727 * @buf: the #GstRingBuffer to flush
729 * Set the ringbuffer to flushing mode or normal mode.
734 gst_ring_buffer_set_flushing (GstRingBuffer * buf, gboolean flushing)
736 g_return_if_fail (GST_IS_RING_BUFFER (buf));
738 GST_OBJECT_LOCK (buf);
739 buf->abidata.ABI.flushing = flushing;
741 gst_ring_buffer_clear_all (buf);
743 gst_ring_buffer_pause_unlocked (buf);
745 GST_OBJECT_UNLOCK (buf);
749 * gst_ring_buffer_start:
750 * @buf: the #GstRingBuffer to start
752 * Start processing samples from the ringbuffer.
754 * Returns: TRUE if the device could be started, FALSE on error.
759 gst_ring_buffer_start (GstRingBuffer * buf)
761 gboolean res = FALSE;
762 GstRingBufferClass *rclass;
763 gboolean resume = FALSE;
765 g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
767 GST_DEBUG_OBJECT (buf, "starting ringbuffer");
769 GST_OBJECT_LOCK (buf);
770 if (G_UNLIKELY (buf->abidata.ABI.flushing))
773 /* if stopped, set to started */
774 res = g_atomic_int_compare_and_exchange (&buf->state,
775 GST_RING_BUFFER_STATE_STOPPED, GST_RING_BUFFER_STATE_STARTED);
778 /* was not stopped, try from paused */
779 res = g_atomic_int_compare_and_exchange (&buf->state,
780 GST_RING_BUFFER_STATE_PAUSED, GST_RING_BUFFER_STATE_STARTED);
782 /* was not paused either, must be started then */
784 GST_DEBUG_OBJECT (buf, "was started");
788 GST_DEBUG_OBJECT (buf, "resuming");
791 rclass = GST_RING_BUFFER_GET_CLASS (buf);
793 if (G_LIKELY (rclass->resume))
794 res = rclass->resume (buf);
796 if (G_LIKELY (rclass->start))
797 res = rclass->start (buf);
800 if (G_UNLIKELY (!res)) {
801 buf->state = GST_RING_BUFFER_STATE_PAUSED;
802 GST_DEBUG_OBJECT (buf, "failed to start");
804 GST_DEBUG_OBJECT (buf, "started");
808 GST_OBJECT_UNLOCK (buf);
814 GST_OBJECT_UNLOCK (buf);
820 gst_ring_buffer_pause_unlocked (GstRingBuffer * buf)
822 gboolean res = FALSE;
823 GstRingBufferClass *rclass;
825 GST_DEBUG_OBJECT (buf, "pausing ringbuffer");
827 /* if started, set to paused */
828 res = g_atomic_int_compare_and_exchange (&buf->state,
829 GST_RING_BUFFER_STATE_STARTED, GST_RING_BUFFER_STATE_PAUSED);
834 /* signal any waiters */
835 GST_DEBUG_OBJECT (buf, "signal waiter");
836 GST_RING_BUFFER_SIGNAL (buf);
838 rclass = GST_RING_BUFFER_GET_CLASS (buf);
839 if (G_LIKELY (rclass->pause))
840 res = rclass->pause (buf);
842 if (G_UNLIKELY (!res)) {
843 buf->state = GST_RING_BUFFER_STATE_STARTED;
844 GST_DEBUG_OBJECT (buf, "failed to pause");
846 GST_DEBUG_OBJECT (buf, "paused");
853 /* was not started */
854 GST_DEBUG_OBJECT (buf, "was not started");
860 * gst_ring_buffer_pause:
861 * @buf: the #GstRingBuffer to pause
863 * Pause processing samples from the ringbuffer.
865 * Returns: TRUE if the device could be paused, FALSE on error.
870 gst_ring_buffer_pause (GstRingBuffer * buf)
872 gboolean res = FALSE;
874 g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
876 GST_OBJECT_LOCK (buf);
877 if (G_UNLIKELY (buf->abidata.ABI.flushing))
880 res = gst_ring_buffer_pause_unlocked (buf);
881 GST_OBJECT_UNLOCK (buf);
887 GST_OBJECT_UNLOCK (buf);
893 * gst_ring_buffer_stop:
894 * @buf: the #GstRingBuffer to stop
896 * Stop processing samples from the ringbuffer.
898 * Returns: TRUE if the device could be stopped, FALSE on error.
903 gst_ring_buffer_stop (GstRingBuffer * buf)
905 gboolean res = FALSE;
906 GstRingBufferClass *rclass;
908 g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
910 GST_DEBUG_OBJECT (buf, "stopping");
912 GST_OBJECT_LOCK (buf);
914 /* if started, set to stopped */
915 res = g_atomic_int_compare_and_exchange (&buf->state,
916 GST_RING_BUFFER_STATE_STARTED, GST_RING_BUFFER_STATE_STOPPED);
919 /* was not started, must be stopped then */
920 GST_DEBUG_OBJECT (buf, "was not started");
925 /* signal any waiters */
926 GST_DEBUG_OBJECT (buf, "signal waiter");
927 GST_RING_BUFFER_SIGNAL (buf);
929 rclass = GST_RING_BUFFER_GET_CLASS (buf);
930 if (G_LIKELY (rclass->stop))
931 res = rclass->stop (buf);
933 if (G_UNLIKELY (!res)) {
934 buf->state = GST_RING_BUFFER_STATE_STARTED;
935 GST_DEBUG_OBJECT (buf, "failed to stop");
937 GST_DEBUG_OBJECT (buf, "stopped");
940 GST_OBJECT_UNLOCK (buf);
946 * gst_ring_buffer_delay:
947 * @buf: the #GstRingBuffer to query
949 * Get the number of samples queued in the audio device. This is
950 * usually less than the segment size but can be bigger when the
951 * implementation uses another internal buffer between the audio
954 * Returns: The number of samples queued in the audio device.
959 gst_ring_buffer_delay (GstRingBuffer * buf)
961 GstRingBufferClass *rclass;
964 g_return_val_if_fail (GST_IS_RING_BUFFER (buf), 0);
968 /* buffer must be acquired */
969 if (G_UNLIKELY (!gst_ring_buffer_is_acquired (buf)))
972 rclass = GST_RING_BUFFER_GET_CLASS (buf);
973 if (G_LIKELY (rclass->delay))
974 res = rclass->delay (buf);
981 * gst_ring_buffer_samples_done:
982 * @buf: the #GstRingBuffer to query
984 * Get the number of samples that were processed by the ringbuffer
985 * since it was last started.
987 * Returns: The number of samples processed by the ringbuffer.
992 gst_ring_buffer_samples_done (GstRingBuffer * buf)
995 guint64 raw, samples;
998 g_return_val_if_fail (GST_IS_RING_BUFFER (buf), 0);
1000 /* get the amount of segments we processed */
1001 segdone = g_atomic_int_get (&buf->segdone);
1003 /* and the number of samples not yet processed */
1004 delay = gst_ring_buffer_delay (buf);
1006 raw = samples = ((guint64) segdone) * buf->samples_per_seg;
1008 if (G_LIKELY (samples >= delay))
1013 GST_DEBUG_OBJECT (buf, "processed samples: raw %llu, delay %u, real %llu",
1014 raw, delay, samples);
1020 * gst_ring_buffer_set_sample:
1021 * @buf: the #GstRingBuffer to use
1022 * @sample: the sample number to set
1024 * Make sure that the next sample written to the device is
1025 * accounted for as being the @sample sample written to the
1026 * device. This value will be used in reporting the current
1027 * sample position of the ringbuffer.
1029 * This function will also clear the buffer with silence.
1034 gst_ring_buffer_set_sample (GstRingBuffer * buf, guint64 sample)
1036 g_return_if_fail (GST_IS_RING_BUFFER (buf));
1041 if (G_UNLIKELY (buf->samples_per_seg == 0))
1044 /* FIXME, we assume the ringbuffer can restart at a random
1045 * position, round down to the beginning and keep track of
1046 * offset when calculating the processed samples. */
1047 buf->segbase = buf->segdone - sample / buf->samples_per_seg;
1049 gst_ring_buffer_clear_all (buf);
1051 GST_DEBUG_OBJECT (buf, "set sample to %llu, segbase %d", sample,
1056 * gst_ring_buffer_clear_all:
1057 * @buf: the #GstRingBuffer to clear
1059 * Fill the ringbuffer with silence.
1064 gst_ring_buffer_clear_all (GstRingBuffer * buf)
1068 g_return_if_fail (GST_IS_RING_BUFFER (buf));
1070 /* not fatal, we just are not negotiated yet */
1071 if (G_UNLIKELY (buf->spec.segtotal <= 0))
1074 GST_DEBUG_OBJECT (buf, "clear all segments");
1076 for (i = 0; i < buf->spec.segtotal; i++) {
1077 gst_ring_buffer_clear (buf, i);
1083 wait_segment (GstRingBuffer * buf)
1085 /* buffer must be started now or we deadlock since nobody is reading */
1086 if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1087 GST_RING_BUFFER_STATE_STARTED)) {
1088 /* see if we are allowed to start it */
1089 if (G_UNLIKELY (g_atomic_int_get (&buf->abidata.ABI.may_start) == FALSE))
1092 GST_DEBUG_OBJECT (buf, "start!");
1093 gst_ring_buffer_start (buf);
1096 /* take lock first, then update our waiting flag */
1097 GST_OBJECT_LOCK (buf);
1098 if (G_UNLIKELY (buf->abidata.ABI.flushing))
1101 if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1102 GST_RING_BUFFER_STATE_STARTED))
1105 if (g_atomic_int_compare_and_exchange (&buf->waiting, 0, 1)) {
1106 GST_DEBUG_OBJECT (buf, "waiting..");
1107 GST_RING_BUFFER_WAIT (buf);
1109 if (G_UNLIKELY (buf->abidata.ABI.flushing))
1112 if (G_UNLIKELY (g_atomic_int_get (&buf->state) !=
1113 GST_RING_BUFFER_STATE_STARTED))
1116 GST_OBJECT_UNLOCK (buf);
1123 g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0);
1124 GST_DEBUG_OBJECT (buf, "stopped processing");
1125 GST_OBJECT_UNLOCK (buf);
1130 g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0);
1131 GST_DEBUG_OBJECT (buf, "flushing");
1132 GST_OBJECT_UNLOCK (buf);
1137 GST_DEBUG_OBJECT (buf, "not allowed to start");
1143 * gst_ring_buffer_commit:
1144 * @buf: the #GstRingBuffer to commit
1145 * @sample: the sample position of the data
1146 * @data: the data to commit
1147 * @len: the number of samples in the data to commit
1149 * Commit @len samples pointed to by @data to the ringbuffer
1150 * @buf. The first sample should be written at position @sample in
1153 * @len does not need to be a multiple of the segment size of the ringbuffer
1154 * although it is recommended for optimal performance.
1156 * Returns: The number of samples written to the ringbuffer or -1 on
1162 gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
1166 gint segsize, segtotal, bps, sps;
1170 g_return_val_if_fail (GST_IS_RING_BUFFER (buf), -1);
1171 g_return_val_if_fail (buf->data != NULL, -1);
1172 g_return_val_if_fail (data != NULL, -1);
1174 dest = GST_BUFFER_DATA (buf->data);
1175 segsize = buf->spec.segsize;
1176 segtotal = buf->spec.segtotal;
1177 bps = buf->spec.bytes_per_sample;
1178 sps = buf->samples_per_seg;
1181 /* write out all samples */
1182 while (to_write > 0) {
1184 gint writeseg, sampleoff;
1186 /* figure out the segment and the offset inside the segment where
1187 * the sample should be written. */
1188 writeseg = sample / sps;
1189 sampleoff = (sample % sps);
1194 /* get the currently processed segment */
1195 segdone = g_atomic_int_get (&buf->segdone) - buf->segbase;
1197 /* see how far away it is from the write segment */
1198 diff = writeseg - segdone;
1201 ("pointer at %d, sample %llu, write to %d-%d, to_write %d, diff %d, segtotal %d, segsize %d",
1202 segdone, sample, writeseg, sampleoff, to_write, diff, segtotal, sps);
1204 /* segment too far ahead, we need to drop, hopefully UNLIKELY */
1205 if (G_UNLIKELY (diff < 0)) {
1206 /* we need to drop one segment at a time, pretend we wrote a
1208 sampleslen = MIN (sps, to_write);
1212 /* write segment is within writable range, we can break the loop and
1213 * start writing the data. */
1214 if (diff < segtotal)
1217 /* else we need to wait for the segment to become writable. */
1218 if (!wait_segment (buf))
1222 /* we can write now */
1223 writeseg = writeseg % segtotal;
1224 sampleslen = MIN (sps - sampleoff, to_write);
1226 GST_DEBUG_OBJECT (buf, "write @%p seg %d, off %d, sampleslen %d",
1227 dest + writeseg * segsize, writeseg, sampleoff, sampleslen);
1229 memcpy (dest + (writeseg * segsize) + (sampleoff * bps), data,
1230 (sampleslen * bps));
1233 to_write -= sampleslen;
1234 sample += sampleslen;
1235 data += sampleslen * bps;
1238 return len - to_write;
1243 GST_DEBUG_OBJECT (buf, "stopped processing");
1244 return len - to_write;
1249 * gst_ring_buffer_read:
1250 * @buf: the #GstRingBuffer to read from
1251 * @sample: the sample position of the data
1252 * @data: where the data should be read
1253 * @len: the number of samples in data to read
1255 * Read @len samples from the ringbuffer into the memory pointed
1257 * The first sample should be read from position @sample in
1260 * @len should not be a multiple of the segment size of the ringbuffer
1261 * although it is recommended.
1263 * Returns: The number of samples read from the ringbuffer or -1 on
1269 gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data,
1273 gint segsize, segtotal, bps, sps;
1276 g_return_val_if_fail (GST_IS_RING_BUFFER (buf), -1);
1277 g_return_val_if_fail (buf->data != NULL, -1);
1278 g_return_val_if_fail (data != NULL, -1);
1280 dest = GST_BUFFER_DATA (buf->data);
1281 segsize = buf->spec.segsize;
1282 segtotal = buf->spec.segtotal;
1283 bps = buf->spec.bytes_per_sample;
1284 sps = buf->samples_per_seg;
1286 /* read enough samples */
1289 gint readseg, sampleoff;
1291 /* figure out the segment and the offset inside the segment where
1292 * the sample should be written. */
1293 readseg = sample / sps;
1294 sampleoff = (sample % sps);
1299 /* get the currently processed segment */
1300 segdone = g_atomic_int_get (&buf->segdone) - buf->segbase;
1302 /* see how far away it is from the read segment */
1303 diff = segdone - readseg;
1306 ("pointer at %d, sample %llu, read from %d-%d, len %d, diff %d, segtotal %d, segsize %d",
1307 segdone, sample, readseg, sampleoff, len, diff, segtotal, segsize);
1309 /* segment too far ahead, we need to drop */
1311 /* we need to drop one segment at a time, pretend we read an
1313 sampleslen = MIN (sps, len);
1314 memcpy (data, buf->empty_seg, sampleslen * bps);
1318 /* read segment is within readable range, we can break the loop and
1319 * start reading the data. */
1320 if (diff > 0 && diff < segtotal)
1323 /* flush if diff has grown bigger than ringbuffer */
1324 if (diff >= segtotal) {
1325 gst_ring_buffer_clear_all (buf);
1326 buf->segdone = readseg;
1329 /* else we need to wait for the segment to become readable. */
1330 if (!wait_segment (buf))
1334 /* we can read now */
1335 readseg = readseg % segtotal;
1336 sampleslen = MIN (sps - sampleoff, len);
1338 GST_DEBUG_OBJECT (buf, "read @%p seg %d, off %d, len %d",
1339 dest + readseg * segsize, readseg, sampleoff, sampleslen);
1341 memcpy (data, dest + (readseg * segsize) + (sampleoff * bps),
1342 (sampleslen * bps));
1346 sample += sampleslen;
1347 data += sampleslen * bps;
1355 GST_DEBUG_OBJECT (buf, "stopped processing");
1361 * gst_ring_buffer_prepare_read:
1362 * @buf: the #GstRingBuffer to read from
1363 * @segment: the segment to read
1364 * @readptr: the pointer to the memory where samples can be read
1365 * @len: the number of bytes to read
1367 * Returns a pointer to memory where the data from segment @segment
1368 * can be found. This function is mostly used by subclasses.
1370 * Returns: FALSE if the buffer is not started.
1375 gst_ring_buffer_prepare_read (GstRingBuffer * buf, gint * segment,
1376 guint8 ** readptr, gint * len)
1381 g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
1383 /* buffer must be started */
1384 if (g_atomic_int_get (&buf->state) != GST_RING_BUFFER_STATE_STARTED)
1387 g_return_val_if_fail (buf->data != NULL, FALSE);
1388 g_return_val_if_fail (segment != NULL, FALSE);
1389 g_return_val_if_fail (readptr != NULL, FALSE);
1390 g_return_val_if_fail (len != NULL, FALSE);
1392 data = GST_BUFFER_DATA (buf->data);
1394 /* get the position of the pointer */
1395 segdone = g_atomic_int_get (&buf->segdone);
1397 *segment = segdone % buf->spec.segtotal;
1398 *len = buf->spec.segsize;
1399 *readptr = data + *segment * *len;
1401 /* callback to fill the memory with data, for pull based
1404 buf->callback (buf, *readptr, *len, buf->cb_data);
1406 GST_LOG ("prepare read from segment %d (real %d) @%p",
1407 *segment, segdone, *readptr);
1413 * gst_ring_buffer_advance:
1414 * @buf: the #GstRingBuffer to advance
1415 * @advance: the number of segments written
1417 * Subclasses should call this function to notify the fact that
1418 * @advance segments are now processed by the device.
1423 gst_ring_buffer_advance (GstRingBuffer * buf, guint advance)
1425 g_return_if_fail (GST_IS_RING_BUFFER (buf));
1427 /* update counter */
1428 g_atomic_int_add (&buf->segdone, advance);
1430 /* the lock is already taken when the waiting flag is set,
1431 * we grab the lock as well to make sure the waiter is actually
1432 * waiting for the signal */
1433 if (g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0)) {
1434 GST_OBJECT_LOCK (buf);
1435 GST_DEBUG_OBJECT (buf, "signal waiter");
1436 GST_RING_BUFFER_SIGNAL (buf);
1437 GST_OBJECT_UNLOCK (buf);
1442 * gst_ring_buffer_clear:
1443 * @buf: the #GstRingBuffer to clear
1444 * @segment: the segment to clear
1446 * Clear the given segment of the buffer with silence samples.
1447 * This function is used by subclasses.
1452 gst_ring_buffer_clear (GstRingBuffer * buf, gint segment)
1456 g_return_if_fail (GST_IS_RING_BUFFER (buf));
1458 /* no data means it's already cleared */
1459 if (G_UNLIKELY (buf->data == NULL))
1462 /* no empty_seg means it's not opened */
1463 if (G_UNLIKELY (buf->empty_seg == NULL))
1466 segment %= buf->spec.segtotal;
1468 data = GST_BUFFER_DATA (buf->data);
1469 data += segment * buf->spec.segsize;
1471 GST_LOG ("clear segment %d @%p", segment, data);
1473 memcpy (data, buf->empty_seg, buf->spec.segsize);
1477 * gst_ring_buffer_may_start:
1478 * @buf: the #GstRingBuffer
1479 * @allowed: the new value
1481 * Tell the ringbuffer that it is allowed to start playback when
1482 * the ringbuffer is filled with samples.
1489 gst_ring_buffer_may_start (GstRingBuffer * buf, gboolean allowed)
1491 g_return_if_fail (GST_IS_RING_BUFFER (buf));
1493 GST_LOG_OBJECT (buf, "may start: %d", allowed);
1494 gst_atomic_int_set (&buf->abidata.ABI.may_start, allowed);