summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2010-03-11 14:47:00 -0800
committerEric Laurent <elaurent@google.com>2010-03-16 17:32:18 -0700
commitef9500fe53b6ec67b610207832b52f8bfbb20cd5 (patch)
tree00a5eea1602d0a358603b0d4e741b0b51f2a36b5 /libs
parent1a3786a3e34112e3e68e6a9b07ba72802867a002 (diff)
downloadframeworks_base-ef9500fe53b6ec67b610207832b52f8bfbb20cd5.zip
frameworks_base-ef9500fe53b6ec67b610207832b52f8bfbb20cd5.tar.gz
frameworks_base-ef9500fe53b6ec67b610207832b52f8bfbb20cd5.tar.bz2
Fix issue 2416481: Support Voice Dialer over BT SCO.
- AudioPolicyManager: allow platform specific choice for opening a direct output. Also fixed problems in direct output management. - AudioFliinger: use shorter standby delay and track inactivity grace period for direct output thread to free hardware resources as soon as possible. - AudioSystem: do not use cached output selection in getOutput() when a direct output can be selected. Change-Id: If44b50d29237b8402ffd7a5ba1dc43c56f903e9b
Diffstat (limited to 'libs')
-rw-r--r--libs/audioflinger/AudioFlinger.cpp14
-rw-r--r--libs/audioflinger/AudioPolicyManagerBase.cpp34
2 files changed, 33 insertions, 15 deletions
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 7902212..815a367 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -72,6 +72,10 @@ static const float MAX_GAIN = 4096.0f;
// 50 * ~20msecs = 1 second
static const int8_t kMaxTrackRetries = 50;
static const int8_t kMaxTrackStartupRetries = 50;
+// allow less retry attempts on direct output thread.
+// direct outputs can be a scarce resource in audio hardware and should
+// be released as quickly as possible.
+static const int8_t kMaxTrackRetriesDirect = 2;
static const int kDumpLockRetries = 50;
static const int kDumpLockSleep = 20000;
@@ -1794,6 +1798,9 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
uint32_t activeSleepTime = activeSleepTimeUs();
uint32_t idleSleepTime = idleSleepTimeUs();
uint32_t sleepTime = idleSleepTime;
+ // use shorter standby delay as on normal output to release
+ // hardware resources as soon as possible
+ nsecs_t standbyDelay = microseconds(activeSleepTime*2);
while (!exitPending())
@@ -1810,6 +1817,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
mixBufferSize = mFrameCount*mFrameSize;
activeSleepTime = activeSleepTimeUs();
idleSleepTime = idleSleepTimeUs();
+ standbyDelay = microseconds(activeSleepTime*2);
}
// put audio hardware into standby after short delay
@@ -1842,7 +1850,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
}
}
- standbyTime = systemTime() + kStandbyTimeInNsecs;
+ standbyTime = systemTime() + standbyDelay;
sleepTime = idleSleepTime;
continue;
}
@@ -1896,7 +1904,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
}
// reset retry count
- track->mRetryCount = kMaxTrackRetries;
+ track->mRetryCount = kMaxTrackRetriesDirect;
activeTrack = t;
mixerStatus = MIXER_TRACKS_READY;
} else {
@@ -1949,7 +1957,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
activeTrack->releaseBuffer(&buffer);
}
sleepTime = 0;
- standbyTime = systemTime() + kStandbyTimeInNsecs;
+ standbyTime = systemTime() + standbyDelay;
} else {
if (sleepTime == 0) {
if (mixerStatus == MIXER_TRACKS_ENABLED) {
diff --git a/libs/audioflinger/AudioPolicyManagerBase.cpp b/libs/audioflinger/AudioPolicyManagerBase.cpp
index a61221a..c8b3f48 100644
--- a/libs/audioflinger/AudioPolicyManagerBase.cpp
+++ b/libs/audioflinger/AudioPolicyManagerBase.cpp
@@ -458,11 +458,8 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str
}
#endif //AUDIO_POLICY_TEST
- // open a direct output if:
- // 1 a direct output is explicitely requested
- // 2 the audio format is compressed
- if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
- (format !=0 && !AudioSystem::isLinearPCM(format))) {
+ // open a direct output if required by specified parameters
+ if (needsDirectOuput(stream, samplingRate, format, channels, flags, device)) {
LOGV("getOutput() opening direct output device %x", device);
AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
@@ -472,7 +469,7 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str
outputDesc->mChannels = channels;
outputDesc->mLatency = 0;
outputDesc->mFlags = (AudioSystem::output_flags)(flags | AudioSystem::OUTPUT_FLAG_DIRECT);
- outputDesc->mRefCount[stream] = 1;
+ outputDesc->mRefCount[stream] = 0;
output = mpClientInterface->openOutput(&outputDesc->mDevice,
&outputDesc->mSamplingRate,
&outputDesc->mFormat,
@@ -609,6 +606,9 @@ status_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output, AudioSyste
setStrategyMute(STRATEGY_MEDIA, false, mA2dpOutput, mOutputs.valueFor(mHardwareOutput)->mLatency*2);
}
#endif
+ if (output != mHardwareOutput) {
+ setOutputDevice(mHardwareOutput, getNewDevice(mHardwareOutput), true);
+ }
return NO_ERROR;
} else {
LOGW("stopOutput() refcount is already 0 for output %d", output);
@@ -1550,10 +1550,10 @@ void AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, uint32_t
}
#ifdef WITH_A2DP
// filter devices according to output selected
- if (output == mHardwareOutput) {
- device &= ~AudioSystem::DEVICE_OUT_ALL_A2DP;
- } else {
+ if (output == mA2dpOutput) {
device &= AudioSystem::DEVICE_OUT_ALL_A2DP;
+ } else {
+ device &= ~AudioSystem::DEVICE_OUT_ALL_A2DP;
}
#endif
@@ -1562,8 +1562,7 @@ void AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, uint32_t
// - the requestede device is 0
// - the requested device is the same as current device and force is not specified.
// Doing this check here allows the caller to call setOutputDevice() without conditions
- if (device == 0 ||
- (device == prevDevice && !force)) {
+ if ((device == 0 || device == prevDevice) && !force) {
LOGV("setOutputDevice() setting same device %x or null device for output %d", device, output);
return;
}
@@ -1666,7 +1665,7 @@ float AudioPolicyManagerBase::computeVolume(int stream, int index, audio_io_hand
int volInt = (100 * (index - streamDesc.mIndexMin)) / (streamDesc.mIndexMax - streamDesc.mIndexMin);
volume = AudioSystem::linearToLog(volInt);
- // if a heaset is connected, apply the following rules to ring tones and notifications
+ // if a headset is connected, apply the following rules to ring tones and notifications
// to avoid sound level bursts in user's ears:
// - always attenuate ring tones and notifications volume by 6dB
// - if music is playing, always limit the volume to current music volume,
@@ -1825,6 +1824,17 @@ void AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting,
}
}
+bool AudioPolicyManagerBase::needsDirectOuput(AudioSystem::stream_type stream,
+ uint32_t samplingRate,
+ uint32_t format,
+ uint32_t channels,
+ AudioSystem::output_flags flags,
+ uint32_t device)
+{
+ return ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
+ (format !=0 && !AudioSystem::isLinearPCM(format)));
+}
+
// --- AudioOutputDescriptor class implementation
AudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor()