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
This commit is contained in:
braveyao@webrtc.org 2012-05-08 09:28:39 +00:00
parent 7415f371ac
commit 113f851cc3

View File

@ -1834,121 +1834,125 @@ WebRtc_Word32 AudioDeviceLinuxALSA::GetDevicesInfo(
int enumCount(0); int enumCount(0);
bool keepSearching(true); bool keepSearching(true);
void **hints; // From Chromium issue 95797
err = LATE(snd_device_name_hint)(-1, // All cards // Loop through the sound cards to get Alsa device hints.
"pcm", // Only PCM devices // Don't use snd_device_name_hint(-1,..) since there is a access violation
&hints); // inside this ALSA API with libasound.so.2.0.0.
if (err != 0) int card = -1;
{ while (!(LATE(snd_card_next)(&card)) && (card >= 0) && keepSearching) {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, void **hints;
"GetDevicesInfo - device name hint error: %s", err = LATE(snd_device_name_hint)(card, "pcm", &hints);
LATE(snd_strerror)(err)); if (err != 0)
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)
{ {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
"Device has no name"); "GetDevicesInfo - device name hint error: %s",
// Skip it. LATE(snd_strerror)(err));
continue; return -1;
} }
// Now check if we actually want to show this device. enumCount++; // default is 0
if (strcmp(name, "default") != 0 && if ((function == FUNC_GET_DEVICE_NAME ||
strcmp(name, "null") != 0 && function == FUNC_GET_DEVICE_NAME_FOR_AN_ENUM) && enumDeviceNo == 0)
strcmp(name, "pulse") != 0 &&
strncmp(name, ignorePrefix, strlen(ignorePrefix)) != 0)
{ {
// Yes, we do. strcpy(enumDeviceName, "default");
char *desc = LATE(snd_device_name_get_hint)(*list, "DESC");
if (!desc) err = LATE(snd_device_name_free_hint)(hints);
if (err != 0)
{ {
// Virtual devices don't necessarily have descriptions. WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
// Use their names instead "GetDevicesInfo - device name free hint error: %s",
desc = name; LATE(snd_strerror)(err));
} }
if (FUNC_GET_NUM_OF_DEVICE == function) return 0;
{
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); for (void **list = hints; *list != NULL; ++list)
if (!keepSearching)
{ {
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); char *name = LATE(snd_device_name_get_hint)(*list, "NAME");
if (err != 0) if (!name)
{ {
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
"GetDevicesInfo - device name free hint error: %s", "Device has no name");
LATE(snd_strerror)(err)); // Skip it.
// Continue and return true anyways, since we did get the whole list. 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) if (FUNC_GET_NUM_OF_DEVICE == function)
@ -1961,7 +1965,7 @@ WebRtc_Word32 AudioDeviceLinuxALSA::GetDevicesInfo(
if (keepSearching) if (keepSearching)
{ {
// If we get here for function 1 and 2, we didn't find the specified // If we get here for function 1 and 2, we didn't find the specified
// enum device // enum device.
WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id,
"GetDevicesInfo - Could not find device name or numbers"); "GetDevicesInfo - Could not find device name or numbers");
return -1; return -1;
@ -2151,7 +2155,7 @@ bool AudioDeviceLinuxALSA::PlayThreadProcess()
if (frames < 0) if (frames < 0)
{ {
WEBRTC_TRACE(kTraceStream, kTraceAudioDevice, _id, WEBRTC_TRACE(kTraceStream, kTraceAudioDevice, _id,
"playout snd_pcm_avail_update error: %s", "playout snd_pcm_writei error: %s",
LATE(snd_strerror)(frames)); LATE(snd_strerror)(frames));
_playoutFramesLeft = 0; _playoutFramesLeft = 0;
ErrorRecovery(frames, _handlePlayout); ErrorRecovery(frames, _handlePlayout);