audio flinger: add support for effects without process function
Add support for effects indicating they do not implement a process
function and do not consume CPU or add latency.
Enable those effects on RAW and FAST outputs and inputs.
Do not call the process function.
Bug: 31491112.
Change-Id: If020c8bb3b180568dec5138b087edec8c2524182
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index bbea971..aedde69 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -279,12 +279,29 @@
mConfig.inputCfg.buffer.s32,
mConfig.inputCfg.buffer.frameCount/2);
}
+ int ret;
+ if (isProcessImplemented()) {
+ // do the actual processing in the effect engine
+ ret = (*mEffectInterface)->process(mEffectInterface,
+ &mConfig.inputCfg.buffer,
+ &mConfig.outputCfg.buffer);
+ } else {
+ if (mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
+ size_t frameCnt = mConfig.inputCfg.buffer.frameCount * FCC_2; //always stereo here
+ int16_t *in = mConfig.inputCfg.buffer.s16;
+ int16_t *out = mConfig.outputCfg.buffer.s16;
- // do the actual processing in the effect engine
- int ret = (*mEffectInterface)->process(mEffectInterface,
- &mConfig.inputCfg.buffer,
- &mConfig.outputCfg.buffer);
-
+ if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
+ for (size_t i = 0; i < frameCnt; i++) {
+ out[i] = clamp16((int32_t)out[i] + (int32_t)in[i]);
+ }
+ } else {
+ memcpy(mConfig.outputCfg.buffer.raw, mConfig.inputCfg.buffer.raw,
+ frameCnt * sizeof(int16_t));
+ }
+ }
+ ret = -ENODATA;
+ }
// force transition to IDLE state when engine is ready
if (mState == STOPPED && ret == -ENODATA) {
mDisableWaitCnt = 1;
@@ -301,7 +318,7 @@
// accumulate input onto output
sp<EffectChain> chain = mChain.promote();
if (chain != 0 && chain->activeTrackCnt() != 0) {
- size_t frameCnt = mConfig.inputCfg.buffer.frameCount * 2; //always stereo here
+ size_t frameCnt = mConfig.inputCfg.buffer.frameCount * FCC_2; //always stereo here
int16_t *in = mConfig.inputCfg.buffer.s16;
int16_t *out = mConfig.outputCfg.buffer.s16;
for (size_t i = 0; i < frameCnt; i++) {
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 322c06a..da0f3c5 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -119,6 +119,8 @@
{ return (mDescriptor.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) != 0; }
bool isImplementationSoftware() const
{ return (mDescriptor.flags & EFFECT_FLAG_HW_ACC_MASK) == 0; }
+ bool isProcessImplemented() const
+ { return (mDescriptor.flags & EFFECT_FLAG_NO_PROCESS) == 0; }
status_t setOffloaded(bool offloaded, audio_io_handle_t io);
bool isOffloaded() const;
void addEffectToHal_l();
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 6aedd29..a91fc26 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1272,6 +1272,12 @@
desc->name, mThreadName);
return BAD_VALUE;
}
+
+ // always allow effects without processing load or latency
+ if ((desc->flags & EFFECT_FLAG_NO_PROCESS_MASK) == EFFECT_FLAG_NO_PROCESS) {
+ return NO_ERROR;
+ }
+
audio_input_flags_t flags = mInput->flags;
if (hasFastCapture() || (flags & AUDIO_INPUT_FLAG_FAST)) {
if (flags & AUDIO_INPUT_FLAG_RAW) {
@@ -1328,6 +1334,11 @@
break;
}
}
+
+ // always allow effects without processing load or latency
+ if ((desc->flags & EFFECT_FLAG_NO_PROCESS_MASK) == EFFECT_FLAG_NO_PROCESS) {
+ break;
+ }
if (flags & AUDIO_OUTPUT_FLAG_RAW) {
ALOGW("checkEffectCompatibility_l(): effect %s on playback thread in raw mode",
desc->name);