diff options
author | Eric Laurent <elaurent@google.com> | 2014-10-03 20:37:46 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-10-03 20:37:47 +0000 |
commit | 2b217bb3aee87ce8486014f261c0f498f6209e80 (patch) | |
tree | 3199fbc19fc6329f1e764ad63a478dbe2308ddc3 /services/audioflinger | |
parent | b220fe0e40bc3752b62a9576fc824634a16fc3ab (diff) | |
parent | 1b92868010b5c1409692a86f6b27e4a265b64c1a (diff) | |
download | frameworks_av-2b217bb3aee87ce8486014f261c0f498f6209e80.zip frameworks_av-2b217bb3aee87ce8486014f261c0f498f6209e80.tar.gz frameworks_av-2b217bb3aee87ce8486014f261c0f498f6209e80.tar.bz2 |
Merge "audioflinger: fix pre processing transfer between record threads." into lmp-dev
Diffstat (limited to 'services/audioflinger')
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 48 | ||||
-rw-r--r-- | services/audioflinger/Effects.cpp | 36 | ||||
-rw-r--r-- | services/audioflinger/Effects.h | 3 | ||||
-rw-r--r-- | services/audioflinger/Threads.cpp | 4 |
4 files changed, 76 insertions, 15 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index e200857..e48af20 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1436,6 +1436,16 @@ sp<IAudioRecord> AudioFlinger::openRecord( IPCThreadState::self()->getCallingUid(), flags, tid, &lStatus); LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0)); + + if (lStatus == NO_ERROR) { + // Check if one effect chain was awaiting for an AudioRecord to be created on this + // session and move it to this thread. + sp<EffectChain> chain = getOrphanEffectChain_l((audio_session_t)lSessionId); + if (chain != 0) { + Mutex::Autolock _l(thread->mLock); + thread->addEffectChain_l(chain); + } + } } if (lStatus != NO_ERROR) { @@ -2034,14 +2044,41 @@ status_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input) } ALOGV("closeInput() %d", input); + + // If we still have effect chains, it means that a client still holds a handle + // on at least one effect. We must either move the chain to an existing thread with the + // same session ID or put it aside in case a new record thread is opened for a + // new capture on the same session + sp<EffectChain> chain; { - // If we still have effect chains, it means that a client still holds a handle - // on at least one effect. We must keep the chain alive in case a new record - // thread is opened for a new capture on the same session Mutex::Autolock _sl(thread->mLock); Vector< sp<EffectChain> > effectChains = thread->getEffectChains_l(); - for (size_t i = 0; i < effectChains.size(); i++) { - putOrphanEffectChain_l(effectChains[i]); + // Note: maximum one chain per record thread + if (effectChains.size() != 0) { + chain = effectChains[0]; + } + } + if (chain != 0) { + // first check if a record thread is already opened with a client on the same session. + // This should only happen in case of overlap between one thread tear down and the + // creation of its replacement + size_t i; + for (i = 0; i < mRecordThreads.size(); i++) { + sp<RecordThread> t = mRecordThreads.valueAt(i); + if (t == thread) { + continue; + } + if (t->hasAudioSession(chain->sessionId()) != 0) { + Mutex::Autolock _l(t->mLock); + ALOGV("closeInput() found thread %d for effect session %d", + t->id(), chain->sessionId()); + t->addEffectChain_l(chain); + break; + } + } + // put the chain aside if we could not find a record thread with the same session id. + if (i == mRecordThreads.size()) { + putOrphanEffectChain_l(chain); } } audioConfigChanged(AudioSystem::INPUT_CLOSED, input, NULL); @@ -2478,6 +2515,7 @@ sp<IEffect> AudioFlinger::createEffect( // session and used it instead of creating a new one. sp<EffectChain> chain = getOrphanEffectChain_l((audio_session_t)sessionId); if (chain != 0) { + Mutex::Autolock _l(thread->mLock); thread->addEffectChain_l(chain); } } diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp index 4678880..bcaf8ae 100644 --- a/services/audioflinger/Effects.cpp +++ b/services/audioflinger/Effects.cpp @@ -440,6 +440,20 @@ status_t AudioFlinger::EffectModule::init() return status; } +void AudioFlinger::EffectModule::addEffectToHal_l() +{ + if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC || + (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) { + sp<ThreadBase> thread = mThread.promote(); + if (thread != 0) { + audio_stream_t *stream = thread->stream(); + if (stream != NULL) { + stream->add_audio_effect(stream, mEffectInterface); + } + } + } +} + status_t AudioFlinger::EffectModule::start() { Mutex::Autolock _l(mLock); @@ -466,16 +480,7 @@ status_t AudioFlinger::EffectModule::start_l() status = cmdStatus; } if (status == 0) { - if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC || - (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) { - sp<ThreadBase> thread = mThread.promote(); - if (thread != 0) { - audio_stream_t *stream = thread->stream(); - if (stream != NULL) { - stream->add_audio_effect(stream, mEffectInterface); - } - } - } + addEffectToHal_l(); sp<EffectChain> chain = mChain.promote(); if (chain != 0) { chain->forceVolume(); @@ -1696,6 +1701,17 @@ bool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right) return hasControl; } +void AudioFlinger::EffectChain::syncHalEffectsState() +{ + Mutex::Autolock _l(mLock); + for (size_t i = 0; i < mEffects.size(); i++) { + if (mEffects[i]->state() == EffectModule::ACTIVE || + mEffects[i]->state() == EffectModule::STOPPING) { + mEffects[i]->addEffectToHal_l(); + } + } +} + void AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args) { const size_t SIZE = 256; diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h index b87a1fd..6f93f81 100644 --- a/services/audioflinger/Effects.h +++ b/services/audioflinger/Effects.h @@ -119,6 +119,7 @@ public: { return (mDescriptor.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) != 0; } status_t setOffloaded(bool offloaded, audio_io_handle_t io); bool isOffloaded() const; + void addEffectToHal_l(); void dump(int fd, const Vector<String16>& args); @@ -325,6 +326,8 @@ public: // we are the only observers. bool isVolumeForced() { return (android_atomic_acquire_cas(true, false, &mForceVolume) == 0); } + void syncHalEffectsState(); + void dump(int fd, const Vector<String16>& args); protected: diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index b1e9c07..44e34b7 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -6207,6 +6207,10 @@ status_t AudioFlinger::RecordThread::addEffectChain_l(const sp<EffectChain>& cha checkSuspendOnAddEffectChain_l(chain); + // make sure enabled pre processing effects state is communicated to the HAL as we + // just moved them to a new input stream. + chain->syncHalEffectsState(); + mEffectChains.add(chain); return NO_ERROR; |