am 8c07f759: am 3bdb4fbf: Merge "audioflinger: fix effect problem during underrun" into jb-dev

* commit '8c07f7599a757fe51dc54253c480067cf01f13d3':
  audioflinger: fix effect problem during underrun
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 0c1b4c1..d9c5d55 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -3147,6 +3147,13 @@
                 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 @@
             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 @@
     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 @@
             // 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 @@
         void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
                                               bool enabled);
 
+        void clearInputBuffer();
+
         status_t dump(int fd, const Vector<String16>& args);
 
     protected:
@@ -1744,6 +1746,8 @@
         // 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