mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
gst-libs/gst/audio/TODO: Updated TODO
Original commit message from CVS: * gst-libs/gst/audio/TODO: Updated TODO * gst-libs/gst/audio/gstaudiosink.c: (gst_audioringbuffer_open_device), (gst_audioringbuffer_close_device), (gst_audioringbuffer_acquire), (gst_audioringbuffer_release): Small cleanups. * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_class_init), (gst_base_audio_sink_render), (gst_base_audio_sink_change_state): Slave to the master clock when going to PLAYING and unslave when going to PAUSED. * gst-libs/gst/audio/gstringbuffer.c: (gst_ring_buffer_open_device), (gst_ring_buffer_close_device), (gst_ring_buffer_acquire), (gst_ring_buffer_release), (gst_ring_buffer_samples_done), (gst_ring_buffer_set_sample), (gst_ring_buffer_clear_all), (wait_segment), (gst_ring_buffer_commit), (gst_ring_buffer_read), (gst_ring_buffer_advance): * gst-libs/gst/audio/gstringbuffer.h: Add some docs and cleanups.
This commit is contained in:
parent
0767718887
commit
3f05db1828
6 changed files with 283 additions and 116 deletions
27
ChangeLog
27
ChangeLog
|
@ -1,3 +1,30 @@
|
|||
2005-11-28 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst-libs/gst/audio/TODO:
|
||||
Updated TODO
|
||||
|
||||
* gst-libs/gst/audio/gstaudiosink.c:
|
||||
(gst_audioringbuffer_open_device),
|
||||
(gst_audioringbuffer_close_device), (gst_audioringbuffer_acquire),
|
||||
(gst_audioringbuffer_release):
|
||||
Small cleanups.
|
||||
|
||||
* gst-libs/gst/audio/gstbaseaudiosink.c:
|
||||
(gst_base_audio_sink_class_init), (gst_base_audio_sink_render),
|
||||
(gst_base_audio_sink_change_state):
|
||||
Slave to the master clock when going to PLAYING and unslave when
|
||||
going to PAUSED.
|
||||
|
||||
* gst-libs/gst/audio/gstringbuffer.c:
|
||||
(gst_ring_buffer_open_device), (gst_ring_buffer_close_device),
|
||||
(gst_ring_buffer_acquire), (gst_ring_buffer_release),
|
||||
(gst_ring_buffer_samples_done), (gst_ring_buffer_set_sample),
|
||||
(gst_ring_buffer_clear_all), (wait_segment),
|
||||
(gst_ring_buffer_commit), (gst_ring_buffer_read),
|
||||
(gst_ring_buffer_advance):
|
||||
* gst-libs/gst/audio/gstringbuffer.h:
|
||||
Add some docs and cleanups.
|
||||
|
||||
2005-11-28 Julien MOUTTE <julien@moutte.net>
|
||||
|
||||
* sys/xvimage/xvimagesink.c:
|
||||
|
|
|
@ -8,3 +8,8 @@ TODO
|
|||
- implement seek/query/convert
|
||||
- implement getrange scheduling
|
||||
- on EOS, only post EOS when the complete ringbuffer has been played.
|
||||
- more accurate clipping of samples outside of the segment
|
||||
- simple resampling
|
||||
- more accurate master/slave calibration handling
|
||||
- faster audio cutoff when going to PAUSED
|
||||
- resubmit samples from ringbuffer when doing PAUSED->PLAYING again
|
||||
|
|
|
@ -264,6 +264,7 @@ gst_audioringbuffer_open_device (GstRingBuffer * buf)
|
|||
|
||||
could_not_open:
|
||||
{
|
||||
GST_DEBUG ("could not open device");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -282,12 +283,13 @@ gst_audioringbuffer_close_device (GstRingBuffer * buf)
|
|||
result = csink->close (sink);
|
||||
|
||||
if (!result)
|
||||
goto could_not_open;
|
||||
goto could_not_close;
|
||||
|
||||
return result;
|
||||
|
||||
could_not_open:
|
||||
could_not_close:
|
||||
{
|
||||
GST_DEBUG ("could not close device");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -307,7 +309,7 @@ gst_audioringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
|
|||
result = csink->prepare (sink, spec);
|
||||
|
||||
if (!result)
|
||||
goto could_not_open;
|
||||
goto could_not_prepare;
|
||||
|
||||
/* allocate one more segment as we need some headroom */
|
||||
spec->segtotal++;
|
||||
|
@ -325,8 +327,9 @@ gst_audioringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
|
|||
|
||||
return result;
|
||||
|
||||
could_not_open:
|
||||
could_not_prepare:
|
||||
{
|
||||
GST_DEBUG ("could not prepare device");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -360,7 +363,16 @@ gst_audioringbuffer_release (GstRingBuffer * buf)
|
|||
if (csink->unprepare)
|
||||
result = csink->unprepare (sink);
|
||||
|
||||
if (!result)
|
||||
goto could_not_unprepare;
|
||||
|
||||
return result;
|
||||
|
||||
could_not_unprepare:
|
||||
{
|
||||
GST_DEBUG ("could not unprepare device");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
@ -68,8 +68,6 @@ static GstStateChangeReturn gst_base_audio_sink_change_state (GstElement *
|
|||
element, GstStateChange transition);
|
||||
|
||||
static GstClock *gst_base_audio_sink_provide_clock (GstElement * elem);
|
||||
static gboolean gst_base_audio_sink_set_clock (GstElement * elem,
|
||||
GstClock * clock);
|
||||
static GstClockTime gst_base_audio_sink_get_time (GstClock * clock,
|
||||
GstBaseAudioSink * sink);
|
||||
static void gst_base_audio_sink_callback (GstRingBuffer * rbuf, guint8 * data,
|
||||
|
@ -127,8 +125,6 @@ gst_base_audio_sink_class_init (GstBaseAudioSinkClass * klass)
|
|||
GST_DEBUG_FUNCPTR (gst_base_audio_sink_change_state);
|
||||
gstelement_class->provide_clock =
|
||||
GST_DEBUG_FUNCPTR (gst_base_audio_sink_provide_clock);
|
||||
gstelement_class->set_clock =
|
||||
GST_DEBUG_FUNCPTR (gst_base_audio_sink_set_clock);
|
||||
|
||||
gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_base_audio_sink_event);
|
||||
gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_base_audio_sink_preroll);
|
||||
|
@ -184,25 +180,6 @@ gst_base_audio_sink_provide_clock (GstElement * elem)
|
|||
return clock;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_base_audio_sink_set_clock (GstElement * elem, GstClock * clock)
|
||||
{
|
||||
GstBaseAudioSink *sink;
|
||||
gboolean ret;
|
||||
|
||||
sink = GST_BASE_AUDIO_SINK (elem);
|
||||
|
||||
GST_OBJECT_LOCK (sink);
|
||||
if (clock != sink->provided_clock) {
|
||||
ret = gst_clock_set_master (sink->provided_clock, clock);
|
||||
} else {
|
||||
ret = gst_clock_set_master (sink->provided_clock, NULL);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (sink);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstClockTime
|
||||
gst_base_audio_sink_get_time (GstClock * clock, GstBaseAudioSink * sink)
|
||||
{
|
||||
|
@ -593,10 +570,13 @@ gst_base_audio_sink_change_state (GstElement * element,
|
|||
break;
|
||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||
{
|
||||
GstClock *clock;
|
||||
|
||||
GST_OBJECT_LOCK (sink);
|
||||
clock = GST_ELEMENT_CLOCK (sink);
|
||||
/* if we are slaved to a clock, we need to set the initial
|
||||
* calibration */
|
||||
/* FIXME, this is not yet accurate enough for smooth playback */
|
||||
if (gst_clock_get_master (sink->provided_clock)) {
|
||||
if (clock != sink->provided_clock) {
|
||||
GstClockTime time;
|
||||
GstClockTime rate_num, rate_denom;
|
||||
|
||||
|
@ -605,12 +585,15 @@ gst_base_audio_sink_change_state (GstElement * element,
|
|||
GST_DEBUG_OBJECT (sink, "time: %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (time));
|
||||
|
||||
gst_clock_set_master (sink->provided_clock, clock);
|
||||
/* FIXME, this is not yet accurate enough for smooth playback */
|
||||
gst_clock_get_calibration (sink->provided_clock, NULL, NULL, &rate_num,
|
||||
&rate_denom);
|
||||
/* Does not work yet. */
|
||||
gst_clock_set_calibration (sink->provided_clock,
|
||||
time, element->base_time, rate_num, rate_denom);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (sink);
|
||||
break;
|
||||
}
|
||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||
|
@ -625,6 +608,8 @@ gst_base_audio_sink_change_state (GstElement * element,
|
|||
switch (transition) {
|
||||
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
||||
gst_ring_buffer_pause (sink->ringbuffer);
|
||||
/* slop slaving ourselves to the master, if any */
|
||||
gst_clock_set_master (sink->provided_clock, NULL);
|
||||
break;
|
||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||
gst_ring_buffer_release (sink->ringbuffer);
|
||||
|
|
|
@ -18,6 +18,15 @@
|
|||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/**
|
||||
* SECTION:gstringbuffer
|
||||
* @short_description: Base class for audio ringbuffer implementations
|
||||
*
|
||||
* This object is the base class for audio ringbuffers used by the base
|
||||
* audio source and sink classes.
|
||||
*
|
||||
* Last reviewed on 2005-11-24 (0.9.6)
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -183,6 +192,12 @@ build_linear_format (int depth, int width, int unsignd, int big_endian)
|
|||
return ((int (*)[2][2]) linear_formats)[depth][!!unsignd][!!big_endian];
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_ring_buffer_debug_spec_caps:
|
||||
* @spec: the spec to debug
|
||||
*
|
||||
* Print debug info about the parsed caps in @spec to the debug log.
|
||||
*/
|
||||
void
|
||||
gst_ring_buffer_debug_spec_caps (GstRingBufferSpec * spec)
|
||||
{
|
||||
|
@ -198,6 +213,12 @@ gst_ring_buffer_debug_spec_caps (GstRingBufferSpec * spec)
|
|||
GST_DEBUG ("parsed caps: sample bytes: %d", spec->bytes_per_sample);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_ring_buffer_debug_spec_buff:
|
||||
* @spec: the spec to debug
|
||||
*
|
||||
* Print debug info about the buffer sized in @spec to the debug log.
|
||||
*/
|
||||
void
|
||||
gst_ring_buffer_debug_spec_buff (GstRingBufferSpec * spec)
|
||||
{
|
||||
|
@ -213,6 +234,15 @@ gst_ring_buffer_debug_spec_buff (GstRingBufferSpec * spec)
|
|||
spec->segsize * spec->segtotal / spec->bytes_per_sample);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_ring_buffer_parse_caps:
|
||||
* @spec: a spec
|
||||
* @caps: a #GstCaps
|
||||
*
|
||||
* Parse @caps into @spec.
|
||||
*
|
||||
* Returns: TRUE if the caps could be parsed.
|
||||
*/
|
||||
gboolean
|
||||
gst_ring_buffer_parse_caps (GstRingBufferSpec * spec, GstCaps * caps)
|
||||
{
|
||||
|
@ -355,11 +385,9 @@ gst_ring_buffer_open_device (GstRingBuffer * buf)
|
|||
GST_DEBUG_OBJECT (buf, "opening device");
|
||||
|
||||
GST_OBJECT_LOCK (buf);
|
||||
if (buf->open) {
|
||||
g_warning ("Device for ring buffer %p already open, fix your code", buf);
|
||||
res = TRUE;
|
||||
goto done;
|
||||
}
|
||||
if (buf->open)
|
||||
goto was_opened;
|
||||
|
||||
buf->open = TRUE;
|
||||
|
||||
/* if this fails, something is wrong in this file */
|
||||
|
@ -369,17 +397,30 @@ gst_ring_buffer_open_device (GstRingBuffer * buf)
|
|||
if (rclass->open_device)
|
||||
res = rclass->open_device (buf);
|
||||
|
||||
if (!res) {
|
||||
buf->open = FALSE;
|
||||
GST_DEBUG_OBJECT (buf, "failed opening device");
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (buf, "opened device");
|
||||
}
|
||||
if (!res)
|
||||
goto open_failed;
|
||||
|
||||
GST_DEBUG_OBJECT (buf, "opened device");
|
||||
|
||||
done:
|
||||
GST_OBJECT_UNLOCK (buf);
|
||||
|
||||
return res;
|
||||
|
||||
/* ERRORS */
|
||||
was_opened:
|
||||
{
|
||||
GST_DEBUG_OBJECT (buf, "Device for ring buffer already open");
|
||||
g_warning ("Device for ring buffer %p already open, fix your code", buf);
|
||||
res = TRUE;
|
||||
goto done;
|
||||
}
|
||||
open_failed:
|
||||
{
|
||||
buf->open = FALSE;
|
||||
GST_DEBUG_OBJECT (buf, "failed opening device");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -404,17 +445,11 @@ gst_ring_buffer_close_device (GstRingBuffer * buf)
|
|||
GST_DEBUG_OBJECT (buf, "closing device");
|
||||
|
||||
GST_OBJECT_LOCK (buf);
|
||||
if (!buf->open) {
|
||||
g_warning ("Device for ring buffer %p already closed, fix your code", buf);
|
||||
res = TRUE;
|
||||
goto done;
|
||||
}
|
||||
if (!buf->open)
|
||||
goto was_closed;
|
||||
|
||||
if (buf->acquired) {
|
||||
g_critical ("Resources for ring buffer %p still acquired", buf);
|
||||
res = FALSE;
|
||||
goto done;
|
||||
}
|
||||
if (buf->acquired)
|
||||
goto was_acquired;
|
||||
|
||||
buf->open = FALSE;
|
||||
|
||||
|
@ -422,17 +457,37 @@ gst_ring_buffer_close_device (GstRingBuffer * buf)
|
|||
if (rclass->close_device)
|
||||
res = rclass->close_device (buf);
|
||||
|
||||
if (!res) {
|
||||
buf->open = TRUE;
|
||||
GST_DEBUG_OBJECT (buf, "error closing device");
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (buf, "closed device");
|
||||
}
|
||||
if (!res)
|
||||
goto close_error;
|
||||
|
||||
GST_DEBUG_OBJECT (buf, "closed device");
|
||||
|
||||
done:
|
||||
GST_OBJECT_UNLOCK (buf);
|
||||
|
||||
return res;
|
||||
|
||||
/* ERRORS */
|
||||
was_closed:
|
||||
{
|
||||
GST_DEBUG_OBJECT (buf, "Device for ring buffer already closed");
|
||||
g_warning ("Device for ring buffer %p already closed, fix your code", buf);
|
||||
res = TRUE;
|
||||
goto done;
|
||||
}
|
||||
was_acquired:
|
||||
{
|
||||
GST_DEBUG_OBJECT (buf, "Resources for ring buffer still acquired");
|
||||
g_critical ("Resources for ring buffer %p still acquired", buf);
|
||||
res = FALSE;
|
||||
goto done;
|
||||
}
|
||||
close_error:
|
||||
{
|
||||
buf->open = TRUE;
|
||||
GST_DEBUG_OBJECT (buf, "error closing device");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -480,56 +535,78 @@ gst_ring_buffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
|
|||
{
|
||||
gboolean res = FALSE;
|
||||
GstRingBufferClass *rclass;
|
||||
gint i, j;
|
||||
gint segsize, bps;
|
||||
|
||||
g_return_val_if_fail (buf != NULL, FALSE);
|
||||
|
||||
GST_DEBUG_OBJECT (buf, "acquiring device");
|
||||
|
||||
GST_OBJECT_LOCK (buf);
|
||||
if (!buf->open) {
|
||||
g_critical ("Device for %p not opened", buf);
|
||||
res = FALSE;
|
||||
goto done;
|
||||
}
|
||||
if (buf->acquired) {
|
||||
res = TRUE;
|
||||
GST_DEBUG_OBJECT (buf, "device was acquired");
|
||||
goto done;
|
||||
}
|
||||
if (!buf->open)
|
||||
goto not_opened;
|
||||
|
||||
if (buf->acquired)
|
||||
goto was_acquired;
|
||||
|
||||
buf->acquired = TRUE;
|
||||
|
||||
rclass = GST_RING_BUFFER_GET_CLASS (buf);
|
||||
if (rclass->acquire)
|
||||
res = rclass->acquire (buf, spec);
|
||||
|
||||
if (!res) {
|
||||
buf->acquired = FALSE;
|
||||
GST_DEBUG_OBJECT (buf, "failed to acquire device");
|
||||
} else {
|
||||
if (buf->spec.bytes_per_sample != 0) {
|
||||
gint i, j;
|
||||
if (!res)
|
||||
goto acquire_failed;
|
||||
|
||||
buf->samples_per_seg = buf->spec.segsize / buf->spec.bytes_per_sample;
|
||||
if ((bps = buf->spec.bytes_per_sample) == 0)
|
||||
goto invalid_bps;
|
||||
|
||||
/* create an empty segment */
|
||||
g_free (buf->empty_seg);
|
||||
buf->empty_seg = g_malloc (buf->spec.segsize);
|
||||
for (i = 0, j = 0; i < buf->spec.segsize; i++) {
|
||||
buf->empty_seg[i] = buf->spec.silence_sample[j];
|
||||
j = (j + 1) % buf->spec.bytes_per_sample;
|
||||
}
|
||||
GST_DEBUG_OBJECT (buf, "acquired device");
|
||||
} else {
|
||||
g_warning
|
||||
("invalid bytes_per_sample from acquire ringbuffer, fix the element");
|
||||
buf->acquired = FALSE;
|
||||
res = FALSE;
|
||||
}
|
||||
segsize = buf->spec.segsize;
|
||||
|
||||
buf->samples_per_seg = segsize / bps;
|
||||
|
||||
/* create an empty segment */
|
||||
g_free (buf->empty_seg);
|
||||
buf->empty_seg = g_malloc (segsize);
|
||||
for (i = 0, j = 0; i < segsize; i++) {
|
||||
buf->empty_seg[i] = buf->spec.silence_sample[j];
|
||||
j = (j + 1) % bps;
|
||||
}
|
||||
GST_DEBUG_OBJECT (buf, "acquired device");
|
||||
|
||||
done:
|
||||
GST_OBJECT_UNLOCK (buf);
|
||||
|
||||
return res;
|
||||
|
||||
/* ERRORS */
|
||||
not_opened:
|
||||
{
|
||||
GST_DEBUG_OBJECT (buf, "device not opened");
|
||||
g_critical ("Device for %p not opened", buf);
|
||||
res = FALSE;
|
||||
goto done;
|
||||
}
|
||||
was_acquired:
|
||||
{
|
||||
res = TRUE;
|
||||
GST_DEBUG_OBJECT (buf, "device was acquired");
|
||||
goto done;
|
||||
}
|
||||
acquire_failed:
|
||||
{
|
||||
buf->acquired = FALSE;
|
||||
GST_DEBUG_OBJECT (buf, "failed to acquire device");
|
||||
goto done;
|
||||
}
|
||||
invalid_bps:
|
||||
{
|
||||
g_warning
|
||||
("invalid bytes_per_sample from acquire ringbuffer, fix the element");
|
||||
buf->acquired = FALSE;
|
||||
res = FALSE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -555,11 +632,9 @@ gst_ring_buffer_release (GstRingBuffer * buf)
|
|||
gst_ring_buffer_stop (buf);
|
||||
|
||||
GST_OBJECT_LOCK (buf);
|
||||
if (!buf->acquired) {
|
||||
res = TRUE;
|
||||
GST_DEBUG_OBJECT (buf, "device was released");
|
||||
goto done;
|
||||
}
|
||||
if (!buf->acquired)
|
||||
goto was_released;
|
||||
|
||||
buf->acquired = FALSE;
|
||||
|
||||
/* if this fails, something is wrong in this file */
|
||||
|
@ -572,19 +647,31 @@ gst_ring_buffer_release (GstRingBuffer * buf)
|
|||
/* signal any waiters */
|
||||
GST_RING_BUFFER_SIGNAL (buf);
|
||||
|
||||
if (!res) {
|
||||
buf->acquired = TRUE;
|
||||
GST_DEBUG_OBJECT (buf, "failed to release device");
|
||||
} else {
|
||||
g_free (buf->empty_seg);
|
||||
buf->empty_seg = NULL;
|
||||
GST_DEBUG_OBJECT (buf, "released device");
|
||||
}
|
||||
if (!res)
|
||||
goto release_failed;
|
||||
|
||||
g_free (buf->empty_seg);
|
||||
buf->empty_seg = NULL;
|
||||
GST_DEBUG_OBJECT (buf, "released device");
|
||||
|
||||
done:
|
||||
GST_OBJECT_UNLOCK (buf);
|
||||
|
||||
return res;
|
||||
|
||||
/* ERRORS */
|
||||
was_released:
|
||||
{
|
||||
res = TRUE;
|
||||
GST_DEBUG_OBJECT (buf, "device was released");
|
||||
goto done;
|
||||
}
|
||||
release_failed:
|
||||
{
|
||||
buf->acquired = TRUE;
|
||||
GST_DEBUG_OBJECT (buf, "failed to release device");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -891,8 +978,8 @@ gst_ring_buffer_samples_done (GstRingBuffer * buf)
|
|||
if (samples >= delay)
|
||||
samples -= delay;
|
||||
|
||||
GST_DEBUG ("processed samples: raw %llu, delay %u, real %llu", raw, delay,
|
||||
samples);
|
||||
GST_DEBUG_OBJECT (buf, "processed samples: raw %llu, delay %u, real %llu",
|
||||
raw, delay, samples);
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
@ -929,7 +1016,8 @@ gst_ring_buffer_set_sample (GstRingBuffer * buf, guint64 sample)
|
|||
|
||||
gst_ring_buffer_clear_all (buf);
|
||||
|
||||
GST_DEBUG ("set sample to %llu, segbase %d", sample, buf->segbase);
|
||||
GST_DEBUG_OBJECT (buf, "set sample to %llu, segbase %d", sample,
|
||||
buf->segbase);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -951,7 +1039,7 @@ gst_ring_buffer_clear_all (GstRingBuffer * buf)
|
|||
if (buf->spec.segtotal <= 0)
|
||||
return;
|
||||
|
||||
GST_DEBUG ("clear all segments");
|
||||
GST_DEBUG_OBJECT (buf, "clear all segments");
|
||||
|
||||
for (i = 0; i < buf->spec.segtotal; i++) {
|
||||
gst_ring_buffer_clear (buf, i);
|
||||
|
@ -964,7 +1052,7 @@ wait_segment (GstRingBuffer * buf)
|
|||
{
|
||||
/* buffer must be started now or we deadlock since nobody is reading */
|
||||
if (g_atomic_int_get (&buf->state) != GST_RING_BUFFER_STATE_STARTED) {
|
||||
GST_DEBUG ("start!");
|
||||
GST_DEBUG_OBJECT (buf, "start!");
|
||||
gst_ring_buffer_start (buf);
|
||||
}
|
||||
|
||||
|
@ -974,7 +1062,7 @@ wait_segment (GstRingBuffer * buf)
|
|||
goto flushing;
|
||||
|
||||
if (g_atomic_int_compare_and_exchange (&buf->waiting, 0, 1)) {
|
||||
GST_DEBUG ("waiting..");
|
||||
GST_DEBUG_OBJECT (buf, "waiting..");
|
||||
if (g_atomic_int_get (&buf->state) != GST_RING_BUFFER_STATE_STARTED)
|
||||
goto not_started;
|
||||
|
||||
|
@ -993,13 +1081,13 @@ wait_segment (GstRingBuffer * buf)
|
|||
not_started:
|
||||
{
|
||||
GST_OBJECT_UNLOCK (buf);
|
||||
GST_DEBUG ("stopped processing");
|
||||
GST_DEBUG_OBJECT (buf, "stopped processing");
|
||||
return FALSE;
|
||||
}
|
||||
flushing:
|
||||
{
|
||||
GST_OBJECT_UNLOCK (buf);
|
||||
GST_DEBUG ("flushing");
|
||||
GST_DEBUG_OBJECT (buf, "flushing");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -1016,7 +1104,7 @@ flushing:
|
|||
* the ringbuffer.
|
||||
*
|
||||
* @len not needs to be a multiple of the segment size of the ringbuffer
|
||||
* although it is recommended.
|
||||
* although it is recommended for optimal performance.
|
||||
*
|
||||
* Returns: The number of samples written to the ringbuffer or -1 on
|
||||
* error.
|
||||
|
@ -1086,7 +1174,7 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
|
|||
writeseg = writeseg % segtotal;
|
||||
sampleslen = MIN (sps - sampleoff, len);
|
||||
|
||||
GST_DEBUG ("write @%p seg %d, off %d, len %d",
|
||||
GST_DEBUG_OBJECT (buf, "write @%p seg %d, off %d, len %d",
|
||||
dest + writeseg * segsize, writeseg, sampleoff, sampleslen);
|
||||
|
||||
memcpy (dest + (writeseg * segsize) + (sampleoff * bps), data,
|
||||
|
@ -1103,7 +1191,7 @@ gst_ring_buffer_commit (GstRingBuffer * buf, guint64 sample, guchar * data,
|
|||
/* ERRORS */
|
||||
not_started:
|
||||
{
|
||||
GST_DEBUG ("stopped processing");
|
||||
GST_DEBUG_OBJECT (buf, "stopped processing");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1198,7 +1286,7 @@ gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data,
|
|||
readseg = readseg % segtotal;
|
||||
sampleslen = MIN (sps - sampleoff, len);
|
||||
|
||||
GST_DEBUG ("read @%p seg %d, off %d, len %d",
|
||||
GST_DEBUG_OBJECT (buf, "read @%p seg %d, off %d, len %d",
|
||||
dest + readseg * segsize, readseg, sampleoff, sampleslen);
|
||||
|
||||
memcpy (data, dest + (readseg * segsize) + (sampleoff * bps),
|
||||
|
@ -1215,7 +1303,7 @@ gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data,
|
|||
/* ERRORS */
|
||||
not_started:
|
||||
{
|
||||
GST_DEBUG ("stopped processing");
|
||||
GST_DEBUG_OBJECT (buf, "stopped processing");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1293,7 +1381,7 @@ gst_ring_buffer_advance (GstRingBuffer * buf, guint advance)
|
|||
* waiting for the signal */
|
||||
if (g_atomic_int_compare_and_exchange (&buf->waiting, 1, 0)) {
|
||||
GST_OBJECT_LOCK (buf);
|
||||
GST_DEBUG ("signal waiter");
|
||||
GST_DEBUG_OBJECT (buf, "signal waiter");
|
||||
GST_RING_BUFFER_SIGNAL (buf);
|
||||
GST_OBJECT_UNLOCK (buf);
|
||||
}
|
||||
|
|
|
@ -41,12 +41,29 @@ typedef struct _GstRingBufferSpec GstRingBufferSpec;
|
|||
/* called to fill data with len bytes of samples */
|
||||
typedef void (*GstRingBufferCallback) (GstRingBuffer *rbuf, guint8* data, guint len, gpointer user_data);
|
||||
|
||||
/**
|
||||
* GstRingBufferState:
|
||||
* @GST_RING_BUFFER_STATE_STOPPED: The ringbuffer is stopped
|
||||
* @GST_RING_BUFFER_STATE_PAUSED: The ringbuffer is paused
|
||||
* @GST_RING_BUFFER_STATE_STARTED: The ringbuffer is started
|
||||
*
|
||||
* The state of the ringbuffer.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_RING_BUFFER_STATE_STOPPED,
|
||||
GST_RING_BUFFER_STATE_PAUSED,
|
||||
GST_RING_BUFFER_STATE_STARTED,
|
||||
} GstRingBufferState;
|
||||
|
||||
/**
|
||||
* GstRingBufferSegState:
|
||||
* @GST_SEGSTATE_INVALID: The content of the segment is invalid
|
||||
* @GST_SEGSTATE_EMPTY: The segment is empty
|
||||
* @GST_SEGSTATE_FILLED: The segment contains valid data
|
||||
* @GST_SEGSTATE_PARTIAL: The segment partially contains valid data
|
||||
*
|
||||
* The state of a segment in the ringbuffer.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_SEGSTATE_INVALID,
|
||||
GST_SEGSTATE_EMPTY,
|
||||
|
@ -54,6 +71,18 @@ typedef enum {
|
|||
GST_SEGSTATE_PARTIAL,
|
||||
} GstRingBufferSegState;
|
||||
|
||||
/**
|
||||
* GstBufferFormatType:
|
||||
* @GST_BUFTYPE_LINEAR: samples in linear PCM
|
||||
* @GST_BUFTYPE_FLOAT: samples in float
|
||||
* @GST_BUFTYPE_MU_LAW: samples in mulaw
|
||||
* @GST_BUFTYPE_A_LAW: samples in alaw
|
||||
* @GST_BUFTYPE_IMA_ADPCM: samples in ima adpcm
|
||||
* @GST_BUFTYPE_MPEG: samples in mpeg audio format
|
||||
* @GST_BUFTYPE_GSM: samples in gsm format
|
||||
*
|
||||
* The format of the samples in the ringbuffer.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_BUFTYPE_LINEAR,
|
||||
|
@ -116,8 +145,29 @@ typedef enum
|
|||
|
||||
} GstBufferFormat;
|
||||
|
||||
/**
|
||||
* GstRingBufferSpec:
|
||||
* @caps: The caps that generated the Spec.
|
||||
* @type: the sample type
|
||||
* @format: the sample format
|
||||
* @sign: the sample sign
|
||||
* @bigend: the endianness of the samples
|
||||
* @width: the width of the samples
|
||||
* @depth: th depth of the samples
|
||||
* @rate: the samplerate
|
||||
* @channels: the number of channels
|
||||
* @latency_time: the latency in time units
|
||||
* @buffer_time: the total buffer size in time units
|
||||
* @segsize: the size of one segment in bytes
|
||||
* @segtotal: the total number of segments
|
||||
* @bytes_per_sample: number of bytes in one sample
|
||||
* @silence_sample: bytes representing one sample of silence
|
||||
*
|
||||
* The structure containing the format specification of the ringbuffer.
|
||||
*/
|
||||
struct _GstRingBufferSpec
|
||||
{
|
||||
/*< public >*/
|
||||
/* in */
|
||||
GstCaps *caps; /* the caps of the buffer */
|
||||
|
||||
|
@ -215,8 +265,8 @@ void gst_ring_buffer_set_callback (GstRingBuffer *buf, GstRingBufferCall
|
|||
gpointer user_data);
|
||||
|
||||
gboolean gst_ring_buffer_parse_caps (GstRingBufferSpec *spec, GstCaps *caps);
|
||||
void gst_ring_buffer_debug_spec_caps (GstRingBufferSpec *spec);
|
||||
void gst_ring_buffer_debug_spec_buff (GstRingBufferSpec *spec);
|
||||
void gst_ring_buffer_debug_spec_caps (GstRingBufferSpec *spec);
|
||||
void gst_ring_buffer_debug_spec_buff (GstRingBufferSpec *spec);
|
||||
|
||||
/* device state */
|
||||
gboolean gst_ring_buffer_open_device (GstRingBuffer *buf);
|
||||
|
|
Loading…
Reference in a new issue