From 0ab81ef59f35d103ec8174834c4fc2a4dcced453 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 30 Jan 2014 16:32:53 +0100 Subject: Alsa: fix crash when detecting devices. Some old versions of Alsa crash when snd_device_name_hint(-1, ...) is called. This patch works around the problem by iterating manually over all the available sound cards. Change-Id: Ic380a371acc15013d137553ff30d68bed5af664e Reviewed-by: Christian Stromme --- src/gsttools/qgstreameraudioinputselector.cpp | 49 +++++----- src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp | 109 ++++++++++++----------- 2 files changed, 83 insertions(+), 75 deletions(-) (limited to 'src') diff --git a/src/gsttools/qgstreameraudioinputselector.cpp b/src/gsttools/qgstreameraudioinputselector.cpp index dcab762a2..02d3e5681 100644 --- a/src/gsttools/qgstreameraudioinputselector.cpp +++ b/src/gsttools/qgstreameraudioinputselector.cpp @@ -119,33 +119,36 @@ void QGstreamerAudioInputSelector::updateAlsaDevices() { #ifdef HAVE_ALSA void **hints, **n; - if (snd_device_name_hint(-1, "pcm", &hints) < 0) { - qWarning()<<"no alsa devices available"; - return; - } - n = hints; - - while (*n != NULL) { - char *name = snd_device_name_get_hint(*n, "NAME"); - char *descr = snd_device_name_get_hint(*n, "DESC"); - char *io = snd_device_name_get_hint(*n, "IOID"); - - if ((name != NULL) && (descr != NULL)) { - if ( io == NULL || qstrcmp(io,"Input") == 0 ) { - m_names.append(QLatin1String("alsa:")+QString::fromUtf8(name)); - m_descriptions.append(QString::fromUtf8(descr)); + int card = -1; + + while (snd_card_next(&card) == 0 && card >= 0) { + if (snd_device_name_hint(card, "pcm", &hints) < 0) + continue; + + n = hints; + while (*n != NULL) { + char *name = snd_device_name_get_hint(*n, "NAME"); + char *descr = snd_device_name_get_hint(*n, "DESC"); + char *io = snd_device_name_get_hint(*n, "IOID"); + + if ((name != NULL) && (descr != NULL)) { + if ( io == NULL || qstrcmp(io,"Input") == 0 ) { + m_names.append(QLatin1String("alsa:")+QString::fromUtf8(name)); + m_descriptions.append(QString::fromUtf8(descr)); + } } + + if (name != NULL) + free(name); + if (descr != NULL) + free(descr); + if (io != NULL) + free(io); + ++n; } - if (name != NULL) - free(name); - if (descr != NULL) - free(descr); - if (io != NULL) - free(io); - n++; + snd_device_name_free_hint(hints); } - snd_device_name_free_hint(hints); #endif } diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp index bc992029a..bd8fa8949 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp @@ -345,14 +345,9 @@ QList QAudioDeviceInfoInternal::availableDevices(QAudio::Mode mode) #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) // Create a list of all current audio devices that support mode - void **hints, **n; + void **hints; char *name, *descr, *io; - - if(snd_device_name_hint(-1, "pcm", &hints) < 0) { - qWarning() << "no alsa devices available"; - return devices; - } - n = hints; + int card = -1; if(mode == QAudio::AudioInput) { filter = "Input"; @@ -360,28 +355,35 @@ QList QAudioDeviceInfoInternal::availableDevices(QAudio::Mode mode) filter = "Output"; } - while (*n != NULL) { - name = snd_device_name_get_hint(*n, "NAME"); - if (name != 0 && qstrcmp(name, "null") != 0) { - descr = snd_device_name_get_hint(*n, "DESC"); - io = snd_device_name_get_hint(*n, "IOID"); - - if ((descr != NULL) && ((io == NULL) || (io == filter))) { - QString deviceName = QLatin1String(name); - QString deviceDescription = QLatin1String(descr); - if (deviceDescription.contains(QLatin1String("Default Audio Device"))) - devices.prepend(deviceName.toLocal8Bit().constData()); - else - devices.append(deviceName.toLocal8Bit().constData()); + while (snd_card_next(&card) == 0 && card >= 0) { + if (snd_device_name_hint(card, "pcm", &hints) < 0) + continue; + + void **n = hints; + while (*n != NULL) { + name = snd_device_name_get_hint(*n, "NAME"); + if (name != 0 && qstrcmp(name, "null") != 0) { + descr = snd_device_name_get_hint(*n, "DESC"); + io = snd_device_name_get_hint(*n, "IOID"); + + if ((descr != NULL) && ((io == NULL) || (io == filter))) { + QString deviceName = QLatin1String(name); + QString deviceDescription = QLatin1String(descr); + if (deviceDescription.contains(QLatin1String("Default Audio Device"))) + devices.prepend(deviceName.toLocal8Bit().constData()); + else + devices.append(deviceName.toLocal8Bit().constData()); + } + + free(descr); + free(io); } - - free(descr); - free(io); + free(name); + ++n; } - free(name); - ++n; + + snd_device_name_free_hint(hints); } - snd_device_name_free_hint(hints); #else int idx = 0; char* name; @@ -422,38 +424,41 @@ void QAudioDeviceInfoInternal::checkSurround() surround51 = false; surround71 = false; - void **hints, **n; + void **hints; char *name, *descr, *io; + int card = -1; - if(snd_device_name_hint(-1, "pcm", &hints) < 0) - return; + while (snd_card_next(&card) == 0 && card >= 0) { + if (snd_device_name_hint(card, "pcm", &hints) < 0) + continue; - n = hints; - - while (*n != NULL) { - name = snd_device_name_get_hint(*n, "NAME"); - descr = snd_device_name_get_hint(*n, "DESC"); - io = snd_device_name_get_hint(*n, "IOID"); - if((name != NULL) && (descr != NULL)) { - QString deviceName = QLatin1String(name); - if (mode == QAudio::AudioOutput) { - if(deviceName.contains(QLatin1String("surround40"))) - surround40 = true; - if(deviceName.contains(QLatin1String("surround51"))) - surround51 = true; - if(deviceName.contains(QLatin1String("surround71"))) - surround71 = true; + void **n = hints; + while (*n != NULL) { + name = snd_device_name_get_hint(*n, "NAME"); + descr = snd_device_name_get_hint(*n, "DESC"); + io = snd_device_name_get_hint(*n, "IOID"); + if((name != NULL) && (descr != NULL)) { + QString deviceName = QLatin1String(name); + if (mode == QAudio::AudioOutput) { + if(deviceName.contains(QLatin1String("surround40"))) + surround40 = true; + if(deviceName.contains(QLatin1String("surround51"))) + surround51 = true; + if(deviceName.contains(QLatin1String("surround71"))) + surround71 = true; + } } + if(name != NULL) + free(name); + if(descr != NULL) + free(descr); + if(io != NULL) + free(io); + ++n; } - if(name != NULL) - free(name); - if(descr != NULL) - free(descr); - if(io != NULL) - free(io); - ++n; + + snd_device_name_free_hint(hints); } - snd_device_name_free_hint(hints); } QT_END_NAMESPACE -- cgit v1.2.3