From e291418a8a5c7e9b6de979b226e7bd570ffd7776 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 15 Mar 2004 06:34:44 +0000 Subject: [PATCH] ext/alsa/: Don't open the device if we're a mixer (= padless). Original commit message from CVS: * ext/alsa/gstalsa.c: (gst_alsa_get_property), (gst_alsa_open_audio), (gst_alsa_close_audio): * ext/alsa/gstalsa.c: Don't open the device if we're a mixer (= padless). * ext/alsa/gstalsamixer.c: (gst_alsa_mixer_class_init), (gst_alsa_mixer_init), (gst_alsa_mixer_open), (gst_alsa_mixer_close), (gst_alsa_mixer_change_state): Open mixer during state change rather than during object initialization. Also, get a device name. Currently in a somewhat hackish fashion, but I didn't really find something better. --- ChangeLog | 13 +++++++++++++ ext/alsa/gstalsa.c | 31 ++++++++++++++++++++++--------- ext/alsa/gstalsamixer.c | 40 +++++++++++++++++++++++++++++----------- 3 files changed, 64 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index ca8989c9e56..eb799285081 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2004-03-15 Ronald Bultje + + * ext/alsa/gstalsa.c: (gst_alsa_get_property), + (gst_alsa_open_audio), (gst_alsa_close_audio): + * ext/alsa/gstalsa.c: + Don't open the device if we're a mixer (= padless). + * ext/alsa/gstalsamixer.c: (gst_alsa_mixer_class_init), + (gst_alsa_mixer_init), (gst_alsa_mixer_open), + (gst_alsa_mixer_close), (gst_alsa_mixer_change_state): + Open mixer during state change rather than during object + initialization. Also, get a device name. Currently in a somewhat + hackish fashion, but I didn't really find something better. + 2004-03-14 Thomas Vander Stichele * *.c, *.h: run gst-indent diff --git a/ext/alsa/gstalsa.c b/ext/alsa/gstalsa.c index ce9abf5ec13..e1cd5da1664 100644 --- a/ext/alsa/gstalsa.c +++ b/ext/alsa/gstalsa.c @@ -273,11 +273,7 @@ gst_alsa_get_property (GObject * object, guint prop_id, GValue * value, g_value_set_string (value, this->device); break; case ARG_DEVICE_NAME: - if (GST_STATE (this) != GST_STATE_NULL) { - g_value_set_string (value, snd_pcm_info_get_name (this->info)); - } else { - g_value_set_string (value, NULL); - } + g_value_set_string (value, this->cardname); break; case ARG_PERIODCOUNT: g_value_set_int (value, this->period_count); @@ -1108,9 +1104,16 @@ gst_alsa_set_eos (GstAlsa * this) static gboolean gst_alsa_open_audio (GstAlsa * this) { + snd_pcm_info_t *info; + g_assert (this != NULL); g_assert (this->handle == NULL); + /* If we have no pads, then we're apparently a mixer object, + * and that doesn't need a handle to the actual audio device. */ + if (!gst_element_get_pad_list (GST_ELEMENT (this))) + return TRUE; + GST_INFO ("Opening alsa device \"%s\"...\n", this->device); #if 0 @@ -1127,8 +1130,10 @@ gst_alsa_open_audio (GstAlsa * this) return FALSE; } - snd_pcm_info_malloc (&this->info); - snd_pcm_info (this->handle, this->info); + snd_pcm_info_malloc (&info); + snd_pcm_info (this->handle, info); + this->cardname = g_strdup (snd_pcm_info_get_name (info)); + snd_pcm_info_free (info); GST_FLAG_SET (this, GST_ALSA_OPEN); return TRUE; @@ -1375,14 +1380,20 @@ gst_alsa_stop_audio (GstAlsa * this) static gboolean gst_alsa_close_audio (GstAlsa * this) { + /* if there's no pads, we never open. So we don't close either. */ + if (!gst_element_get_pad_list (GST_ELEMENT (this))) + return TRUE; + g_return_val_if_fail (this != NULL, FALSE); g_return_val_if_fail (this->handle != NULL, FALSE); - snd_pcm_info_free (this->info); ERROR_CHECK (snd_pcm_close (this->handle), "Error closing device: %s"); this->handle = NULL; - this->info = NULL; + if (this->cardname) { + g_free (this->cardname); + this->cardname = NULL; + } GST_FLAG_UNSET (this, GST_ALSA_OPEN); return TRUE; @@ -1399,6 +1410,7 @@ gst_alsa_get_formats (GstPad * pad) GST_FORMAT_BYTES, 0 }; + return formats; } @@ -1483,6 +1495,7 @@ gst_alsa_get_query_types (GstPad * pad) GST_QUERY_POSITION, 0, }; + return query_types; } diff --git a/ext/alsa/gstalsamixer.c b/ext/alsa/gstalsamixer.c index b0040d65b2d..9d9f5b26b91 100644 --- a/ext/alsa/gstalsamixer.c +++ b/ext/alsa/gstalsamixer.c @@ -34,7 +34,6 @@ static void gst_alsa_interface_init (GstImplementsInterfaceClass * klass); static void gst_alsa_mixer_class_init (gpointer g_class, gpointer class_data); static void gst_alsa_mixer_init (GstAlsaMixer * mixer); -static void gst_alsa_mixer_dispose (GObject * object); static void gst_alsa_mixer_interface_init (GstMixerClass * klass); static gboolean gst_alsa_mixer_supported (GstImplementsInterface * iface, GType iface_type); @@ -117,8 +116,6 @@ gst_alsa_mixer_class_init (gpointer g_class, gpointer class_data) if (parent_class == NULL) parent_class = g_type_class_ref (GST_TYPE_ALSA); - object_class->dispose = gst_alsa_mixer_dispose; - element_class->change_state = gst_alsa_mixer_change_state; gst_element_class_set_details (element_class, &gst_alsa_mixer_details); @@ -127,7 +124,13 @@ gst_alsa_mixer_class_init (gpointer g_class, gpointer class_data) static void gst_alsa_mixer_init (GstAlsaMixer * mixer) { - gint err; + mixer->mixer_handle = NULL; +} + +static gboolean +gst_alsa_mixer_open (GstAlsaMixer * mixer) +{ + gint err, device; GstAlsa *alsa = GST_ALSA (mixer); mixer->mixer_handle = (snd_mixer_t *) - 1; @@ -137,7 +140,7 @@ gst_alsa_mixer_init (GstAlsaMixer * mixer) if (err < 0 || mixer->mixer_handle == NULL) { GST_ERROR_OBJECT (GST_OBJECT (mixer), "Cannot open mixer device."); mixer->mixer_handle = (snd_mixer_t *) - 1; - return; + return FALSE; } if ((err = snd_mixer_attach (mixer->mixer_handle, alsa->device)) < 0) { @@ -156,25 +159,37 @@ gst_alsa_mixer_init (GstAlsaMixer * mixer) goto error; } - return; + /* I don't know how to get a device name from a mixer handle. So on + * to the ugly hacks here, then... */ + if (sscanf (alsa->device, "hw:%d", &device) == 1) { + gchar *name; + + if (!snd_card_get_name (device, &name)) + alsa->cardname = name; + } + + return TRUE; error: snd_mixer_close (mixer->mixer_handle); mixer->mixer_handle = (snd_mixer_t *) - 1; + return FALSE; } static void -gst_alsa_mixer_dispose (GObject * object) +gst_alsa_mixer_close (GstAlsaMixer * mixer) { - GstAlsaMixer *mixer = GST_ALSA_MIXER (object); + GstAlsa *alsa = GST_ALSA (mixer); if (((gint) mixer->mixer_handle) == -1) return; + if (alsa->cardname) { + g_free (alsa->cardname); + alsa->cardname = NULL; + } snd_mixer_close (mixer->mixer_handle); mixer->mixer_handle = (snd_mixer_t *) - 1; - - G_OBJECT_CLASS (parent_class)->dispose (object); } static void @@ -278,13 +293,16 @@ gst_alsa_mixer_change_state (GstElement * element) switch (GST_STATE_TRANSITION (element)) { case GST_STATE_NULL_TO_READY: + if (!gst_alsa_mixer_open (this)) + return GST_STATE_FAILURE; gst_alsa_mixer_build_list (this); break; case GST_STATE_READY_TO_NULL: gst_alsa_mixer_free_list (this); + gst_alsa_mixer_close (this); break; default: - g_assert_not_reached (); + break; } if (GST_ELEMENT_CLASS (parent_class)->change_state)