OSDN Git Service

Mark similar and different sections in threadLoop
authorGlenn Kasten <gkasten@google.com>
Wed, 29 Feb 2012 15:57:06 +0000 (07:57 -0800)
committerGlenn Kasten <gkasten@google.com>
Wed, 29 Feb 2012 17:38:15 +0000 (09:38 -0800)
Most of these comments will be removed after the threadLoop merge.

Note: the trivial change in assignments to mixBufferSize, and the
comments about "tracks to remove" is to make them all identical.

Change-Id: I3b1a33a7f2cd12ad557a1986bb71f6171161974a

services/audioflinger/AudioFlinger.cpp

index 462c2fa..36df2c0 100644 (file)
@@ -1993,9 +1993,12 @@ void AudioFlinger::PlaybackThread::checkSilentMode_l()
 
 bool AudioFlinger::MixerThread::threadLoop()
 {
+    // DirectOutputThread has single trackToRemove instead of Vector
     Vector< sp<Track> > tracksToRemove;
+    // DirectOutputThread has activeTrack here
     nsecs_t standbyTime = systemTime();
     size_t mixBufferSize = mFrameCount * mFrameSize;
+
     // FIXME: Relaxed timing because of a certain device that can't meet latency
     // Should be reduced to 2x after the vendor fixes the driver issue
     // increase threshold again due to low power audio mode. The way this warning threshold is
@@ -2003,18 +2006,25 @@ bool AudioFlinger::MixerThread::threadLoop()
     nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
     nsecs_t lastWarning = 0;
     bool longStandbyExit = false;
+
     uint32_t activeSleepTime = activeSleepTimeUs();
     uint32_t idleSleepTime = idleSleepTimeUs();
     uint32_t sleepTime = idleSleepTime;
+
     uint32_t sleepTimeShift = 0;
     Vector< sp<EffectChain> > effectChains;
     CpuStats cpuStats;
 
+    // DirectOutputThread has shorter standbyDelay
+
     acquireWakeLock();
 
     while (!exitPending())
     {
         cpuStats.sample();
+
+        // DirectOutputThread has rampVolume, leftVol, rightVol
+
         processConfigEvents();
 
         mixer_state mixerStatus = MIXER_IDLE;
@@ -2024,13 +2034,16 @@ bool AudioFlinger::MixerThread::threadLoop()
 
             if (checkForNewParameters_l()) {
                 mixBufferSize = mFrameCount * mFrameSize;
+
                 // FIXME: Relaxed timing because of a certain device that can't meet latency
                 // Should be reduced to 2x after the vendor fixes the driver issue
                 // increase threshold again due to low power audio mode. The way this warning
                 // threshold is calculated and its usefulness should be reconsidered anyway.
                 maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
+
                 activeSleepTime = activeSleepTimeUs();
                 idleSleepTime = idleSleepTimeUs();
+                // DirectOutputThread updates standbyDelay also
             }
 
             const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
@@ -2136,6 +2149,9 @@ bool AudioFlinger::MixerThread::threadLoop()
 
         // only process effects if we're going to write
         if (sleepTime == 0) {
+
+            // DirectOutputThread adds applyVolume here
+
             for (size_t i = 0; i < effectChains.size(); i ++) {
                 effectChains[i]->process_l();
             }
@@ -2146,14 +2162,16 @@ bool AudioFlinger::MixerThread::threadLoop()
 
         // sleepTime == 0 means we must write to audio hardware
         if (sleepTime == 0) {
+            // FIXME Only in MixerThread, and rewrite to reduce number of system calls
             mLastWriteTime = systemTime();
             mInWrite = true;
             mBytesWritten += mixBufferSize;
-
             int bytesWritten = (int)mOutput->stream->write(mOutput->stream, mMixBuffer, mixBufferSize);
             if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
             mNumWrites++;
             mInWrite = false;
+
+            // Only in MixerThread: start of write blocked detection
             nsecs_t now = systemTime();
             nsecs_t delta = now - mLastWriteTime;
             if (!mStandby && delta > maxPeriod) {
@@ -2167,12 +2185,14 @@ bool AudioFlinger::MixerThread::threadLoop()
                     longStandbyExit = true;
                 }
             }
+            // end of write blocked detection
+
             mStandby = false;
         } else {
             usleep(sleepTime);
         }
 
-        // finally let go of all our tracks, without the lock held
+        // finally let go of removed track(s), without the lock held
         // since we can't guarantee the destructors won't acquire that
         // same lock.
         tracksToRemove.clear();
@@ -2182,6 +2202,7 @@ bool AudioFlinger::MixerThread::threadLoop()
         effectChains.clear();
     }
 
+    // put output stream into standby mode
     if (!mStandby) {
         mOutput->stream->common.standby(&mOutput->stream->common);
     }
@@ -2706,13 +2727,21 @@ void AudioFlinger::DirectOutputThread::applyVolume(uint16_t leftVol, uint16_t ri
 
 bool AudioFlinger::DirectOutputThread::threadLoop()
 {
+    // MixerThread has Vector instead of single trackToRemove
     sp<Track> trackToRemove;
+    // MixerThread does not have activeTrack here
     sp<Track> activeTrack;
     nsecs_t standbyTime = systemTime();
-    size_t mixBufferSize = mFrameCount*mFrameSize;
+    size_t mixBufferSize = mFrameCount * mFrameSize;
+
+    // MixerThread has relaxed timing: maxPeriod, lastWarning, longStandbyExit
+
     uint32_t activeSleepTime = activeSleepTimeUs();
     uint32_t idleSleepTime = idleSleepTimeUs();
     uint32_t sleepTime = idleSleepTime;
+
+    // MixerThread has sleepTimeShift and cpuStats
+
     // use shorter standby delay as on normal output to release
     // hardware resources as soon as possible
     nsecs_t standbyDelay = microseconds(activeSleepTime*2);
@@ -2721,9 +2750,12 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
 
     while (!exitPending())
     {
+        // MixerThread has cpuStats.sample()
+
         bool rampVolume;
         uint16_t leftVol;
         uint16_t rightVol;
+
         Vector< sp<EffectChain> > effectChains;
 
         processConfigEvents();
@@ -2734,7 +2766,11 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
             Mutex::Autolock _l(mLock);
 
             if (checkForNewParameters_l()) {
-                mixBufferSize = mFrameCount*mFrameSize;
+                mixBufferSize = mFrameCount * mFrameSize;
+
+                // different calculations here
+                standbyDelay = microseconds(activeSleepTime*2);
+
                 activeSleepTime = activeSleepTimeUs();
                 idleSleepTime = idleSleepTimeUs();
                 standbyDelay = microseconds(activeSleepTime*2);
@@ -2743,7 +2779,6 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
             // put audio hardware into standby after short delay
             if (CC_UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) ||
                         mSuspended)) {
-                // wait until we have something to do...
                 if (!mStandby) {
                     ALOGV("Audio hardware entering standby, mixer %p, mSuspended %d", this, mSuspended);
                     mOutput->stream->common.standby(&mOutput->stream->common);
@@ -2758,19 +2793,27 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
                     if (exitPending()) break;
 
                     releaseWakeLock_l();
+                    // wait until we have something to do...
                     ALOGV("Thread %p type %d TID %d going to sleep", this, mType, gettid());
                     mWaitWorkCV.wait(mLock);
                     ALOGV("Thread %p type %d TID %d waking up", this, mType, gettid());
                     acquireWakeLock_l();
 
+                    // MixerThread has "mPrevMixerStatus = MIXER_IDLE"
                     checkSilentMode_l();
 
+                    // MixerThread has different standbyDelay
                     standbyTime = systemTime() + standbyDelay;
                     sleepTime = idleSleepTime;
+                    // MixerThread has "sleepTimeShift = 0"
                     continue;
                 }
             }
 
+            // MixerThread has "mixerStatus = prepareTracks_l(...)"
+
+            // equivalent to MixerThread's lockEffectChains_l, but without the lock
+            // FIXME - is it OK to omit the lock here?
             effectChains = mEffectChains;
 
             // find out which tracks need to be processed
@@ -2939,9 +2982,12 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
 
         // only process effects if we're going to write
         if (sleepTime == 0) {
+
+            // MixerThread does not have applyVolume
             if (mixerStatus == MIXER_TRACKS_READY) {
                 applyVolume(leftVol, rightVol, rampVolume);
             }
+
             for (size_t i = 0; i < effectChains.size(); i ++) {
                 effectChains[i]->process_l();
             }
@@ -2959,12 +3005,15 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
             if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
             mNumWrites++;
             mInWrite = false;
+
+            // MixerThread has write blocked detection here
+
             mStandby = false;
         } else {
             usleep(sleepTime);
         }
 
-        // finally let go of removed track, without the lock held
+        // finally let go of removed track(s), without the lock held
         // since we can't guarantee the destructors won't acquire that
         // same lock.
         trackToRemove.clear();
@@ -2975,6 +3024,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
         effectChains.clear();
     }
 
+    // put output stream into standby mode
     if (!mStandby) {
         mOutput->stream->common.standby(&mOutput->stream->common);
     }
@@ -3099,9 +3149,12 @@ bool AudioFlinger::DuplicatingThread::threadLoop()
 {
     Vector< sp<Track> > tracksToRemove;
     nsecs_t standbyTime = systemTime();
-    size_t mixBufferSize = mFrameCount*mFrameSize;
+    size_t mixBufferSize = mFrameCount * mFrameSize;
+
+    // Only in DuplicatingThread
     SortedVector< sp<OutputTrack> > outputTracks;
     uint32_t writeFrames = 0;
+
     uint32_t activeSleepTime = activeSleepTimeUs();
     uint32_t idleSleepTime = idleSleepTimeUs();
     uint32_t sleepTime = idleSleepTime;
@@ -3111,6 +3164,8 @@ bool AudioFlinger::DuplicatingThread::threadLoop()
 
     while (!exitPending())
     {
+        // MixerThread has cpuStats.sample
+
         processConfigEvents();
 
         mixer_state mixerStatus = MIXER_IDLE;
@@ -3119,14 +3174,18 @@ bool AudioFlinger::DuplicatingThread::threadLoop()
             Mutex::Autolock _l(mLock);
 
             if (checkForNewParameters_l()) {
-                mixBufferSize = mFrameCount*mFrameSize;
+                mixBufferSize = mFrameCount * mFrameSize;
+
+                // Only in DuplicatingThread
                 updateWaitTime();
+
                 activeSleepTime = activeSleepTimeUs();
                 idleSleepTime = idleSleepTimeUs();
             }
 
             const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
 
+            // Only in DuplicatingThread
             for (size_t i = 0; i < mOutputTracks.size(); i++) {
                 outputTracks.add(mOutputTracks[i]);
             }
@@ -3135,6 +3194,7 @@ bool AudioFlinger::DuplicatingThread::threadLoop()
             if (CC_UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
                          mSuspended)) {
                 if (!mStandby) {
+                    // DuplicatingThread implements standby by stopping all tracks
                     for (size_t i = 0; i < outputTracks.size(); i++) {
                         outputTracks[i]->stop();
                     }
@@ -3156,10 +3216,12 @@ bool AudioFlinger::DuplicatingThread::threadLoop()
                     ALOGV("Thread %p type %d TID %d waking up", this, mType, gettid());
                     acquireWakeLock_l();
 
+                    // MixerThread has "mPrevMixerStatus = MIXER_IDLE"
                     checkSilentMode_l();
 
                     standbyTime = systemTime() + mStandbyTimeInNsecs;
                     sleepTime = idleSleepTime;
+                    // MixerThread has sleepTimeShift
                     continue;
                 }
             }
@@ -3172,6 +3234,7 @@ bool AudioFlinger::DuplicatingThread::threadLoop()
             lockEffectChains_l(effectChains);
         }
 
+        // Duplicating Thread is completely different here
         if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
             // mix buffers...
             if (outputsReady(outputTracks)) {
@@ -3223,11 +3286,14 @@ bool AudioFlinger::DuplicatingThread::threadLoop()
             }
             mStandby = false;
             mBytesWritten += mixBufferSize;
+
+            // MixerThread has write blocked detection here
+
         } else {
             usleep(sleepTime);
         }
 
-        // finally let go of all our tracks, without the lock held
+        // finally let go of removed track(s), without the lock held
         // since we can't guarantee the destructors won't acquire that
         // same lock.
         tracksToRemove.clear();
@@ -3238,6 +3304,9 @@ bool AudioFlinger::DuplicatingThread::threadLoop()
         effectChains.clear();
     }
 
+    // MixerThread and DirectOutpuThread have standby here,
+    // but for DuplicatingThread this is handled by the outputTracks
+
     releaseWakeLock();
 
     ALOGV("Thread %p type %d exiting", this, mType);