From 813e2a74853bde19e37d878c596a044b3f299efc Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Sat, 31 Aug 2013 12:59:48 -0700 Subject: audioflinger: no effects on offloaded tracks Invalidate offloaded tracks when an effect is enabled so that the track is recreated in PCM mode and the effect can be applied. This is temporary until effect offloading is implemented. Bug: 8174034. Change-Id: I77b8b54a10db6cb8334be76d863ea7e720eaad09 --- services/audioflinger/AudioFlinger.cpp | 40 +++++++++++++++++++++++++++++++++- services/audioflinger/AudioFlinger.h | 6 +++++ services/audioflinger/Effects.cpp | 34 +++++++++++++++++++---------- services/audioflinger/Effects.h | 4 ++++ services/audioflinger/Tracks.cpp | 12 +++++++++- 5 files changed, 83 insertions(+), 13 deletions(-) (limited to 'services/audioflinger') diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index b8a6b37..626b5c2 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -98,6 +98,11 @@ 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); + // ---------------------------------------------------------------------------- static int load_audio_interface(const char *if_name, audio_hw_device_t **dev) @@ -141,7 +146,8 @@ AudioFlinger::AudioFlinger() mMode(AUDIO_MODE_INVALID), mBtNrecIsOff(false), mIsLowRamDevice(true), - mIsDeviceTypeKnown(false) + mIsDeviceTypeKnown(false), + mGlobalEffectEnableTime(0) { getpid_cached = getpid(); char value[PROPERTY_VALUE_MAX]; @@ -2314,6 +2320,38 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId, return NO_ERROR; } +bool AudioFlinger::isGlobalEffectEnabled_l() +{ + if (mGlobalEffectEnableTime != 0 && + ((systemTime() - mGlobalEffectEnableTime) < kMinGlobalEffectEnabletimeNs)) { + return true; + } + + for (size_t i = 0; i < mPlaybackThreads.size(); i++) { + sp ec = + mPlaybackThreads.valueAt(i)->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); + if (ec != 0 && ec->isEnabled()) { + return true; + } + } + return false; +} + +void AudioFlinger::onGlobalEffectEnable() +{ + Mutex::Autolock _l(mLock); + + mGlobalEffectEnableTime = systemTime(); + + for (size_t i = 0; i < mPlaybackThreads.size(); i++) { + sp t = mPlaybackThreads.valueAt(i); + if (t->mType == ThreadBase::OFFLOAD) { + t->invalidateTracks(AUDIO_STREAM_MUSIC); + } + } + +} + struct Entry { #define MAX_NAME 32 // %Y%m%d%H%M%S_%d.wav char mName[MAX_NAME]; diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 5df04f4..0992308 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -466,6 +466,10 @@ private: void removeClient_l(pid_t pid); void removeNotificationClient(pid_t pid); + //TODO: remove when effect offload is implemented + bool isGlobalEffectEnabled_l(); + void onGlobalEffectEnable(); + class AudioHwDevice { public: enum Flags { @@ -641,6 +645,8 @@ public: private: bool mIsLowRamDevice; bool mIsDeviceTypeKnown; + //TODO: remove when effect offload is implemented + nsecs_t mGlobalEffectEnableTime; // when a global effect was last enabled }; #undef INCLUDING_FROM_AUDIOFLINGER_H diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp index d5a21a7..86671a9 100644 --- a/services/audioflinger/Effects.cpp +++ b/services/audioflinger/Effects.cpp @@ -593,17 +593,6 @@ status_t AudioFlinger::EffectModule::setEnabled_l(bool enabled) h->setEnabled(enabled); } } -//EL_FIXME not sure why this is needed? -// sp thread = mThread.promote(); -// if (thread == 0) { -// return NO_ERROR; -// } -// -// if ((thread->type() == ThreadBase::OFFLOAD) && (enabled)) { -// PlaybackThread *p = (PlaybackThread *)thread.get(); -// ALOGV("setEnabled: Offload, invalidate tracks"); -// p->invalidateTracks(AUDIO_STREAM_MUSIC); -// } } return NO_ERROR; } @@ -942,6 +931,17 @@ status_t AudioFlinger::EffectHandle::enable() thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId()); } mEnabled = false; + } else { + //TODO: remove when effect offload is implemented + if (thread != 0) { + 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(); + } + } } return status; } @@ -1728,4 +1728,16 @@ void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const spisEnabled()) { + return true; + } + } + return false; +} + }; // namespace android diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h index 0b7fb83..bac50f2 100644 --- a/services/audioflinger/Effects.h +++ b/services/audioflinger/Effects.h @@ -303,6 +303,10 @@ public: void clearInputBuffer(); + // At least one effect in the chain is enabled + bool isEnabled(); + + void dump(int fd, const Vector& args); protected: diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp index 2042050..6002aa3 100644 --- a/services/audioflinger/Tracks.cpp +++ b/services/audioflinger/Tracks.cpp @@ -543,7 +543,17 @@ status_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t ev sp thread = mThread.promote(); if (thread != 0) { - Mutex::Autolock _l(thread->mLock); + //TODO: remove when effect offload is implemented + if (isOffloaded()) { + Mutex::Autolock _laf(thread->mAudioFlinger->mLock); + Mutex::Autolock _lth(thread->mLock); + sp ec = thread->getEffectChain_l(mSessionId); + if (thread->mAudioFlinger->isGlobalEffectEnabled_l() || (ec != 0 && ec->isEnabled())) { + invalidate(); + return PERMISSION_DENIED; + } + } + Mutex::Autolock _lth(thread->mLock); track_state state = mState; // here the track could be either new, or restarted // in both cases "unstop" the track -- cgit v1.1