diff --git a/ChangeLog b/ChangeLog index 51a7891827..47414a3c04 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2007-02-08 Tim-Philipp Müller + + Based on patch by: Julien Puydt + + * ext/alsa/gstalsa.c: (gst_alsa_find_device_name_no_handle), + (gst_alsa_find_device_name): + * ext/alsa/gstalsa.h: + * ext/alsa/gstalsasink.c: (gst_alsasink_get_property): + * ext/alsa/gstalsasrc.c: (gst_alsasrc_get_property): + Improve device-name detection a bit, especially in the case where + the device is not actually open (#405020, #405024). Move common code + into gstalsa.c instead of duplicating it. + 2007-02-07 Tim-Philipp Müller * gst/audioconvert/gstaudioconvert.c: @@ -144,7 +157,6 @@ Add small test for 32bit float <=> 64bit float conversion (works only one way so far, 32=>64 produces structured noise). ->>>>>>> 1.3137 2007-02-02 Tim-Philipp Müller * gst/audioconvert/gstaudioconvert.c: diff --git a/ext/alsa/gstalsa.c b/ext/alsa/gstalsa.c index 221392a883..7653475fea 100644 --- a/ext/alsa/gstalsa.c +++ b/ext/alsa/gstalsa.c @@ -389,3 +389,96 @@ subroutine_error: return NULL; } } + +static gchar * +gst_alsa_find_device_name_no_handle (GstObject * obj, const gchar * devcard, + gint device_num, snd_pcm_stream_t stream) +{ + snd_ctl_card_info_t *info = NULL; + snd_ctl_t *ctl = NULL; + gchar *ret = NULL; + gint dev = -1; + + GST_LOG_OBJECT (obj, "[%s] device=%d", devcard, device_num); + + if (snd_ctl_open (&ctl, devcard, 0) < 0) + return NULL; + + snd_ctl_card_info_malloc (&info); + if (snd_ctl_card_info (ctl, info) < 0) + goto done; + + while (snd_ctl_pcm_next_device (ctl, &dev) == 0 && dev >= 0) { + if (dev == device_num) { + snd_pcm_info_t *pcminfo; + + snd_pcm_info_malloc (&pcminfo); + snd_pcm_info_set_device (pcminfo, dev); + snd_pcm_info_set_subdevice (pcminfo, 0); + snd_pcm_info_set_stream (pcminfo, stream); + if (snd_ctl_pcm_info (ctl, pcminfo) < 0) { + snd_pcm_info_free (pcminfo); + break; + } + + ret = g_strdup (snd_pcm_info_get_name (pcminfo)); + snd_pcm_info_free (pcminfo); + GST_LOG_OBJECT (obj, "name from pcminfo: %s", GST_STR_NULL (ret)); + } + } + + if (ret == NULL) { + char *name = NULL; + gint card; + + GST_LOG_OBJECT (obj, "no luck so far, trying backup"); + card = snd_ctl_card_info_get_card (info); + snd_card_get_name (card, &name); + ret = g_strdup (name); + free (name); + } + +done: + snd_ctl_card_info_free (info); + snd_ctl_close (ctl); + + return ret; +} + +gchar * +gst_alsa_find_device_name (GstObject * obj, const gchar * device, + snd_pcm_t * handle, snd_pcm_stream_t stream) +{ + gchar *ret = NULL; + + if (handle != NULL) { + snd_pcm_info_t *info; + + GST_LOG_OBJECT (obj, "Trying to get device name from open handle"); + snd_pcm_info_malloc (&info); + snd_pcm_info (handle, info); + ret = g_strdup (snd_pcm_info_get_name (info)); + snd_pcm_info_free (info); + } + + if (ret == NULL && device != NULL) { + gchar *dev, *comma; + gint devnum; + + GST_LOG_OBJECT (obj, "Trying to get device name from string '%s'", device); + + /* only want name:card bit, but not devices and subdevices */ + dev = g_strdup (device); + if ((comma = strchr (dev, ','))) { + *comma = '\0'; + devnum = atoi (comma + 1); + ret = gst_alsa_find_device_name_no_handle (obj, dev, devnum, stream); + } + g_free (dev); + } + + GST_LOG_OBJECT (obj, "Device name for device '%s': %s", + GST_STR_NULL (device), GST_STR_NULL (ret)); + + return ret; +} diff --git a/ext/alsa/gstalsa.h b/ext/alsa/gstalsa.h index 5650e679af..75ffa86c16 100644 --- a/ext/alsa/gstalsa.h +++ b/ext/alsa/gstalsa.h @@ -39,4 +39,9 @@ GstCaps * gst_alsa_probe_supported_formats (GstObject * obj, snd_pcm_t * handle, const GstCaps * template_caps); +gchar * gst_alsa_find_device_name (GstObject * obj, + const gchar * device, + snd_pcm_t * handle, + snd_pcm_stream_t stream); + #endif /* __GST_ALSA_H__ */ diff --git a/ext/alsa/gstalsasink.c b/ext/alsa/gstalsasink.c index e4dd390592..dd8e7984e8 100644 --- a/ext/alsa/gstalsasink.c +++ b/ext/alsa/gstalsasink.c @@ -253,16 +253,9 @@ gst_alsasink_get_property (GObject * object, guint prop_id, g_value_set_string (value, sink->device); break; case PROP_DEVICE_NAME: - if (sink->handle) { - snd_pcm_info_t *info; - - snd_pcm_info_malloc (&info); - snd_pcm_info (sink->handle, info); - g_value_set_string (value, snd_pcm_info_get_name (info)); - snd_pcm_info_free (info); - } else { - g_value_set_string (value, NULL); - } + g_value_take_string (value, + gst_alsa_find_device_name (GST_OBJECT_CAST (sink), + sink->device, sink->handle, SND_PCM_STREAM_PLAYBACK)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); diff --git a/ext/alsa/gstalsasrc.c b/ext/alsa/gstalsasrc.c index 838e3b8fd6..27cb17ee0c 100644 --- a/ext/alsa/gstalsasrc.c +++ b/ext/alsa/gstalsasrc.c @@ -265,16 +265,9 @@ gst_alsasrc_get_property (GObject * object, guint prop_id, g_value_set_string (value, src->device); break; case PROP_DEVICE_NAME: - if (src->handle) { - snd_pcm_info_t *info; - - snd_pcm_info_malloc (&info); - snd_pcm_info (src->handle, info); - g_value_set_string (value, snd_pcm_info_get_name (info)); - snd_pcm_info_free (info); - } else { - g_value_set_string (value, NULL); - } + g_value_take_string (value, + gst_alsa_find_device_name (GST_OBJECT_CAST (src), + src->device, src->handle, SND_PCM_STREAM_CAPTURE)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);