mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
ext/alsa/gstalsasink.*: Add lock to protect alsa calls.
Original commit message from CVS: * ext/alsa/gstalsasink.c: (gst_alsasink_finalise), (gst_alsasink_class_init), (gst_alsasink_init), (gst_alsasink_write), (gst_alsasink_reset): * ext/alsa/gstalsasink.h: Add lock to protect alsa calls. Implement reset to flush samples ASAP, does not work with dmix though.
This commit is contained in:
parent
260b5295c9
commit
7aeb1d4587
3 changed files with 40 additions and 6 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2006-02-03 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* ext/alsa/gstalsasink.c: (gst_alsasink_finalise),
|
||||
(gst_alsasink_class_init), (gst_alsasink_init),
|
||||
(gst_alsasink_write), (gst_alsasink_reset):
|
||||
* ext/alsa/gstalsasink.h:
|
||||
Add lock to protect alsa calls.
|
||||
Implement reset to flush samples ASAP, does not work
|
||||
with dmix though.
|
||||
|
||||
2006-02-02 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst-libs/gst/audio/gstbaseaudiosink.c:
|
||||
|
|
|
@ -42,6 +42,9 @@ GST_ELEMENT_DETAILS ("Audio Sink (ALSA)",
|
|||
"Output to a sound card via ALSA",
|
||||
"Wim Taymans <wim@fluendo.com>");
|
||||
|
||||
#define DEFAULT_DEVICE "default"
|
||||
#define DEFAULT_DEVICE_NAME ""
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
@ -142,6 +145,7 @@ gst_alsasink_finalise (GObject * object)
|
|||
GstAlsaSink *sink = GST_ALSA_SINK (object);
|
||||
|
||||
g_free (sink->device);
|
||||
g_mutex_free (sink->alsa_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -189,11 +193,12 @@ gst_alsasink_class_init (GstAlsaSinkClass * klass)
|
|||
g_object_class_install_property (gobject_class, PROP_DEVICE,
|
||||
g_param_spec_string ("device", "Device",
|
||||
"ALSA device, as defined in an asound configuration file",
|
||||
"default", G_PARAM_READWRITE));
|
||||
DEFAULT_DEVICE, G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_DEVICE_NAME,
|
||||
g_param_spec_string ("device-name", "Device name",
|
||||
"Human-readable name of the sound device", "", G_PARAM_READABLE));
|
||||
"Human-readable name of the sound device", DEFAULT_DEVICE_NAME,
|
||||
G_PARAM_READABLE));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -246,13 +251,18 @@ gst_alsasink_get_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
|
||||
static snd_output_t *output = NULL;
|
||||
|
||||
static void
|
||||
gst_alsasink_init (GstAlsaSink * alsasink)
|
||||
{
|
||||
GST_DEBUG_OBJECT (alsasink, "initializing alsasink");
|
||||
|
||||
alsasink->device = g_strdup ("default");
|
||||
alsasink->device = g_strdup (DEFAULT_DEVICE);
|
||||
alsasink->handle = NULL;
|
||||
alsasink->alsa_lock = g_mutex_new ();
|
||||
|
||||
snd_output_stdio_attach (&output, stdout, 0);
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
|
@ -695,12 +705,14 @@ gst_alsasink_write (GstAudioSink * asink, gpointer data, guint length)
|
|||
cptr = length / alsa->bytes_per_sample;
|
||||
ptr = data;
|
||||
|
||||
GST_ALSA_LOCK (asink);
|
||||
while (cptr > 0) {
|
||||
err = snd_pcm_writei (alsa->handle, ptr, cptr);
|
||||
|
||||
GST_DEBUG_OBJECT (asink, "written %d result %d", cptr, err);
|
||||
if (err < 0) {
|
||||
GST_DEBUG_OBJECT (asink, "Write error: %s", snd_strerror (err));
|
||||
if (err == -EAGAIN) {
|
||||
GST_DEBUG_OBJECT (asink, "Write error: %s", snd_strerror (err));
|
||||
continue;
|
||||
} else if (xrun_recovery (alsa->handle, err) < 0) {
|
||||
goto write_error;
|
||||
|
@ -711,11 +723,13 @@ gst_alsasink_write (GstAudioSink * asink, gpointer data, guint length)
|
|||
ptr += err * alsa->channels;
|
||||
cptr -= err;
|
||||
}
|
||||
GST_ALSA_UNLOCK (asink);
|
||||
|
||||
return length - cptr;
|
||||
|
||||
write_error:
|
||||
{
|
||||
GST_ALSA_UNLOCK (asink);
|
||||
return length; /* skip one period */
|
||||
}
|
||||
}
|
||||
|
@ -736,14 +750,18 @@ gst_alsasink_delay (GstAudioSink * asink)
|
|||
static void
|
||||
gst_alsasink_reset (GstAudioSink * asink)
|
||||
{
|
||||
#if 0
|
||||
GstAlsaSink *alsa;
|
||||
gint err;
|
||||
|
||||
alsa = GST_ALSA_SINK (asink);
|
||||
|
||||
GST_ALSA_LOCK (asink);
|
||||
GST_DEBUG_OBJECT (alsa, "drop");
|
||||
CHECK (snd_pcm_drop (alsa->handle), drop_error);
|
||||
GST_DEBUG_OBJECT (alsa, "prepare");
|
||||
CHECK (snd_pcm_prepare (alsa->handle), prepare_error);
|
||||
GST_DEBUG_OBJECT (alsa, "reset done");
|
||||
GST_ALSA_UNLOCK (asink);
|
||||
|
||||
return;
|
||||
|
||||
|
@ -760,5 +778,4 @@ prepare_error:
|
|||
("alsa-reset: pcm prepare error: %s", snd_strerror (err)), (NULL));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -36,10 +36,15 @@ G_BEGIN_DECLS
|
|||
#define GST_ALSA_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_SINK,GstAlsaSinkClass))
|
||||
#define GST_IS_ALSA_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_SINK))
|
||||
#define GST_IS_ALSA_SINK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_SINK))
|
||||
#define GST_ALSA_SINK_CAST(obj) ((GstAlsaSink *) (obj))
|
||||
|
||||
typedef struct _GstAlsaSink GstAlsaSink;
|
||||
typedef struct _GstAlsaSinkClass GstAlsaSinkClass;
|
||||
|
||||
#define GST_ALSA_GET_LOCK(obj) (GST_ALSA_SINK_CAST (obj)->alsa_lock)
|
||||
#define GST_ALSA_LOCK(obj) (g_mutex_lock (GST_ALSA_GET_LOCK (obj)))
|
||||
#define GST_ALSA_UNLOCK(obj) (g_mutex_unlock (GST_ALSA_GET_LOCK (obj)))
|
||||
|
||||
struct _GstAlsaSink {
|
||||
GstAudioSink sink;
|
||||
|
||||
|
@ -59,6 +64,8 @@ struct _GstAlsaSink {
|
|||
guint period_time;
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
snd_pcm_uframes_t period_size;
|
||||
|
||||
GMutex *alsa_lock;
|
||||
};
|
||||
|
||||
struct _GstAlsaSinkClass {
|
||||
|
|
Loading…
Reference in a new issue