diff --git a/audio/AudioPolicyManagerBase.cpp b/audio/AudioPolicyManagerBase.cpp index c176146..dbca8ff 100644 --- a/audio/AudioPolicyManagerBase.cpp +++ b/audio/AudioPolicyManagerBase.cpp @@ -582,11 +582,22 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str flags = (AudioSystem::output_flags)(flags | AUDIO_OUTPUT_FLAG_DIRECT); } - IOProfile *profile = getProfileForDirectOutput(device, - samplingRate, - format, - channelMask, - (audio_output_flags_t)flags); + // Do not allow offloading if one non offloadable effect is enabled. This prevents from + // creating an offloaded track and tearing it down immediately after start when audioflinger + // detects there is an active non offloadable effect. + // FIXME: We should check the audio session here but we do not have it in this context. + // This may prevent offloading in rare situations where effects are left active by apps + // in the background. + IOProfile *profile = NULL; + if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) || + !isNonOffloadableEffectEnabled()) { + profile = getProfileForDirectOutput(device, + samplingRate, + format, + channelMask, + (audio_output_flags_t)flags); + } + if (profile != NULL) { AudioOutputDescriptor *outputDesc = NULL; @@ -1299,6 +1310,20 @@ status_t AudioPolicyManagerBase::setEffectEnabled(EffectDescriptor *pDesc, bool return NO_ERROR; } +bool AudioPolicyManagerBase::isNonOffloadableEffectEnabled() +{ + for (size_t i = 0; i < mEffects.size(); i++) { + const EffectDescriptor * const pDesc = mEffects.valueAt(i); + if (pDesc->mEnabled && (pDesc->mStrategy == STRATEGY_MEDIA) && + ((pDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) { + ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d", + pDesc->mDesc.name, pDesc->mSession); + return true; + } + } + return false; +} + bool AudioPolicyManagerBase::isStreamActive(int stream, uint32_t inPastMs) const { nsecs_t sysTime = systemTime(); @@ -1472,6 +1497,16 @@ bool AudioPolicyManagerBase::isOffloadSupported(const audio_offload_info_t& offl return false; } + // Do not allow offloading if one non offloadable effect is enabled. This prevents from + // creating an offloaded track and tearing it down immediately after start when audioflinger + // detects there is an active non offloadable effect. + // FIXME: We should check the audio session here but we do not have it in this context. + // This may prevent offloading in rare situations where effects are left active by apps + // in the background. + if (isNonOffloadableEffectEnabled()) { + return false; + } + // See if there is a profile to support this. // AUDIO_DEVICE_NONE IOProfile *profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */, diff --git a/include/hardware_legacy/AudioPolicyManagerBase.h b/include/hardware_legacy/AudioPolicyManagerBase.h index 482ea86..5fea77a 100644 --- a/include/hardware_legacy/AudioPolicyManagerBase.h +++ b/include/hardware_legacy/AudioPolicyManagerBase.h @@ -491,6 +491,8 @@ protected: audio_io_handle_t selectOutputForEffects(const SortedVector& outputs); + bool isNonOffloadableEffectEnabled(); + // // Audio policy configuration file parsing (audio_policy.conf) //