diff options
author | Eric Laurent <elaurent@google.com> | 2010-03-11 14:47:00 -0800 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2010-03-16 17:32:18 -0700 |
commit | ef9500fe53b6ec67b610207832b52f8bfbb20cd5 (patch) | |
tree | 00a5eea1602d0a358603b0d4e741b0b51f2a36b5 /libs | |
parent | 1a3786a3e34112e3e68e6a9b07ba72802867a002 (diff) | |
download | frameworks_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.cpp | 14 | ||||
-rw-r--r-- | libs/audioflinger/AudioPolicyManagerBase.cpp | 34 |
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() |