mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 09:10:36 +00:00
gst-libs/gst/audio/gstbaseaudiosink.c
Original commit message from CVS: 2005-08-08 Andy Wingo <wingo@pobox.com> * gst-libs/gst/audio/gstbaseaudiosink.c (gst_base_audio_sink_change_state): Open the device in NULL->READY like good elements should. Close on READY->NULL too. * gst-libs/gst/audio/gstaudiosink.c (gst_audioringbuffer_open_device, (gst_audioringbuffer_close_device, gst_audioringbuffer_acquire) (gst_audioringbuffer_release): Updates for new ring buffer API, hook into the new audio sink api. * gst-libs/gst/audio/gstaudiosink.h (GstAudioSinkClass.open) (GstAudioSinkClass.close): Just open and close the device -- no resource allocation or configuration. (GstAudioSinkClass.prepare, GstAudioSinkClass.unprepare): New vmethods, handle device setup and resource allocation. * ext/alsa/gstalsasink.c (gst_alsasink_open, gst_alsasink_close) (gst_alsasink_prepare, gst_alsasink_unprepare): Update for new base class API. * gst-libs/gst/audio/gstringbuffer.h (GstRingBufferClass.open_device, GstRingBufferClass.close_device): New vmethods. * gst-libs/gst/audio/gstringbuffer.c (gst_ring_buffer_open_device) (gst_ring_buffer_close_device, gst_ring_buffer_device_is_open): New API functions. The device should be opened before acquiring and closed after releasing.
This commit is contained in:
parent
074b6a3b64
commit
69d36f02ce
7 changed files with 312 additions and 26 deletions
31
ChangeLog
31
ChangeLog
|
@ -1,3 +1,34 @@
|
||||||
|
2005-08-08 Andy Wingo <wingo@pobox.com>
|
||||||
|
|
||||||
|
* gst-libs/gst/audio/gstbaseaudiosink.c
|
||||||
|
(gst_base_audio_sink_change_state): Open the device in NULL->READY
|
||||||
|
like good elements should. Close on READY->NULL too.
|
||||||
|
|
||||||
|
* gst-libs/gst/audio/gstaudiosink.c
|
||||||
|
(gst_audioringbuffer_open_device,
|
||||||
|
(gst_audioringbuffer_close_device, gst_audioringbuffer_acquire)
|
||||||
|
(gst_audioringbuffer_release): Updates for new ring buffer API,
|
||||||
|
hook into the new audio sink api.
|
||||||
|
|
||||||
|
* gst-libs/gst/audio/gstaudiosink.h (GstAudioSinkClass.open)
|
||||||
|
(GstAudioSinkClass.close): Just open and close the device -- no
|
||||||
|
resource allocation or configuration.
|
||||||
|
(GstAudioSinkClass.prepare, GstAudioSinkClass.unprepare): New
|
||||||
|
vmethods, handle device setup and resource allocation.
|
||||||
|
|
||||||
|
* ext/alsa/gstalsasink.c (gst_alsasink_open, gst_alsasink_close)
|
||||||
|
(gst_alsasink_prepare, gst_alsasink_unprepare): Update for new
|
||||||
|
base class API.
|
||||||
|
|
||||||
|
* gst-libs/gst/audio/gstringbuffer.h
|
||||||
|
(GstRingBufferClass.open_device, GstRingBufferClass.close_device):
|
||||||
|
New vmethods.
|
||||||
|
|
||||||
|
* gst-libs/gst/audio/gstringbuffer.c (gst_ring_buffer_open_device)
|
||||||
|
(gst_ring_buffer_close_device, gst_ring_buffer_device_is_open):
|
||||||
|
New API functions. The device should be opened before acquiring
|
||||||
|
and closed after releasing.
|
||||||
|
|
||||||
2005-08-08 Tim-Philipp Müller <tim at centricular dot net>
|
2005-08-08 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
* gst-libs/gst/interfaces/mixer.h:
|
* gst-libs/gst/interfaces/mixer.h:
|
||||||
|
|
|
@ -57,8 +57,10 @@ static void gst_alsasink_get_property (GObject * object,
|
||||||
|
|
||||||
static GstCaps *gst_alsasink_getcaps (GstBaseSink * bsink);
|
static GstCaps *gst_alsasink_getcaps (GstBaseSink * bsink);
|
||||||
|
|
||||||
static gboolean gst_alsasink_open (GstAudioSink * asink,
|
static gboolean gst_alsasink_open (GstAudioSink * asink);
|
||||||
|
static gboolean gst_alsasink_prepare (GstAudioSink * asink,
|
||||||
GstRingBufferSpec * spec);
|
GstRingBufferSpec * spec);
|
||||||
|
static gboolean gst_alsasink_unprepare (GstAudioSink * asink);
|
||||||
static gboolean gst_alsasink_close (GstAudioSink * asink);
|
static gboolean gst_alsasink_close (GstAudioSink * asink);
|
||||||
static guint gst_alsasink_write (GstAudioSink * asink, gpointer data,
|
static guint gst_alsasink_write (GstAudioSink * asink, gpointer data,
|
||||||
guint length);
|
guint length);
|
||||||
|
@ -163,6 +165,8 @@ gst_alsasink_class_init (GstAlsaSinkClass * klass)
|
||||||
gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_alsasink_getcaps);
|
gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_alsasink_getcaps);
|
||||||
|
|
||||||
gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_alsasink_open);
|
gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_alsasink_open);
|
||||||
|
gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_alsasink_prepare);
|
||||||
|
gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR (gst_alsasink_unprepare);
|
||||||
gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_alsasink_close);
|
gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_alsasink_close);
|
||||||
gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_alsasink_write);
|
gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_alsasink_write);
|
||||||
gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_alsasink_delay);
|
gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_alsasink_delay);
|
||||||
|
@ -480,7 +484,29 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_alsasink_open (GstAudioSink * asink, GstRingBufferSpec * spec)
|
gst_alsasink_open (GstAudioSink * asink)
|
||||||
|
{
|
||||||
|
GstAlsaSink *alsa;
|
||||||
|
gint err;
|
||||||
|
|
||||||
|
alsa = GST_ALSA_SINK (asink);
|
||||||
|
|
||||||
|
CHECK (snd_pcm_open (&alsa->handle, alsa->device, SND_PCM_STREAM_PLAYBACK,
|
||||||
|
SND_PCM_NONBLOCK), open_error);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
open_error:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
|
||||||
|
("Playback open error: %s", snd_strerror (err)), (NULL));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_alsasink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
|
||||||
{
|
{
|
||||||
GstAlsaSink *alsa;
|
GstAlsaSink *alsa;
|
||||||
gint err;
|
gint err;
|
||||||
|
@ -490,9 +516,6 @@ gst_alsasink_open (GstAudioSink * asink, GstRingBufferSpec * spec)
|
||||||
if (!alsasink_parse_spec (alsa, spec))
|
if (!alsasink_parse_spec (alsa, spec))
|
||||||
goto spec_parse;
|
goto spec_parse;
|
||||||
|
|
||||||
CHECK (snd_pcm_open (&alsa->handle, alsa->device, SND_PCM_STREAM_PLAYBACK,
|
|
||||||
SND_PCM_NONBLOCK), open_error);
|
|
||||||
|
|
||||||
CHECK (snd_pcm_nonblock (alsa->handle, 0), non_block);
|
CHECK (snd_pcm_nonblock (alsa->handle, 0), non_block);
|
||||||
|
|
||||||
CHECK (set_hwparams (alsa), hw_params_failed);
|
CHECK (set_hwparams (alsa), hw_params_failed);
|
||||||
|
@ -515,12 +538,6 @@ spec_parse:
|
||||||
("Error parsing spec"), (NULL));
|
("Error parsing spec"), (NULL));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
open_error:
|
|
||||||
{
|
|
||||||
GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
|
|
||||||
("Playback open error: %s", snd_strerror (err)), (NULL));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
non_block:
|
non_block:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
|
GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
|
||||||
|
@ -542,12 +559,48 @@ sw_params_failed:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_alsasink_close (GstAudioSink * asink)
|
gst_alsasink_unprepare (GstAudioSink * asink)
|
||||||
{
|
{
|
||||||
GstAlsaSink *alsa;
|
GstAlsaSink *alsa;
|
||||||
|
gint err;
|
||||||
|
|
||||||
alsa = GST_ALSA_SINK (asink);
|
alsa = GST_ALSA_SINK (asink);
|
||||||
|
|
||||||
|
CHECK (snd_pcm_drop (alsa->handle), drop);
|
||||||
|
|
||||||
|
CHECK (snd_pcm_hw_free (alsa->handle), hw_free);
|
||||||
|
|
||||||
|
CHECK (snd_pcm_nonblock (alsa->handle, 1), non_block);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
drop:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
|
||||||
|
("Could not drop samples: %s", snd_strerror (err)), (NULL));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
hw_free:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
|
||||||
|
("Could not free hw params: %s", snd_strerror (err)), (NULL));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
non_block:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (alsa, RESOURCE, OPEN_READ,
|
||||||
|
("Could not set device to nonblocking: %s", snd_strerror (err)),
|
||||||
|
(NULL));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_alsasink_close (GstAudioSink * asink)
|
||||||
|
{
|
||||||
|
GstAlsaSink *alsa = GST_ALSA_SINK (asink);
|
||||||
|
|
||||||
snd_pcm_close (alsa->handle);
|
snd_pcm_close (alsa->handle);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -70,6 +70,8 @@ static void gst_audioringbuffer_finalize (GObject * object);
|
||||||
|
|
||||||
static GstRingBufferClass *ring_parent_class = NULL;
|
static GstRingBufferClass *ring_parent_class = NULL;
|
||||||
|
|
||||||
|
static gboolean gst_audioringbuffer_open_device (GstRingBuffer * buf);
|
||||||
|
static gboolean gst_audioringbuffer_close_device (GstRingBuffer * buf);
|
||||||
static gboolean gst_audioringbuffer_acquire (GstRingBuffer * buf,
|
static gboolean gst_audioringbuffer_acquire (GstRingBuffer * buf,
|
||||||
GstRingBufferSpec * spec);
|
GstRingBufferSpec * spec);
|
||||||
static gboolean gst_audioringbuffer_release (GstRingBuffer * buf);
|
static gboolean gst_audioringbuffer_release (GstRingBuffer * buf);
|
||||||
|
@ -120,6 +122,10 @@ gst_audioringbuffer_class_init (GstAudioRingBufferClass * klass)
|
||||||
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_audioringbuffer_dispose);
|
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_audioringbuffer_dispose);
|
||||||
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_audioringbuffer_finalize);
|
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_audioringbuffer_finalize);
|
||||||
|
|
||||||
|
gstringbuffer_class->open_device =
|
||||||
|
GST_DEBUG_FUNCPTR (gst_audioringbuffer_open_device);
|
||||||
|
gstringbuffer_class->close_device =
|
||||||
|
GST_DEBUG_FUNCPTR (gst_audioringbuffer_close_device);
|
||||||
gstringbuffer_class->acquire =
|
gstringbuffer_class->acquire =
|
||||||
GST_DEBUG_FUNCPTR (gst_audioringbuffer_acquire);
|
GST_DEBUG_FUNCPTR (gst_audioringbuffer_acquire);
|
||||||
gstringbuffer_class->release =
|
gstringbuffer_class->release =
|
||||||
|
@ -235,6 +241,54 @@ gst_audioringbuffer_finalize (GObject * object)
|
||||||
G_OBJECT_CLASS (ring_parent_class)->finalize (object);
|
G_OBJECT_CLASS (ring_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_audioringbuffer_open_device (GstRingBuffer * buf)
|
||||||
|
{
|
||||||
|
GstAudioSink *sink;
|
||||||
|
GstAudioSinkClass *csink;
|
||||||
|
gboolean result = TRUE;
|
||||||
|
|
||||||
|
sink = GST_AUDIO_SINK (GST_OBJECT_PARENT (buf));
|
||||||
|
csink = GST_AUDIO_SINK_GET_CLASS (sink);
|
||||||
|
|
||||||
|
if (csink->open)
|
||||||
|
result = csink->open (sink);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
goto could_not_open;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
could_not_open:
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_audioringbuffer_close_device (GstRingBuffer * buf)
|
||||||
|
{
|
||||||
|
GstAudioSink *sink;
|
||||||
|
GstAudioSinkClass *csink;
|
||||||
|
gboolean result = TRUE;
|
||||||
|
|
||||||
|
sink = GST_AUDIO_SINK (GST_OBJECT_PARENT (buf));
|
||||||
|
csink = GST_AUDIO_SINK_GET_CLASS (sink);
|
||||||
|
|
||||||
|
if (csink->close)
|
||||||
|
result = csink->close (sink);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
goto could_not_open;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
could_not_open:
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_audioringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
|
gst_audioringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
|
||||||
{
|
{
|
||||||
|
@ -246,8 +300,8 @@ gst_audioringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
|
||||||
sink = GST_AUDIO_SINK (GST_OBJECT_PARENT (buf));
|
sink = GST_AUDIO_SINK (GST_OBJECT_PARENT (buf));
|
||||||
csink = GST_AUDIO_SINK_GET_CLASS (sink);
|
csink = GST_AUDIO_SINK_GET_CLASS (sink);
|
||||||
|
|
||||||
if (csink->open)
|
if (csink->prepare)
|
||||||
result = csink->open (sink, spec);
|
result = csink->prepare (sink, spec);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
goto could_not_open;
|
goto could_not_open;
|
||||||
|
@ -300,8 +354,8 @@ gst_audioringbuffer_release (GstRingBuffer * buf)
|
||||||
gst_buffer_unref (buf->data);
|
gst_buffer_unref (buf->data);
|
||||||
buf->data = NULL;
|
buf->data = NULL;
|
||||||
|
|
||||||
if (csink->close)
|
if (csink->unprepare)
|
||||||
result = csink->close (sink);
|
result = csink->unprepare (sink);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,11 @@ struct _GstAudioSinkClass {
|
||||||
/* vtable */
|
/* vtable */
|
||||||
|
|
||||||
/* open the device with given specs */
|
/* open the device with given specs */
|
||||||
gboolean (*open) (GstAudioSink *sink, GstRingBufferSpec *spec);
|
gboolean (*open) (GstAudioSink *sink);
|
||||||
|
/* prepare resources and state to operate with the given specs */
|
||||||
|
gboolean (*prepare) (GstAudioSink *sink, GstRingBufferSpec *spec);
|
||||||
|
/* undo anything that was done in prepare() */
|
||||||
|
gboolean (*unprepare) (GstAudioSink *sink);
|
||||||
/* close the device */
|
/* close the device */
|
||||||
gboolean (*close) (GstAudioSink *sink);
|
gboolean (*close) (GstAudioSink *sink);
|
||||||
/* write samples to the device */
|
/* write samples to the device */
|
||||||
|
|
|
@ -419,13 +419,15 @@ gst_base_audio_sink_change_state (GstElement * element)
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_NULL_TO_READY:
|
case GST_STATE_NULL_TO_READY:
|
||||||
break;
|
|
||||||
case GST_STATE_READY_TO_PAUSED:
|
|
||||||
if (sink->ringbuffer == NULL) {
|
if (sink->ringbuffer == NULL) {
|
||||||
sink->ringbuffer = gst_base_audio_sink_create_ringbuffer (sink);
|
sink->ringbuffer = gst_base_audio_sink_create_ringbuffer (sink);
|
||||||
gst_ring_buffer_set_callback (sink->ringbuffer,
|
gst_ring_buffer_set_callback (sink->ringbuffer,
|
||||||
gst_base_audio_sink_callback, sink);
|
gst_base_audio_sink_callback, sink);
|
||||||
}
|
}
|
||||||
|
if (!gst_ring_buffer_open_device (sink->ringbuffer))
|
||||||
|
return GST_STATE_FAILURE;
|
||||||
|
break;
|
||||||
|
case GST_STATE_READY_TO_PAUSED:
|
||||||
break;
|
break;
|
||||||
case GST_STATE_PAUSED_TO_PLAYING:
|
case GST_STATE_PAUSED_TO_PLAYING:
|
||||||
break;
|
break;
|
||||||
|
@ -441,10 +443,11 @@ gst_base_audio_sink_change_state (GstElement * element)
|
||||||
break;
|
break;
|
||||||
case GST_STATE_PAUSED_TO_READY:
|
case GST_STATE_PAUSED_TO_READY:
|
||||||
gst_ring_buffer_stop (sink->ringbuffer);
|
gst_ring_buffer_stop (sink->ringbuffer);
|
||||||
gst_ring_buffer_release (sink->ringbuffer);
|
|
||||||
gst_pad_set_caps (GST_BASE_SINK_PAD (sink), NULL);
|
gst_pad_set_caps (GST_BASE_SINK_PAD (sink), NULL);
|
||||||
|
gst_ring_buffer_release (sink->ringbuffer);
|
||||||
break;
|
break;
|
||||||
case GST_STATE_READY_TO_NULL:
|
case GST_STATE_READY_TO_NULL:
|
||||||
|
gst_ring_buffer_close_device (sink->ringbuffer);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -80,6 +80,7 @@ gst_ring_buffer_class_init (GstRingBufferClass * klass)
|
||||||
static void
|
static void
|
||||||
gst_ring_buffer_init (GstRingBuffer * ringbuffer)
|
gst_ring_buffer_init (GstRingBuffer * ringbuffer)
|
||||||
{
|
{
|
||||||
|
ringbuffer->open = FALSE;
|
||||||
ringbuffer->acquired = FALSE;
|
ringbuffer->acquired = FALSE;
|
||||||
ringbuffer->state = GST_RING_BUFFER_STATE_STOPPED;
|
ringbuffer->state = GST_RING_BUFFER_STATE_STOPPED;
|
||||||
ringbuffer->cond = g_cond_new ();
|
ringbuffer->cond = g_cond_new ();
|
||||||
|
@ -327,6 +328,127 @@ gst_ring_buffer_set_callback (GstRingBuffer * buf, GstRingBufferCallback cb,
|
||||||
GST_UNLOCK (buf);
|
GST_UNLOCK (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_ring_buffer_open_device:
|
||||||
|
* @buf: the #GstRingBuffer
|
||||||
|
*
|
||||||
|
* Open the audio device associated with the ring buffer. Does not perform any
|
||||||
|
* setup on the device. You must open the device before acquiring the ring
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* Returns: TRUE if the device could be opened, FALSE on error.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_ring_buffer_open_device (GstRingBuffer * buf)
|
||||||
|
{
|
||||||
|
gboolean res = TRUE;
|
||||||
|
GstRingBufferClass *rclass;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
|
||||||
|
|
||||||
|
GST_LOCK (buf);
|
||||||
|
if (buf->open) {
|
||||||
|
g_warning ("Device for ring buffer %p already open, fix your code", buf);
|
||||||
|
res = TRUE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
buf->open = TRUE;
|
||||||
|
|
||||||
|
/* if this fails, something is wrong in this file */
|
||||||
|
g_assert (!buf->acquired);
|
||||||
|
|
||||||
|
rclass = GST_RING_BUFFER_GET_CLASS (buf);
|
||||||
|
if (rclass->open_device)
|
||||||
|
res = rclass->open_device (buf);
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
buf->open = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
GST_UNLOCK (buf);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_ring_buffer_close_device:
|
||||||
|
* @buf: the #GstRingBuffer
|
||||||
|
*
|
||||||
|
* Close the audio device associated with the ring buffer. The ring buffer
|
||||||
|
* should already have been released via gst_ring_buffer_release().
|
||||||
|
*
|
||||||
|
* Returns: TRUE if the device could be closed, FALSE on error.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_ring_buffer_close_device (GstRingBuffer * buf)
|
||||||
|
{
|
||||||
|
gboolean res = TRUE;
|
||||||
|
GstRingBufferClass *rclass;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
|
||||||
|
|
||||||
|
GST_LOCK (buf);
|
||||||
|
if (!buf->open) {
|
||||||
|
g_warning ("Device for ring buffer %p already closed, fix your code", buf);
|
||||||
|
res = TRUE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->acquired) {
|
||||||
|
g_critical ("Resources for ring buffer %p still acquired", buf);
|
||||||
|
res = FALSE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->open = FALSE;
|
||||||
|
|
||||||
|
rclass = GST_RING_BUFFER_GET_CLASS (buf);
|
||||||
|
if (rclass->close_device)
|
||||||
|
res = rclass->close_device (buf);
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
buf->open = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
GST_UNLOCK (buf);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_ring_buffer_device_is_open:
|
||||||
|
* @buf: the #GstRingBuffer
|
||||||
|
*
|
||||||
|
* Checks the status of the device associated with the ring buffer.
|
||||||
|
*
|
||||||
|
* Returns: TRUE if the device was open, FALSE if it was closed.
|
||||||
|
*
|
||||||
|
* MT safe.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_ring_buffer_device_is_open (GstRingBuffer * buf)
|
||||||
|
{
|
||||||
|
gboolean res = TRUE;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_RING_BUFFER (buf), FALSE);
|
||||||
|
|
||||||
|
GST_LOCK (buf);
|
||||||
|
|
||||||
|
res = buf->open;
|
||||||
|
|
||||||
|
GST_UNLOCK (buf);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_ring_buffer_acquire:
|
* gst_ring_buffer_acquire:
|
||||||
* @buf: the #GstRingBuffer to acquire
|
* @buf: the #GstRingBuffer to acquire
|
||||||
|
@ -349,6 +471,11 @@ gst_ring_buffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
|
||||||
g_return_val_if_fail (buf != NULL, FALSE);
|
g_return_val_if_fail (buf != NULL, FALSE);
|
||||||
|
|
||||||
GST_LOCK (buf);
|
GST_LOCK (buf);
|
||||||
|
if (!buf->open) {
|
||||||
|
g_critical ("Device for %p not opened", buf);
|
||||||
|
res = FALSE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (buf->acquired) {
|
if (buf->acquired) {
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -414,6 +541,9 @@ gst_ring_buffer_release (GstRingBuffer * buf)
|
||||||
}
|
}
|
||||||
buf->acquired = FALSE;
|
buf->acquired = FALSE;
|
||||||
|
|
||||||
|
/* if this fails, something is wrong in this file */
|
||||||
|
g_assert (buf->open == TRUE);
|
||||||
|
|
||||||
rclass = GST_RING_BUFFER_GET_CLASS (buf);
|
rclass = GST_RING_BUFFER_GET_CLASS (buf);
|
||||||
if (rclass->release)
|
if (rclass->release)
|
||||||
res = rclass->release (buf);
|
res = rclass->release (buf);
|
||||||
|
|
|
@ -151,6 +151,7 @@ struct _GstRingBuffer {
|
||||||
|
|
||||||
/*< public >*/ /* with LOCK */
|
/*< public >*/ /* with LOCK */
|
||||||
GCond *cond;
|
GCond *cond;
|
||||||
|
gboolean open;
|
||||||
gboolean acquired;
|
gboolean acquired;
|
||||||
GstBuffer *data;
|
GstBuffer *data;
|
||||||
GstRingBufferSpec spec;
|
GstRingBufferSpec spec;
|
||||||
|
@ -174,10 +175,14 @@ struct _GstRingBufferClass {
|
||||||
GstObjectClass parent_class;
|
GstObjectClass parent_class;
|
||||||
|
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
|
/* just open the device, don't set any params or allocate anything */
|
||||||
|
gboolean (*open_device) (GstRingBuffer *buf);
|
||||||
/* allocate the resources for the ringbuffer using the given specs */
|
/* allocate the resources for the ringbuffer using the given specs */
|
||||||
gboolean (*acquire) (GstRingBuffer *buf, GstRingBufferSpec *spec);
|
gboolean (*acquire) (GstRingBuffer *buf, GstRingBufferSpec *spec);
|
||||||
/* free resources of the ringbuffer */
|
/* free resources of the ringbuffer */
|
||||||
gboolean (*release) (GstRingBuffer *buf);
|
gboolean (*release) (GstRingBuffer *buf);
|
||||||
|
/* close the device */
|
||||||
|
gboolean (*close_device) (GstRingBuffer *buf);
|
||||||
|
|
||||||
/* playback control */
|
/* playback control */
|
||||||
gboolean (*start) (GstRingBuffer *buf);
|
gboolean (*start) (GstRingBuffer *buf);
|
||||||
|
@ -199,6 +204,12 @@ 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_caps (GstRingBufferSpec *spec);
|
||||||
void gst_ring_buffer_debug_spec_buff (GstRingBufferSpec *spec);
|
void gst_ring_buffer_debug_spec_buff (GstRingBufferSpec *spec);
|
||||||
|
|
||||||
|
/* device state */
|
||||||
|
gboolean gst_ring_buffer_open_device (GstRingBuffer *buf);
|
||||||
|
gboolean gst_ring_buffer_close_device (GstRingBuffer *buf);
|
||||||
|
|
||||||
|
gboolean gst_ring_buffer_device_is_open (GstRingBuffer *buf);
|
||||||
|
|
||||||
/* allocate resources */
|
/* allocate resources */
|
||||||
gboolean gst_ring_buffer_acquire (GstRingBuffer *buf, GstRingBufferSpec *spec);
|
gboolean gst_ring_buffer_acquire (GstRingBuffer *buf, GstRingBufferSpec *spec);
|
||||||
gboolean gst_ring_buffer_release (GstRingBuffer *buf);
|
gboolean gst_ring_buffer_release (GstRingBuffer *buf);
|
||||||
|
|
Loading…
Reference in a new issue