Loading services/audioflinger/Effects.cpp +39 −5 Original line number Diff line number Diff line Loading @@ -2032,16 +2032,50 @@ void AudioFlinger::EffectChain::setThread(const sp<ThreadBase>& thread) } } bool AudioFlinger::EffectChain::hasSoftwareEffect() const void AudioFlinger::EffectChain::checkOutputFlagCompatibility(audio_output_flags_t *flags) const { if ((*flags & AUDIO_OUTPUT_FLAG_RAW) != 0 && !isRawCompatible()) { *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_RAW); } if ((*flags & AUDIO_OUTPUT_FLAG_FAST) != 0 && !isFastCompatible()) { *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_FAST); } } void AudioFlinger::EffectChain::checkInputFlagCompatibility(audio_input_flags_t *flags) const { if ((*flags & AUDIO_INPUT_FLAG_RAW) != 0 && !isRawCompatible()) { *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_RAW); } if ((*flags & AUDIO_INPUT_FLAG_FAST) != 0 && !isFastCompatible()) { *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_FAST); } } bool AudioFlinger::EffectChain::isRawCompatible() const { Mutex::Autolock _l(mLock); for (size_t i = 0; i < mEffects.size(); i++) { if (mEffects[i]->isImplementationSoftware()) { return true; for (const auto &effect : mEffects) { if (effect->isProcessImplemented()) { return false; } } // Allow effects without processing. return true; } bool AudioFlinger::EffectChain::isFastCompatible() const { Mutex::Autolock _l(mLock); for (const auto &effect : mEffects) { if (effect->isProcessImplemented() && effect->isImplementationSoftware()) { return false; } } // Allow effects without processing or hw accelerated effects. return true; } // isCompatibleWithThread_l() must be called with thread->mLock held bool AudioFlinger::EffectChain::isCompatibleWithThread_l(const sp<ThreadBase>& thread) const Loading services/audioflinger/Effects.h +11 −1 Original line number Diff line number Diff line Loading @@ -328,7 +328,17 @@ public: void syncHalEffectsState(); bool hasSoftwareEffect() const; // flags is an ORed set of audio_output_flags_t which is updated on return. void checkOutputFlagCompatibility(audio_output_flags_t *flags) const; // flags is an ORed set of audio_input_flags_t which is updated on return. void checkInputFlagCompatibility(audio_input_flags_t *flags) const; // Is this EffectChain compatible with the RAW audio flag. bool isRawCompatible() const; // Is this EffectChain compatible with the FAST audio flag. bool isFastCompatible() const; // isCompatibleWithThread_l() must be called with thread->mLock held bool isCompatibleWithThread_l(const sp<ThreadBase>& thread) const; Loading services/audioflinger/Threads.cpp +18 −34 Original line number Diff line number Diff line Loading @@ -1918,34 +1918,19 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac // check compatibility with audio effects. { // scope for mLock Mutex::Autolock _l(mLock); // do not accept RAW flag if post processing are present. Note that post processing on // a fast mixer are necessarily hardware sp<EffectChain> chain = getEffectChain_l(AUDIO_SESSION_OUTPUT_STAGE); if (chain != 0) { ALOGV_IF((*flags & AUDIO_OUTPUT_FLAG_RAW) != 0, "AUDIO_OUTPUT_FLAG_RAW denied: post processing effect present"); *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_RAW); } // Do not accept FAST flag if software global effects are present chain = getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); if (chain != 0) { ALOGV_IF((*flags & AUDIO_OUTPUT_FLAG_RAW) != 0, "AUDIO_OUTPUT_FLAG_RAW denied: global effect present"); *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_RAW); if (chain->hasSoftwareEffect()) { ALOGV("AUDIO_OUTPUT_FLAG_FAST denied: software global effect present"); *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_FAST); } for (audio_session_t session : { AUDIO_SESSION_OUTPUT_STAGE, AUDIO_SESSION_OUTPUT_MIX, sessionId, }) { sp<EffectChain> chain = getEffectChain_l(session); if (chain.get() != nullptr) { audio_output_flags_t old = *flags; chain->checkOutputFlagCompatibility(flags); if (old != *flags) { ALOGV("AUDIO_OUTPUT_FLAGS denied by effect, session=%d old=%#x new=%#x", (int)session, (int)old, (int)*flags); } // Do not accept FAST flag if the session has software effects chain = getEffectChain_l(sessionId); if (chain != 0) { ALOGV_IF((*flags & AUDIO_OUTPUT_FLAG_RAW) != 0, "AUDIO_OUTPUT_FLAG_RAW denied: effect present on session"); *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_RAW); if (chain->hasSoftwareEffect()) { ALOGV("AUDIO_OUTPUT_FLAG_FAST denied: software effect present on session"); *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_FAST); } } } Loading Loading @@ -6594,12 +6579,11 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRe // Do not accept FAST flag if the session has software effects sp<EffectChain> chain = getEffectChain_l(sessionId); if (chain != 0) { ALOGV_IF((*flags & AUDIO_INPUT_FLAG_RAW) != 0, "AUDIO_INPUT_FLAG_RAW denied: effect present on session"); *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_RAW); if (chain->hasSoftwareEffect()) { ALOGV("AUDIO_INPUT_FLAG_FAST denied: software effect present on session"); *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_FAST); audio_input_flags_t old = *flags; chain->checkInputFlagCompatibility(flags); if (old != *flags) { ALOGV("AUDIO_INPUT_FLAGS denied by effect old=%#x new=%#x", (int)old, (int)*flags); } } ALOGV_IF((*flags & AUDIO_INPUT_FLAG_FAST) != 0, Loading Loading
services/audioflinger/Effects.cpp +39 −5 Original line number Diff line number Diff line Loading @@ -2032,16 +2032,50 @@ void AudioFlinger::EffectChain::setThread(const sp<ThreadBase>& thread) } } bool AudioFlinger::EffectChain::hasSoftwareEffect() const void AudioFlinger::EffectChain::checkOutputFlagCompatibility(audio_output_flags_t *flags) const { if ((*flags & AUDIO_OUTPUT_FLAG_RAW) != 0 && !isRawCompatible()) { *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_RAW); } if ((*flags & AUDIO_OUTPUT_FLAG_FAST) != 0 && !isFastCompatible()) { *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_FAST); } } void AudioFlinger::EffectChain::checkInputFlagCompatibility(audio_input_flags_t *flags) const { if ((*flags & AUDIO_INPUT_FLAG_RAW) != 0 && !isRawCompatible()) { *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_RAW); } if ((*flags & AUDIO_INPUT_FLAG_FAST) != 0 && !isFastCompatible()) { *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_FAST); } } bool AudioFlinger::EffectChain::isRawCompatible() const { Mutex::Autolock _l(mLock); for (size_t i = 0; i < mEffects.size(); i++) { if (mEffects[i]->isImplementationSoftware()) { return true; for (const auto &effect : mEffects) { if (effect->isProcessImplemented()) { return false; } } // Allow effects without processing. return true; } bool AudioFlinger::EffectChain::isFastCompatible() const { Mutex::Autolock _l(mLock); for (const auto &effect : mEffects) { if (effect->isProcessImplemented() && effect->isImplementationSoftware()) { return false; } } // Allow effects without processing or hw accelerated effects. return true; } // isCompatibleWithThread_l() must be called with thread->mLock held bool AudioFlinger::EffectChain::isCompatibleWithThread_l(const sp<ThreadBase>& thread) const Loading
services/audioflinger/Effects.h +11 −1 Original line number Diff line number Diff line Loading @@ -328,7 +328,17 @@ public: void syncHalEffectsState(); bool hasSoftwareEffect() const; // flags is an ORed set of audio_output_flags_t which is updated on return. void checkOutputFlagCompatibility(audio_output_flags_t *flags) const; // flags is an ORed set of audio_input_flags_t which is updated on return. void checkInputFlagCompatibility(audio_input_flags_t *flags) const; // Is this EffectChain compatible with the RAW audio flag. bool isRawCompatible() const; // Is this EffectChain compatible with the FAST audio flag. bool isFastCompatible() const; // isCompatibleWithThread_l() must be called with thread->mLock held bool isCompatibleWithThread_l(const sp<ThreadBase>& thread) const; Loading
services/audioflinger/Threads.cpp +18 −34 Original line number Diff line number Diff line Loading @@ -1918,34 +1918,19 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac // check compatibility with audio effects. { // scope for mLock Mutex::Autolock _l(mLock); // do not accept RAW flag if post processing are present. Note that post processing on // a fast mixer are necessarily hardware sp<EffectChain> chain = getEffectChain_l(AUDIO_SESSION_OUTPUT_STAGE); if (chain != 0) { ALOGV_IF((*flags & AUDIO_OUTPUT_FLAG_RAW) != 0, "AUDIO_OUTPUT_FLAG_RAW denied: post processing effect present"); *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_RAW); } // Do not accept FAST flag if software global effects are present chain = getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); if (chain != 0) { ALOGV_IF((*flags & AUDIO_OUTPUT_FLAG_RAW) != 0, "AUDIO_OUTPUT_FLAG_RAW denied: global effect present"); *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_RAW); if (chain->hasSoftwareEffect()) { ALOGV("AUDIO_OUTPUT_FLAG_FAST denied: software global effect present"); *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_FAST); } for (audio_session_t session : { AUDIO_SESSION_OUTPUT_STAGE, AUDIO_SESSION_OUTPUT_MIX, sessionId, }) { sp<EffectChain> chain = getEffectChain_l(session); if (chain.get() != nullptr) { audio_output_flags_t old = *flags; chain->checkOutputFlagCompatibility(flags); if (old != *flags) { ALOGV("AUDIO_OUTPUT_FLAGS denied by effect, session=%d old=%#x new=%#x", (int)session, (int)old, (int)*flags); } // Do not accept FAST flag if the session has software effects chain = getEffectChain_l(sessionId); if (chain != 0) { ALOGV_IF((*flags & AUDIO_OUTPUT_FLAG_RAW) != 0, "AUDIO_OUTPUT_FLAG_RAW denied: effect present on session"); *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_RAW); if (chain->hasSoftwareEffect()) { ALOGV("AUDIO_OUTPUT_FLAG_FAST denied: software effect present on session"); *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_FAST); } } } Loading Loading @@ -6594,12 +6579,11 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRe // Do not accept FAST flag if the session has software effects sp<EffectChain> chain = getEffectChain_l(sessionId); if (chain != 0) { ALOGV_IF((*flags & AUDIO_INPUT_FLAG_RAW) != 0, "AUDIO_INPUT_FLAG_RAW denied: effect present on session"); *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_RAW); if (chain->hasSoftwareEffect()) { ALOGV("AUDIO_INPUT_FLAG_FAST denied: software effect present on session"); *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_FAST); audio_input_flags_t old = *flags; chain->checkInputFlagCompatibility(flags); if (old != *flags) { ALOGV("AUDIO_INPUT_FLAGS denied by effect old=%#x new=%#x", (int)old, (int)*flags); } } ALOGV_IF((*flags & AUDIO_INPUT_FLAG_FAST) != 0, Loading