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);
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);