diff options
author | Eric Laurent <elaurent@google.com> | 2010-09-28 14:09:57 -0700 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2010-09-28 14:23:39 -0700 |
commit | dac69110ed1073bf0a9827a3f78698896dd05d97 (patch) | |
tree | db990d1cf1867854ffbf39585c0ce19e436c56b9 /services | |
parent | 036fad5034d05beecae19da6da46e1ce7be78e64 (diff) | |
download | frameworks_av-dac69110ed1073bf0a9827a3f78698896dd05d97.zip frameworks_av-dac69110ed1073bf0a9827a3f78698896dd05d97.tar.gz frameworks_av-dac69110ed1073bf0a9827a3f78698896dd05d97.tar.bz2 |
Fix several audio effects problems.
Fixed the following issues in LVM effect bundle wrapper:
- memory leaks in EffectCreate() in case effect creation fails at various stages
- Added saturation when accumulating to output buffer
- Fixed problems with enabled effects count when an effect is released while enabled
- Do not allocate temporary buffer for accumulation each time process() is called
Fixed the following issues in effects framework (AudioFlinger)
- Release effect synchronously in the library when deleted from effect chain
- Do not call the effect process function if no tracks are present in the same
audio session
Change-Id: Ifbd80a163415cfb3c0a337c12082853ea45d9c91
Diffstat (limited to 'services')
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 8a732ed..97b8086 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -5332,6 +5332,15 @@ size_t AudioFlinger::EffectModule::removeHandle(const wp<EffectHandle>& handle) } } + // Release effect engine here so that it is done immediately. Otherwise it will be released + // by the destructor when the last strong reference on the this object is released which can + // happen after next process is called on this effect. + if (size == 0 && mEffectInterface != NULL) { + // release effect engine + EffectRelease(mEffectInterface); + mEffectInterface = NULL; + } + return size; } @@ -6145,21 +6154,36 @@ sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int // Must be called with EffectChain::mLock locked void AudioFlinger::EffectChain::process_l() { + sp<ThreadBase> thread = mThread.promote(); + if (thread == 0) { + LOGW("process_l(): cannot promote mixer thread"); + return; + } + PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); + bool isGlobalSession = (mSessionId == AudioSystem::SESSION_OUTPUT_MIX) || + (mSessionId == AudioSystem::SESSION_OUTPUT_STAGE); + bool tracksOnSession = false; + if (!isGlobalSession) { + tracksOnSession = + playbackThread->hasAudioSession(mSessionId) & PlaybackThread::TRACK_SESSION; + } + size_t size = mEffects.size(); - for (size_t i = 0; i < size; i++) { - mEffects[i]->process(); + // do not process effect if no track is present in same audio session + if (isGlobalSession || tracksOnSession) { + for (size_t i = 0; i < size; i++) { + mEffects[i]->process(); + } } for (size_t i = 0; i < size; i++) { mEffects[i]->updateState(); } // if no track is active, input buffer must be cleared here as the mixer process // will not do it - if (mSessionId > 0 && activeTracks() == 0) { - sp<ThreadBase> thread = mThread.promote(); - if (thread != 0) { - size_t numSamples = thread->frameCount() * thread->channelCount(); - memset(mInBuffer, 0, numSamples * sizeof(int16_t)); - } + if (tracksOnSession && + activeTracks() == 0) { + size_t numSamples = playbackThread->frameCount() * playbackThread->channelCount(); + memset(mInBuffer, 0, numSamples * sizeof(int16_t)); } } |