summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2012-05-30 14:07:38 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-05-30 14:07:38 -0700
commit3bdb4fbfc6730b6edc0b1ee980141574ed54ed8d (patch)
tree0629fb88ed24815990afca3e04f4821e7b974336 /services
parentcc9833b5db0e96f12daddb90a747fd146627377d (diff)
parent91b14c4c144d0cc957a427cffc02ba10d0615677 (diff)
downloadframeworks_av-3bdb4fbfc6730b6edc0b1ee980141574ed54ed8d.zip
frameworks_av-3bdb4fbfc6730b6edc0b1ee980141574ed54ed8d.tar.gz
frameworks_av-3bdb4fbfc6730b6edc0b1ee980141574ed54ed8d.tar.bz2
Merge "audioflinger: fix effect problem during underrun" into jb-dev
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp35
-rw-r--r--services/audioflinger/AudioFlinger.h4
2 files changed, 37 insertions, 2 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 57d7089..eea3cd2 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -3147,6 +3147,13 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
mixerStatus = MIXER_TRACKS_READY;
}
} else {
+ // clear effect chain input buffer if an active track underruns to avoid sending
+ // previous audio buffer again to effects
+ chain = getEffectChain_l(track->sessionId());
+ if (chain != 0) {
+ chain->clearInputBuffer();
+ }
+
//ALOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", name, cblk->user, cblk->server, this);
if ((track->sharedBuffer() != 0) || track->isTerminated() ||
track->isStopped() || track->isPaused()) {
@@ -3661,6 +3668,12 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
mActiveTrack = t;
mixerStatus = MIXER_TRACKS_READY;
} else {
+ // clear effect chain input buffer if an active track underruns to avoid sending
+ // previous audio buffer again to effects
+ if (!mEffectChains.isEmpty()) {
+ mEffectChains[0]->clearInputBuffer();
+ }
+
//ALOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
if (track->isTerminated() || track->isStopped() || track->isPaused()) {
// We have consumed all the buffers of this track.
@@ -8978,6 +8991,25 @@ sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromType_l(
return 0;
}
+void AudioFlinger::EffectChain::clearInputBuffer()
+{
+ Mutex::Autolock _l(mLock);
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread == 0) {
+ ALOGW("clearInputBuffer(): cannot promote mixer thread");
+ return;
+ }
+ clearInputBuffer_l(thread);
+}
+
+// Must be called with EffectChain::mLock locked
+void AudioFlinger::EffectChain::clearInputBuffer_l(sp<ThreadBase> thread)
+{
+ size_t numSamples = thread->frameCount() * thread->channelCount();
+ memset(mInBuffer, 0, numSamples * sizeof(int16_t));
+
+}
+
// Must be called with EffectChain::mLock locked
void AudioFlinger::EffectChain::process_l()
{
@@ -9002,8 +9034,7 @@ void AudioFlinger::EffectChain::process_l()
// if no track is active and the effect tail has not been rendered,
// the input buffer must be cleared here as the mixer process will not do it
if (tracksOnSession || mTailBufferCount > 0) {
- size_t numSamples = thread->frameCount() * thread->channelCount();
- memset(mInBuffer, 0, numSamples * sizeof(int16_t));
+ clearInputBuffer_l(thread);
if (mTailBufferCount > 0) {
mTailBufferCount--;
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 51cbae7..19390b1 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -1717,6 +1717,8 @@ mutable Mutex mLock; // mutex for process, commands and handl
void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
bool enabled);
+ void clearInputBuffer();
+
status_t dump(int fd, const Vector<String16>& args);
protected:
@@ -1744,6 +1746,8 @@ mutable Mutex mLock; // mutex for process, commands and handl
// types or implementations from the suspend/restore mechanism.
bool isEffectEligibleForSuspend(const effect_descriptor_t& desc);
+ void clearInputBuffer_l(sp<ThreadBase> thread);
+
wp<ThreadBase> mThread; // parent mixer thread
Mutex mLock; // mutex protecting effect list
Vector< sp<EffectModule> > mEffects; // list of effect modules