AudioFlinger: Improve effect compatibility with RAW and FAST
Effects without process function now are allowed with RAW
and FAST playback and record tracks.
Bug: 32053844
Change-Id: I58064eb2c357043c2da1a781a20988f42570d97e
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index aedde69..9711f2d 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -2032,15 +2032,49 @@
}
}
-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;
}
}
- 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
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index da0f3c5..818bf94 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -328,7 +328,17 @@
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;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 897873b..0f403ae 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1918,34 +1918,19 @@
// 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);
- }
- }
- // 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);
+ 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);
+ }
}
}
}
@@ -6594,12 +6579,11 @@
// 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,