diff --git a/ChangeLog b/ChangeLog index c7bd725cbc..2a3fece0c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2006-08-13 Wim Taymans + + * ext/alsa/gstalsa.c: (gst_alsa_detect_rates), + (gst_alsa_detect_channels), (gst_alsa_probe_supported_formats): + Small code cleanup. + + * ext/alsa/gstalsamixer.c: (gst_alsa_mixer_open), + (gst_alsa_mixer_new): + Remove hack that always set the device to hw:0*. + Properly find the card name for whatever device was configured. + Do some better debugging. + Fixes #350784. + + * ext/alsa/gstalsamixerelement.c: + (gst_alsa_mixer_element_set_property), + (gst_alsa_mixer_element_change_state): + Cleanups. + Handle setting of a NULL device name better. + 2006-08-11 Wim Taymans * gst/adder/gstadder.c: diff --git a/ext/alsa/gstalsa.c b/ext/alsa/gstalsa.c index ef17600037..221392a883 100644 --- a/ext/alsa/gstalsa.c +++ b/ext/alsa/gstalsa.c @@ -65,6 +65,7 @@ gst_alsa_detect_rates (GstObject * obj, snd_pcm_hw_params_t * hw_params, return caps; + /* ERRORS */ min_rate_err: { GST_ERROR_OBJECT (obj, "failed to query minimum sample rate: %s", @@ -328,6 +329,7 @@ gst_alsa_detect_channels (GstObject * obj, snd_pcm_hw_params_t * hw_params, return caps; + /* ERRORS */ min_chan_error: { GST_ERROR_OBJECT (obj, "failed to query minimum channel count: %s", @@ -375,12 +377,12 @@ gst_alsa_probe_supported_formats (GstObject * obj, snd_pcm_t * handle, return caps; + /* ERRORS */ error: { GST_ERROR_OBJECT (obj, "failed to query formats: %s", snd_strerror (err)); return NULL; } - subroutine_error: { GST_ERROR_OBJECT (obj, "failed to query formats"); diff --git a/ext/alsa/gstalsamixer.c b/ext/alsa/gstalsamixer.c index dfb040b9d7..1fb275e56b 100644 --- a/ext/alsa/gstalsamixer.c +++ b/ext/alsa/gstalsamixer.c @@ -44,76 +44,78 @@ /* First some utils, then the mixer implementation */ - static gboolean gst_alsa_mixer_open (GstAlsaMixer * mixer) { - gint err, devicenum; + gint err; + snd_ctl_t *ctl; + snd_ctl_card_info_t *card_info; g_return_val_if_fail (mixer->handle == NULL, FALSE); /* open and initialize the mixer device */ err = snd_mixer_open (&mixer->handle, 0); - if (err < 0 || mixer->handle == NULL) { - GST_WARNING ("Cannot open empty mixer."); - mixer->handle = NULL; - return FALSE; - } - - /* hack hack hack hack hack!!!!! */ - if (strncmp (mixer->device, "default", 7) == 0) { - /* hack! */ - g_free (mixer->device); - mixer->device = g_strdup ("hw:0"); - } else if (strncmp (mixer->device, "hw:", 3) == 0) { - /* ok */ - } else if (strncmp (mixer->device, "plughw:", 7) == 0) { - gchar *freeme = mixer->device; - - mixer->device = g_strdup (freeme + 4); - g_free (freeme); - } else { - goto error; - } - - if (strchr (mixer->device, ',')) - strchr (mixer->device, ',')[0] = '\0'; + if (err < 0 || mixer->handle == NULL) + goto open_failed; if ((err = snd_mixer_attach (mixer->handle, mixer->device)) < 0) { - GST_WARNING ("Cannot open mixer for sound device `%s'.", mixer->device); + GST_WARNING ("Cannot open mixer for sound device '%s': %s", mixer->device, + snd_strerror (err)); goto error; } if ((err = snd_mixer_selem_register (mixer->handle, NULL, NULL)) < 0) { - GST_WARNING ("Cannot register mixer elements."); + GST_WARNING ("Cannot register mixer elements: %s", snd_strerror (err)); goto error; } if ((err = snd_mixer_load (mixer->handle)) < 0) { - GST_WARNING ("Cannot load mixer settings."); + GST_WARNING ("Cannot load mixer settings: %s", snd_strerror (err)); goto error; } - /* I don't know how to get a device name from a mixer handle. So on - * to the ugly hacks here, then... */ - if (sscanf (mixer->device, "hw:%d", &devicenum) == 1) { - gchar *name; - if (!snd_card_get_name (devicenum, &name)) { - mixer->cardname = g_strdup (name); - free (name); - GST_DEBUG ("Card name = %s", GST_STR_NULL (mixer->cardname)); - } + /* now get the device name, any of this is not fatal */ + g_free (mixer->cardname); + if ((err = snd_ctl_open (&ctl, mixer->device, 0)) < 0) { + GST_WARNING ("Cannot open CTL: %s", snd_strerror (err)); + goto no_card_name; } - GST_INFO ("Successfully opened mixer for device `%s'.", mixer->device); + snd_ctl_card_info_alloca (&card_info); + if ((err = snd_ctl_card_info (ctl, card_info)) < 0) { + GST_WARNING ("Cannot get card info: %s", snd_strerror (err)); + snd_ctl_close (ctl); + goto no_card_name; + } + + mixer->cardname = g_strdup (snd_ctl_card_info_get_name (card_info)); + GST_DEBUG ("Card name = %s", GST_STR_NULL (mixer->cardname)); + snd_ctl_close (ctl); + + if (FALSE) { + no_card_name: + mixer->cardname = g_strdup ("Unknown"); + GST_DEBUG ("Cannot find card name"); + } + + GST_INFO ("Successfully opened mixer for device '%s'.", mixer->device); return TRUE; + /* ERROR */ +open_failed: + { + GST_WARNING ("Cannot open mixer: %s", snd_strerror (err)); + mixer->handle = NULL; + return FALSE; + } error: - snd_mixer_close (mixer->handle); - mixer->handle = NULL; - return FALSE; + { + snd_mixer_close (mixer->handle); + mixer->handle = NULL; + return FALSE; + } } static void @@ -230,11 +232,12 @@ gst_alsa_mixer_new (const char *device, GstAlsaMixerDirection dir) return ret; + /* ERRORS */ error: - if (ret) + { gst_alsa_mixer_free (ret); - - return NULL; + return NULL; + } } void diff --git a/ext/alsa/gstalsamixerelement.c b/ext/alsa/gstalsamixerelement.c index 4cefe781f9..75d5b4a49c 100644 --- a/ext/alsa/gstalsamixerelement.c +++ b/ext/alsa/gstalsamixerelement.c @@ -35,7 +35,6 @@ enum PROP_DEVICE_NAME }; - static const GstElementDetails gst_alsa_mixer_element_details = GST_ELEMENT_DETAILS ("Alsa mixer", "Generic/Audio", @@ -160,6 +159,10 @@ gst_alsa_mixer_element_set_property (GObject * object, guint prop_id, GST_OBJECT_LOCK (this); g_free (this->device); this->device = g_value_dup_string (value); + /* make sure we never set NULL, this is nice when we want to open the + * device. */ + if (this->device == NULL) + this->device = g_strdup (DEFAULT_PROP_DEVICE); GST_OBJECT_UNLOCK (this); break; } @@ -208,14 +211,9 @@ gst_alsa_mixer_element_change_state (GstElement * element, switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (!this->mixer) { - const gchar *device = (this->device) ? this->device : "default"; - - this->mixer = gst_alsa_mixer_new (device, GST_ALSA_MIXER_ALL); - if (!this->mixer) { - GST_ELEMENT_ERROR (element, RESOURCE, OPEN_READ_WRITE, (NULL), - ("Failed to open alsa mixer device '%s'", device)); - return GST_STATE_CHANGE_FAILURE; - } + this->mixer = gst_alsa_mixer_new (this->device, GST_ALSA_MIXER_ALL); + if (!this->mixer) + goto open_failed; } break; default: @@ -238,4 +236,12 @@ gst_alsa_mixer_element_change_state (GstElement * element, } return ret; + + /* ERRORS */ +open_failed: + { + GST_ELEMENT_ERROR (element, RESOURCE, OPEN_READ_WRITE, (NULL), + ("Failed to open alsa mixer device '%s'", this->device)); + return GST_STATE_CHANGE_FAILURE; + } }