Loading media/libeffects/proxy/EffectProxy.cpp +48 −11 Original line number Diff line number Diff line Loading @@ -48,6 +48,21 @@ static const effect_descriptor_t *const gDescriptors[] = &gProxyDescriptor, }; static inline bool isGetterCmd(uint32_t cmdCode) { switch (cmdCode) { case EFFECT_CMD_GET_PARAM: case EFFECT_CMD_GET_CONFIG: case EFFECT_CMD_GET_CONFIG_REVERSE: case EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: case EFFECT_CMD_GET_FEATURE_CONFIG: return true; default: return false; } } int EffectProxyCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, Loading Loading @@ -155,7 +170,6 @@ int Effect_process(effect_handle_t self, int index = pContext->index; // if the index refers to HW , do not do anything. Just return. if (index == SUB_FX_HOST) { ALOGV("Calling CoreProcess"); ret = (*pContext->eHandle[index])->process(pContext->eHandle[index], inBuffer, outBuffer); } Loading @@ -172,7 +186,7 @@ int Effect_command(effect_handle_t self, void *pReplyData) { EffectContext *pContext = (EffectContext *) self; int status; int status = 0; if (pContext == NULL) { ALOGV("Effect_command() Proxy context is NULL"); return -EINVAL; Loading Loading @@ -237,23 +251,46 @@ int Effect_command(effect_handle_t self, ALOGV("Effect_command: effect index is neither offload nor host"); return -EINVAL; } ALOGV("Effect_command: pContext->eHandle[%d]: %p", index, pContext->eHandle[index]); if (pContext->eHandle[SUB_FX_HOST]) (*pContext->eHandle[SUB_FX_HOST])->command( // Getter commands are only sent to the active sub effect. uint32_t hostReplySize = replySize != NULL ? *replySize : 0; bool hostReplied = false; int hostStatus = 0; uint32_t offloadReplySize = replySize != NULL ? *replySize : 0; bool offloadReplied = false; int offloadStatus = 0; if (pContext->eHandle[SUB_FX_HOST] && (!isGetterCmd(cmdCode) || index == SUB_FX_HOST)) { hostStatus = (*pContext->eHandle[SUB_FX_HOST])->command( pContext->eHandle[SUB_FX_HOST], cmdCode, cmdSize, pCmdData, replySize, pReplyData); if (pContext->eHandle[SUB_FX_OFFLOAD]) { pCmdData, replySize != NULL ? &hostReplySize : NULL, pReplyData); hostReplied = true; } if (pContext->eHandle[SUB_FX_OFFLOAD] && (!isGetterCmd(cmdCode) || index == SUB_FX_OFFLOAD)) { // In case of SET CMD, when the offload stream is unavailable, // we will store the effect param values in the DSP effect wrapper. // When the offload effects get enabled, we send these values to the // DSP during Effect_config. // So,we send the params to DSP wrapper also (*pContext->eHandle[SUB_FX_OFFLOAD])->command( offloadStatus = (*pContext->eHandle[SUB_FX_OFFLOAD])->command( pContext->eHandle[SUB_FX_OFFLOAD], cmdCode, cmdSize, pCmdData, replySize, pReplyData); pCmdData, replySize != NULL ? &offloadReplySize : NULL, pReplyData); offloadReplied = true; } return 0; // By convention the offloaded implementation reply is returned if command is processed by both // host and offloaded sub effects if (offloadReplied){ status = offloadStatus; if (replySize) { *replySize = offloadReplySize; } } else if (hostReplied) { status = hostStatus; if (replySize) { *replySize = hostReplySize; } } return status; } /* end Effect_command */ Loading media/libeffects/visualizer/EffectVisualizer.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ struct VisualizerContext { uint32_t mCaptureSize; uint32_t mScalingMode; uint8_t mState; uint8_t mLastCaptureIdx; uint32_t mLastCaptureIdx; uint32_t mLatency; struct timespec mBufferUpdateTime; uint8_t mCaptureBuf[CAPTURE_BUF_SIZE]; Loading Loading @@ -499,7 +499,7 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, memcpy(pReplyData, pContext->mCaptureBuf + CAPTURE_BUF_SIZE + capturePoint, size); pReplyData += size; pReplyData = (char *)pReplyData + size; captureSize -= size; capturePoint = 0; } Loading services/audioflinger/AudioFlinger.cpp +53 −36 Original line number Diff line number Diff line Loading @@ -98,7 +98,6 @@ size_t AudioFlinger::mTeeSinkOutputFrames = kTeeSinkOutputFramesDefault; size_t AudioFlinger::mTeeSinkTrackFrames = kTeeSinkTrackFramesDefault; #endif //TODO: remove when effect offload is implemented // In order to avoid invalidating offloaded tracks each time a Visualizer is turned on and off // we define a minimum time during which a global effect is considered enabled. static const nsecs_t kMinGlobalEffectEnabletimeNs = seconds(7200); Loading Loading @@ -2084,20 +2083,6 @@ sp<IEffect> AudioFlinger::createEffect( goto Exit; } if (io == 0) { if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) { // output must be specified by AudioPolicyManager when using session // AUDIO_SESSION_OUTPUT_STAGE lStatus = BAD_VALUE; goto Exit; } else if (sessionId == AUDIO_SESSION_OUTPUT_MIX) { // if the output returned by getOutputForEffect() is removed before we lock the // mutex below, the call to checkPlaybackThread_l(io) below will detect it // and we will exit safely io = AudioSystem::getOutputForEffect(&desc); } } { Mutex::Autolock _l(mLock); Loading Loading @@ -2180,6 +2165,20 @@ sp<IEffect> AudioFlinger::createEffect( // If output is 0 here, sessionId is neither SESSION_OUTPUT_STAGE nor SESSION_OUTPUT_MIX // because of code checking output when entering the function. // Note: io is never 0 when creating an effect on an input if (io == 0) { if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) { // output must be specified by AudioPolicyManager when using session // AUDIO_SESSION_OUTPUT_STAGE lStatus = BAD_VALUE; goto Exit; } if (sessionId == AUDIO_SESSION_OUTPUT_MIX) { // if the output returned by getOutputForEffect() is removed before we lock the // mutex below, the call to checkPlaybackThread_l(io) below will detect it // and we will exit safely io = AudioSystem::getOutputForEffect(&desc); ALOGV("createEffect got output %d", io); } if (io == 0) { // look for the thread where the specified audio session is present for (size_t i = 0; i < mPlaybackThreads.size(); i++) { Loading @@ -2196,6 +2195,7 @@ sp<IEffect> AudioFlinger::createEffect( } } } } // If no output thread contains the requested session ID, default to // first output. The effect chain will be moved to the correct output // thread when a track with the same session ID is created Loading Loading @@ -2254,9 +2254,7 @@ status_t AudioFlinger::moveEffects(int sessionId, audio_io_handle_t srcOutput, Mutex::Autolock _dl(dstThread->mLock); Mutex::Autolock _sl(srcThread->mLock); moveEffectChain_l(sessionId, srcThread, dstThread, false); return NO_ERROR; return moveEffectChain_l(sessionId, srcThread, dstThread, false); } // moveEffectChain_l must be called with both srcThread and dstThread mLocks held Loading @@ -2283,13 +2281,18 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId, // transfer all effects one by one so that new effect chain is created on new thread with // correct buffer sizes and audio parameters and effect engines reconfigured accordingly audio_io_handle_t dstOutput = dstThread->id(); sp<EffectChain> dstChain; uint32_t strategy = 0; // prevent compiler warning sp<EffectModule> effect = chain->getEffectFromId_l(0); Vector< sp<EffectModule> > removed; status_t status = NO_ERROR; while (effect != 0) { srcThread->removeEffect_l(effect); dstThread->addEffect_l(effect); removed.add(effect); status = dstThread->addEffect_l(effect); if (status != NO_ERROR) { break; } // removeEffect_l() has stopped the effect if it was active so it must be restarted if (effect->state() == EffectModule::ACTIVE || effect->state() == EffectModule::STOPPING) { Loading @@ -2301,15 +2304,15 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId, dstChain = effect->chain().promote(); if (dstChain == 0) { ALOGW("moveEffectChain_l() cannot get chain from effect %p", effect.get()); srcThread->addEffect_l(effect); return NO_INIT; status = NO_INIT; break; } strategy = dstChain->strategy(); } if (reRegister) { AudioSystem::unregisterEffect(effect->id()); AudioSystem::registerEffect(&effect->desc(), dstOutput, dstThread->id(), strategy, sessionId, effect->id()); Loading @@ -2317,10 +2320,24 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId, effect = chain->getEffectFromId_l(0); } return NO_ERROR; if (status != NO_ERROR) { for (size_t i = 0; i < removed.size(); i++) { srcThread->addEffect_l(removed[i]); if (dstChain != 0 && reRegister) { AudioSystem::unregisterEffect(removed[i]->id()); AudioSystem::registerEffect(&removed[i]->desc(), srcThread->id(), strategy, sessionId, removed[i]->id()); } } } return status; } bool AudioFlinger::isGlobalEffectEnabled_l() bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l() { if (mGlobalEffectEnableTime != 0 && ((systemTime() - mGlobalEffectEnableTime) < kMinGlobalEffectEnabletimeNs)) { Loading @@ -2330,14 +2347,14 @@ bool AudioFlinger::isGlobalEffectEnabled_l() for (size_t i = 0; i < mPlaybackThreads.size(); i++) { sp<EffectChain> ec = mPlaybackThreads.valueAt(i)->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); if (ec != 0 && ec->isEnabled()) { if (ec != 0 && ec->isNonOffloadableEnabled()) { return true; } } return false; } void AudioFlinger::onGlobalEffectEnable() void AudioFlinger::onNonOffloadableGlobalEffectEnable() { Mutex::Autolock _l(mLock); Loading services/audioflinger/AudioFlinger.h +2 −4 Original line number Diff line number Diff line Loading @@ -466,9 +466,8 @@ private: void removeClient_l(pid_t pid); void removeNotificationClient(pid_t pid); //TODO: remove when effect offload is implemented bool isGlobalEffectEnabled_l(); void onGlobalEffectEnable(); bool isNonOffloadableGlobalEffectEnabled_l(); void onNonOffloadableGlobalEffectEnable(); class AudioHwDevice { public: Loading Loading @@ -645,7 +644,6 @@ public: private: bool mIsLowRamDevice; bool mIsDeviceTypeKnown; //TODO: remove when effect offload is implemented nsecs_t mGlobalEffectEnableTime; // when a global effect was last enabled }; Loading services/audioflinger/Effects.cpp +44 −5 Original line number Diff line number Diff line Loading @@ -764,6 +764,46 @@ bool AudioFlinger::EffectModule::purgeHandles() return enabled; } status_t AudioFlinger::EffectModule::setOffloaded(bool offloaded, audio_io_handle_t io) { Mutex::Autolock _l(mLock); if (mStatus != NO_ERROR) { return mStatus; } status_t status = NO_ERROR; if ((mDescriptor.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) != 0) { status_t cmdStatus; uint32_t size = sizeof(status_t); effect_offload_param_t cmd; cmd.isOffload = offloaded; cmd.ioHandle = io; status = (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_OFFLOAD, sizeof(effect_offload_param_t), &cmd, &size, &cmdStatus); if (status == NO_ERROR) { status = cmdStatus; } mOffloaded = (status == NO_ERROR) ? offloaded : false; } else { if (offloaded) { status = INVALID_OPERATION; } mOffloaded = false; } ALOGV("setOffloaded() offloaded %d io %d status %d", offloaded, io, status); return status; } bool AudioFlinger::EffectModule::isOffloaded() const { Mutex::Autolock _l(mLock); return mOffloaded; } void AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args) { const size_t SIZE = 256; Loading Loading @@ -932,14 +972,13 @@ status_t AudioFlinger::EffectHandle::enable() } mEnabled = false; } else { //TODO: remove when effect offload is implemented if (thread != 0) { if (thread != 0 && !mEffect->isOffloadable()) { if ((thread->type() == ThreadBase::OFFLOAD)) { PlaybackThread *t = (PlaybackThread *)thread.get(); t->invalidateTracks(AUDIO_STREAM_MUSIC); } if (mEffect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) { thread->mAudioFlinger->onGlobalEffectEnable(); thread->mAudioFlinger->onNonOffloadableGlobalEffectEnable(); } } } Loading Loading @@ -1728,12 +1767,12 @@ void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModul } } bool AudioFlinger::EffectChain::isEnabled() bool AudioFlinger::EffectChain::isNonOffloadableEnabled() { Mutex::Autolock _l(mLock); size_t size = mEffects.size(); for (size_t i = 0; i < size; i++) { if (mEffects[i]->isEnabled()) { if (mEffects[i]->isEnabled() && !mEffects[i]->isOffloadable()) { return true; } } Loading Loading
media/libeffects/proxy/EffectProxy.cpp +48 −11 Original line number Diff line number Diff line Loading @@ -48,6 +48,21 @@ static const effect_descriptor_t *const gDescriptors[] = &gProxyDescriptor, }; static inline bool isGetterCmd(uint32_t cmdCode) { switch (cmdCode) { case EFFECT_CMD_GET_PARAM: case EFFECT_CMD_GET_CONFIG: case EFFECT_CMD_GET_CONFIG_REVERSE: case EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: case EFFECT_CMD_GET_FEATURE_CONFIG: return true; default: return false; } } int EffectProxyCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, Loading Loading @@ -155,7 +170,6 @@ int Effect_process(effect_handle_t self, int index = pContext->index; // if the index refers to HW , do not do anything. Just return. if (index == SUB_FX_HOST) { ALOGV("Calling CoreProcess"); ret = (*pContext->eHandle[index])->process(pContext->eHandle[index], inBuffer, outBuffer); } Loading @@ -172,7 +186,7 @@ int Effect_command(effect_handle_t self, void *pReplyData) { EffectContext *pContext = (EffectContext *) self; int status; int status = 0; if (pContext == NULL) { ALOGV("Effect_command() Proxy context is NULL"); return -EINVAL; Loading Loading @@ -237,23 +251,46 @@ int Effect_command(effect_handle_t self, ALOGV("Effect_command: effect index is neither offload nor host"); return -EINVAL; } ALOGV("Effect_command: pContext->eHandle[%d]: %p", index, pContext->eHandle[index]); if (pContext->eHandle[SUB_FX_HOST]) (*pContext->eHandle[SUB_FX_HOST])->command( // Getter commands are only sent to the active sub effect. uint32_t hostReplySize = replySize != NULL ? *replySize : 0; bool hostReplied = false; int hostStatus = 0; uint32_t offloadReplySize = replySize != NULL ? *replySize : 0; bool offloadReplied = false; int offloadStatus = 0; if (pContext->eHandle[SUB_FX_HOST] && (!isGetterCmd(cmdCode) || index == SUB_FX_HOST)) { hostStatus = (*pContext->eHandle[SUB_FX_HOST])->command( pContext->eHandle[SUB_FX_HOST], cmdCode, cmdSize, pCmdData, replySize, pReplyData); if (pContext->eHandle[SUB_FX_OFFLOAD]) { pCmdData, replySize != NULL ? &hostReplySize : NULL, pReplyData); hostReplied = true; } if (pContext->eHandle[SUB_FX_OFFLOAD] && (!isGetterCmd(cmdCode) || index == SUB_FX_OFFLOAD)) { // In case of SET CMD, when the offload stream is unavailable, // we will store the effect param values in the DSP effect wrapper. // When the offload effects get enabled, we send these values to the // DSP during Effect_config. // So,we send the params to DSP wrapper also (*pContext->eHandle[SUB_FX_OFFLOAD])->command( offloadStatus = (*pContext->eHandle[SUB_FX_OFFLOAD])->command( pContext->eHandle[SUB_FX_OFFLOAD], cmdCode, cmdSize, pCmdData, replySize, pReplyData); pCmdData, replySize != NULL ? &offloadReplySize : NULL, pReplyData); offloadReplied = true; } return 0; // By convention the offloaded implementation reply is returned if command is processed by both // host and offloaded sub effects if (offloadReplied){ status = offloadStatus; if (replySize) { *replySize = offloadReplySize; } } else if (hostReplied) { status = hostStatus; if (replySize) { *replySize = hostReplySize; } } return status; } /* end Effect_command */ Loading
media/libeffects/visualizer/EffectVisualizer.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ struct VisualizerContext { uint32_t mCaptureSize; uint32_t mScalingMode; uint8_t mState; uint8_t mLastCaptureIdx; uint32_t mLastCaptureIdx; uint32_t mLatency; struct timespec mBufferUpdateTime; uint8_t mCaptureBuf[CAPTURE_BUF_SIZE]; Loading Loading @@ -499,7 +499,7 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, memcpy(pReplyData, pContext->mCaptureBuf + CAPTURE_BUF_SIZE + capturePoint, size); pReplyData += size; pReplyData = (char *)pReplyData + size; captureSize -= size; capturePoint = 0; } Loading
services/audioflinger/AudioFlinger.cpp +53 −36 Original line number Diff line number Diff line Loading @@ -98,7 +98,6 @@ size_t AudioFlinger::mTeeSinkOutputFrames = kTeeSinkOutputFramesDefault; size_t AudioFlinger::mTeeSinkTrackFrames = kTeeSinkTrackFramesDefault; #endif //TODO: remove when effect offload is implemented // In order to avoid invalidating offloaded tracks each time a Visualizer is turned on and off // we define a minimum time during which a global effect is considered enabled. static const nsecs_t kMinGlobalEffectEnabletimeNs = seconds(7200); Loading Loading @@ -2084,20 +2083,6 @@ sp<IEffect> AudioFlinger::createEffect( goto Exit; } if (io == 0) { if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) { // output must be specified by AudioPolicyManager when using session // AUDIO_SESSION_OUTPUT_STAGE lStatus = BAD_VALUE; goto Exit; } else if (sessionId == AUDIO_SESSION_OUTPUT_MIX) { // if the output returned by getOutputForEffect() is removed before we lock the // mutex below, the call to checkPlaybackThread_l(io) below will detect it // and we will exit safely io = AudioSystem::getOutputForEffect(&desc); } } { Mutex::Autolock _l(mLock); Loading Loading @@ -2180,6 +2165,20 @@ sp<IEffect> AudioFlinger::createEffect( // If output is 0 here, sessionId is neither SESSION_OUTPUT_STAGE nor SESSION_OUTPUT_MIX // because of code checking output when entering the function. // Note: io is never 0 when creating an effect on an input if (io == 0) { if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) { // output must be specified by AudioPolicyManager when using session // AUDIO_SESSION_OUTPUT_STAGE lStatus = BAD_VALUE; goto Exit; } if (sessionId == AUDIO_SESSION_OUTPUT_MIX) { // if the output returned by getOutputForEffect() is removed before we lock the // mutex below, the call to checkPlaybackThread_l(io) below will detect it // and we will exit safely io = AudioSystem::getOutputForEffect(&desc); ALOGV("createEffect got output %d", io); } if (io == 0) { // look for the thread where the specified audio session is present for (size_t i = 0; i < mPlaybackThreads.size(); i++) { Loading @@ -2196,6 +2195,7 @@ sp<IEffect> AudioFlinger::createEffect( } } } } // If no output thread contains the requested session ID, default to // first output. The effect chain will be moved to the correct output // thread when a track with the same session ID is created Loading Loading @@ -2254,9 +2254,7 @@ status_t AudioFlinger::moveEffects(int sessionId, audio_io_handle_t srcOutput, Mutex::Autolock _dl(dstThread->mLock); Mutex::Autolock _sl(srcThread->mLock); moveEffectChain_l(sessionId, srcThread, dstThread, false); return NO_ERROR; return moveEffectChain_l(sessionId, srcThread, dstThread, false); } // moveEffectChain_l must be called with both srcThread and dstThread mLocks held Loading @@ -2283,13 +2281,18 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId, // transfer all effects one by one so that new effect chain is created on new thread with // correct buffer sizes and audio parameters and effect engines reconfigured accordingly audio_io_handle_t dstOutput = dstThread->id(); sp<EffectChain> dstChain; uint32_t strategy = 0; // prevent compiler warning sp<EffectModule> effect = chain->getEffectFromId_l(0); Vector< sp<EffectModule> > removed; status_t status = NO_ERROR; while (effect != 0) { srcThread->removeEffect_l(effect); dstThread->addEffect_l(effect); removed.add(effect); status = dstThread->addEffect_l(effect); if (status != NO_ERROR) { break; } // removeEffect_l() has stopped the effect if it was active so it must be restarted if (effect->state() == EffectModule::ACTIVE || effect->state() == EffectModule::STOPPING) { Loading @@ -2301,15 +2304,15 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId, dstChain = effect->chain().promote(); if (dstChain == 0) { ALOGW("moveEffectChain_l() cannot get chain from effect %p", effect.get()); srcThread->addEffect_l(effect); return NO_INIT; status = NO_INIT; break; } strategy = dstChain->strategy(); } if (reRegister) { AudioSystem::unregisterEffect(effect->id()); AudioSystem::registerEffect(&effect->desc(), dstOutput, dstThread->id(), strategy, sessionId, effect->id()); Loading @@ -2317,10 +2320,24 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId, effect = chain->getEffectFromId_l(0); } return NO_ERROR; if (status != NO_ERROR) { for (size_t i = 0; i < removed.size(); i++) { srcThread->addEffect_l(removed[i]); if (dstChain != 0 && reRegister) { AudioSystem::unregisterEffect(removed[i]->id()); AudioSystem::registerEffect(&removed[i]->desc(), srcThread->id(), strategy, sessionId, removed[i]->id()); } } } return status; } bool AudioFlinger::isGlobalEffectEnabled_l() bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l() { if (mGlobalEffectEnableTime != 0 && ((systemTime() - mGlobalEffectEnableTime) < kMinGlobalEffectEnabletimeNs)) { Loading @@ -2330,14 +2347,14 @@ bool AudioFlinger::isGlobalEffectEnabled_l() for (size_t i = 0; i < mPlaybackThreads.size(); i++) { sp<EffectChain> ec = mPlaybackThreads.valueAt(i)->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); if (ec != 0 && ec->isEnabled()) { if (ec != 0 && ec->isNonOffloadableEnabled()) { return true; } } return false; } void AudioFlinger::onGlobalEffectEnable() void AudioFlinger::onNonOffloadableGlobalEffectEnable() { Mutex::Autolock _l(mLock); Loading
services/audioflinger/AudioFlinger.h +2 −4 Original line number Diff line number Diff line Loading @@ -466,9 +466,8 @@ private: void removeClient_l(pid_t pid); void removeNotificationClient(pid_t pid); //TODO: remove when effect offload is implemented bool isGlobalEffectEnabled_l(); void onGlobalEffectEnable(); bool isNonOffloadableGlobalEffectEnabled_l(); void onNonOffloadableGlobalEffectEnable(); class AudioHwDevice { public: Loading Loading @@ -645,7 +644,6 @@ public: private: bool mIsLowRamDevice; bool mIsDeviceTypeKnown; //TODO: remove when effect offload is implemented nsecs_t mGlobalEffectEnableTime; // when a global effect was last enabled }; Loading
services/audioflinger/Effects.cpp +44 −5 Original line number Diff line number Diff line Loading @@ -764,6 +764,46 @@ bool AudioFlinger::EffectModule::purgeHandles() return enabled; } status_t AudioFlinger::EffectModule::setOffloaded(bool offloaded, audio_io_handle_t io) { Mutex::Autolock _l(mLock); if (mStatus != NO_ERROR) { return mStatus; } status_t status = NO_ERROR; if ((mDescriptor.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) != 0) { status_t cmdStatus; uint32_t size = sizeof(status_t); effect_offload_param_t cmd; cmd.isOffload = offloaded; cmd.ioHandle = io; status = (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_OFFLOAD, sizeof(effect_offload_param_t), &cmd, &size, &cmdStatus); if (status == NO_ERROR) { status = cmdStatus; } mOffloaded = (status == NO_ERROR) ? offloaded : false; } else { if (offloaded) { status = INVALID_OPERATION; } mOffloaded = false; } ALOGV("setOffloaded() offloaded %d io %d status %d", offloaded, io, status); return status; } bool AudioFlinger::EffectModule::isOffloaded() const { Mutex::Autolock _l(mLock); return mOffloaded; } void AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args) { const size_t SIZE = 256; Loading Loading @@ -932,14 +972,13 @@ status_t AudioFlinger::EffectHandle::enable() } mEnabled = false; } else { //TODO: remove when effect offload is implemented if (thread != 0) { if (thread != 0 && !mEffect->isOffloadable()) { if ((thread->type() == ThreadBase::OFFLOAD)) { PlaybackThread *t = (PlaybackThread *)thread.get(); t->invalidateTracks(AUDIO_STREAM_MUSIC); } if (mEffect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) { thread->mAudioFlinger->onGlobalEffectEnable(); thread->mAudioFlinger->onNonOffloadableGlobalEffectEnable(); } } } Loading Loading @@ -1728,12 +1767,12 @@ void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModul } } bool AudioFlinger::EffectChain::isEnabled() bool AudioFlinger::EffectChain::isNonOffloadableEnabled() { Mutex::Autolock _l(mLock); size_t size = mEffects.size(); for (size_t i = 0; i < size; i++) { if (mEffects[i]->isEnabled()) { if (mEffects[i]->isEnabled() && !mEffects[i]->isOffloadable()) { return true; } } Loading