diff options
author | Eric Laurent <elaurent@google.com> | 2012-06-29 16:36:52 -0700 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2012-06-29 17:03:53 -0700 |
commit | 717e128691f083a9469a1d0e363ac6ecd5c65d58 (patch) | |
tree | 70761520a17703d543262ebe7778f51a360d7923 /services/audioflinger/AudioFlinger.cpp | |
parent | 33e28dd3c033641f4db9d1b99c7c88d6d08c61f7 (diff) | |
download | frameworks_av-717e128691f083a9469a1d0e363ac6ecd5c65d58.zip frameworks_av-717e128691f083a9469a1d0e363ac6ecd5c65d58.tar.gz frameworks_av-717e128691f083a9469a1d0e363ac6ecd5c65d58.tar.bz2 |
audioflinger: fix auxiliary effect attachment
Auxiliary effects (Reverb) are global effects and as such follow
the default rule which is to attach them to the output thread that
handles music streams by default. This causes a problem when several
threads are eligible to handle music streams as tracks can be attached
to either thread based on criteria unknown when teh effect is created.
The fix consists in moving the auxiliary effect if necessary when an
AudioTrack is attached to it and this track is not on the same
output thread.
Bug 6608561.
Change-Id: Ib32c3cabc731b2046aba728be1771982999c6069
Diffstat (limited to 'services/audioflinger/AudioFlinger.cpp')
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index b78c6d1..abe0293 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1106,6 +1106,20 @@ void AudioFlinger::removeClient_l(pid_t pid) mClients.removeItem(pid); } +// getEffectThread_l() must be called with AudioFlinger::mLock held +sp<AudioFlinger::PlaybackThread> AudioFlinger::getEffectThread_l(int sessionId, int EffectId) +{ + sp<PlaybackThread> thread; + + for (size_t i = 0; i < mPlaybackThreads.size(); i++) { + if (mPlaybackThreads.valueAt(i)->getEffect(sessionId, EffectId) != 0) { + ALOG_ASSERT(thread == 0); + thread = mPlaybackThreads.valueAt(i); + } + } + + return thread; +} // ---------------------------------------------------------------------------- @@ -4677,6 +4691,47 @@ status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId) sp<ThreadBase> thread = mThread.promote(); if (thread != 0) { PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); + sp<AudioFlinger> af = mClient->audioFlinger(); + + Mutex::Autolock _l(af->mLock); + + sp<PlaybackThread> srcThread = af->getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId); + if (srcThread == 0) { + return INVALID_OPERATION; + } + + if (EffectId != 0 && playbackThread != srcThread.get()) { + Mutex::Autolock _dl(playbackThread->mLock); + Mutex::Autolock _sl(srcThread->mLock); + sp<EffectChain> chain = srcThread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); + if (chain == 0) { + return INVALID_OPERATION; + } + + sp<EffectModule> effect = chain->getEffectFromId_l(EffectId); + if (effect == 0) { + return INVALID_OPERATION; + } + srcThread->removeEffect_l(effect); + playbackThread->addEffect_l(effect); + // removeEffect_l() has stopped the effect if it was active so it must be restarted + if (effect->state() == EffectModule::ACTIVE || + effect->state() == EffectModule::STOPPING) { + effect->start(); + } + + sp<EffectChain> dstChain = effect->chain().promote(); + if (dstChain == 0) { + srcThread->addEffect_l(effect); + return INVALID_OPERATION; + } + AudioSystem::unregisterEffect(effect->id()); + AudioSystem::registerEffect(&effect->desc(), + srcThread->id(), + dstChain->strategy(), + AUDIO_SESSION_OUTPUT_MIX, + effect->id()); + } status = playbackThread->attachAuxEffect(this, EffectId); } return status; @@ -7645,6 +7700,12 @@ Exit: return handle; } +sp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect(int sessionId, int effectId) +{ + Mutex::Autolock _l(mLock); + return getEffect_l(sessionId, effectId); +} + sp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect_l(int sessionId, int effectId) { sp<EffectChain> chain = getEffectChain_l(sessionId); |