Loading services/audioflinger/AudioFlinger.cpp +43 −5 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 keep the chain alive in case a new record // thread is opened for a new capture on the same session // 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; { 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); Loading Loading @@ -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); } } Loading services/audioflinger/Effects.cpp +26 −10 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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(); Loading Loading @@ -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; Loading services/audioflinger/Effects.h +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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: Loading services/audioflinger/Threads.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading
services/audioflinger/AudioFlinger.cpp +43 −5 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 keep the chain alive in case a new record // thread is opened for a new capture on the same session // 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; { 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); Loading Loading @@ -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); } } Loading
services/audioflinger/Effects.cpp +26 −10 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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(); Loading Loading @@ -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; Loading
services/audioflinger/Effects.h +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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: Loading
services/audioflinger/Threads.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading