From 113f851cc3fa1ecacdda743d5aa6fa7980df49f3 Mon Sep 17 00:00:00 2001 From: "braveyao@webrtc.org" Date: Tue, 8 May 2012 09:28:39 +0000 Subject: [PATCH] Merge Chromium issue 95797 into WebRTC. Bug = 450 Test = Manual test Review URL: https://webrtc-codereview.appspot.com/551004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2192 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../source/linux/audio_device_alsa_linux.cc | 214 +++++++++--------- 1 file changed, 109 insertions(+), 105 deletions(-) diff --git a/src/modules/audio_device/main/source/linux/audio_device_alsa_linux.cc b/src/modules/audio_device/main/source/linux/audio_device_alsa_linux.cc index ad814add09..e62636339e 100644 --- a/src/modules/audio_device/main/source/linux/audio_device_alsa_linux.cc +++ b/src/modules/audio_device/main/source/linux/audio_device_alsa_linux.cc @@ -1834,121 +1834,125 @@ WebRtc_Word32 AudioDeviceLinuxALSA::GetDevicesInfo( int enumCount(0); bool keepSearching(true); - void **hints; - err = LATE(snd_device_name_hint)(-1, // All cards - "pcm", // Only PCM devices - &hints); - if (err != 0) - { - WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, - "GetDevicesInfo - device name hint error: %s", - LATE(snd_strerror)(err)); - return -1; - } - - enumCount++; // default is 0 - if (function == FUNC_GET_DEVICE_NAME && enumDeviceNo == 0) - { - strcpy(enumDeviceName, "default"); - return 0; - } - if (function == FUNC_GET_DEVICE_NAME_FOR_AN_ENUM && enumDeviceNo == 0) - { - strcpy(enumDeviceName, "default"); - return 0; - } - - for (void **list = hints; *list != NULL; ++list) - { - char *actualType = LATE(snd_device_name_get_hint)(*list, "IOID"); - if (actualType) - { // NULL means it's both. - bool wrongType = (strcmp(actualType, type) != 0); - free(actualType); - if (wrongType) - { - // Wrong type of device (i.e., input vs. output). - continue; - } - } - - char *name = LATE(snd_device_name_get_hint)(*list, "NAME"); - if (!name) + // From Chromium issue 95797 + // Loop through the sound cards to get Alsa device hints. + // Don't use snd_device_name_hint(-1,..) since there is a access violation + // inside this ALSA API with libasound.so.2.0.0. + int card = -1; + while (!(LATE(snd_card_next)(&card)) && (card >= 0) && keepSearching) { + void **hints; + err = LATE(snd_device_name_hint)(card, "pcm", &hints); + if (err != 0) { WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, - "Device has no name"); - // Skip it. - continue; + "GetDevicesInfo - device name hint error: %s", + LATE(snd_strerror)(err)); + return -1; } - // Now check if we actually want to show this device. - if (strcmp(name, "default") != 0 && - strcmp(name, "null") != 0 && - strcmp(name, "pulse") != 0 && - strncmp(name, ignorePrefix, strlen(ignorePrefix)) != 0) + enumCount++; // default is 0 + if ((function == FUNC_GET_DEVICE_NAME || + function == FUNC_GET_DEVICE_NAME_FOR_AN_ENUM) && enumDeviceNo == 0) { - // Yes, we do. - char *desc = LATE(snd_device_name_get_hint)(*list, "DESC"); - if (!desc) + strcpy(enumDeviceName, "default"); + + err = LATE(snd_device_name_free_hint)(hints); + if (err != 0) { - // Virtual devices don't necessarily have descriptions. - // Use their names instead - desc = name; + WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, + "GetDevicesInfo - device name free hint error: %s", + LATE(snd_strerror)(err)); } - if (FUNC_GET_NUM_OF_DEVICE == function) - { - WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, - " Enum device %d - %s", enumCount, name); - - } - if ((FUNC_GET_DEVICE_NAME == function) && - (enumDeviceNo == enumCount)) - { - - // We have found the enum device, copy the name to buffer - strncpy(enumDeviceName, desc, ednLen); - enumDeviceName[ednLen-1] = '\0'; - keepSearching = false; - // replace '\n' with '-' - char * pret = strchr(enumDeviceName, '\n'/*0xa*/); //LF - if (pret) - *pret = '-'; - } - if ((FUNC_GET_DEVICE_NAME_FOR_AN_ENUM == function) && - (enumDeviceNo == enumCount)) - { - // We have found the enum device, copy the name to buffer - strncpy(enumDeviceName, name, ednLen); - enumDeviceName[ednLen-1] = '\0'; - keepSearching = false; - } - if (keepSearching) - { - ++enumCount; - } - - if (desc != name) - { - free(desc); - } + return 0; } - free(name); - - if (!keepSearching) + for (void **list = hints; *list != NULL; ++list) { - break; - } - } + char *actualType = LATE(snd_device_name_get_hint)(*list, "IOID"); + if (actualType) + { // NULL means it's both. + bool wrongType = (strcmp(actualType, type) != 0); + free(actualType); + if (wrongType) + { + // Wrong type of device (i.e., input vs. output). + continue; + } + } - err = LATE(snd_device_name_free_hint)(hints); - if (err != 0) - { - WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, - "GetDevicesInfo - device name free hint error: %s", - LATE(snd_strerror)(err)); - // Continue and return true anyways, since we did get the whole list. + char *name = LATE(snd_device_name_get_hint)(*list, "NAME"); + if (!name) + { + WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, + "Device has no name"); + // Skip it. + continue; + } + + // Now check if we actually want to show this device. + if (strcmp(name, "default") != 0 && + strcmp(name, "null") != 0 && + strcmp(name, "pulse") != 0 && + strncmp(name, ignorePrefix, strlen(ignorePrefix)) != 0) + { + // Yes, we do. + char *desc = LATE(snd_device_name_get_hint)(*list, "DESC"); + if (!desc) + { + // Virtual devices don't necessarily have descriptions. + // Use their names instead. + desc = name; + } + + if (FUNC_GET_NUM_OF_DEVICE == function) + { + WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, + " Enum device %d - %s", enumCount, name); + + } + if ((FUNC_GET_DEVICE_NAME == function) && + (enumDeviceNo == enumCount)) + { + // We have found the enum device, copy the name to buffer. + strncpy(enumDeviceName, desc, ednLen); + enumDeviceName[ednLen-1] = '\0'; + keepSearching = false; + // Replace '\n' with '-'. + char * pret = strchr(enumDeviceName, '\n'/*0xa*/); //LF + if (pret) + *pret = '-'; + } + if ((FUNC_GET_DEVICE_NAME_FOR_AN_ENUM == function) && + (enumDeviceNo == enumCount)) + { + // We have found the enum device, copy the name to buffer. + strncpy(enumDeviceName, name, ednLen); + enumDeviceName[ednLen-1] = '\0'; + keepSearching = false; + } + + if (keepSearching) + ++enumCount; + + if (desc != name) + free(desc); + } + + free(name); + + if (!keepSearching) + break; + } + + err = LATE(snd_device_name_free_hint)(hints); + if (err != 0) + { + WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, + "GetDevicesInfo - device name free hint error: %s", + LATE(snd_strerror)(err)); + // Continue and return true anyway, since we did get the whole list. + } } if (FUNC_GET_NUM_OF_DEVICE == function) @@ -1961,7 +1965,7 @@ WebRtc_Word32 AudioDeviceLinuxALSA::GetDevicesInfo( if (keepSearching) { // If we get here for function 1 and 2, we didn't find the specified - // enum device + // enum device. WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, "GetDevicesInfo - Could not find device name or numbers"); return -1; @@ -2151,7 +2155,7 @@ bool AudioDeviceLinuxALSA::PlayThreadProcess() if (frames < 0) { WEBRTC_TRACE(kTraceStream, kTraceAudioDevice, _id, - "playout snd_pcm_avail_update error: %s", + "playout snd_pcm_writei error: %s", LATE(snd_strerror)(frames)); _playoutFramesLeft = 0; ErrorRecovery(frames, _handlePlayout);