Merge "Was calculating measured warmup time wrong" into jb-dev
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index eea3cd2..7d6b121 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2841,6 +2841,8 @@
             // at the identical fast mixer slot within the same normal mix cycle,
             // is impossible because the slot isn't marked available until the end of each cycle.
             int j = track->mFastIndex;
+            ALOG_ASSERT(0 < j && j < (int)FastMixerState::kMaxFastTracks);
+            ALOG_ASSERT(!(mFastTrackAvailMask & (1 << j)));
             FastTrack *fastTrack = &state->mFastTracks[j];
 
             // Determine whether the track is currently in underrun condition,
@@ -4295,6 +4297,13 @@
         // NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of
         // 16 bit because data is converted to 16 bit before being stored in buffer by AudioTrack
         mCblk->frameSize = audio_is_linear_pcm(format) ? mChannelCount * sizeof(int16_t) : sizeof(uint8_t);
+        // to avoid leaking a track name, do not allocate one unless there is an mCblk
+        mName = thread->getTrackName_l((audio_channel_mask_t)channelMask);
+        if (mName < 0) {
+            ALOGE("no more track names available");
+            return;
+        }
+        // only allocate a fast track index if we were able to allocate a normal track name
         if (flags & IAudioFlinger::TRACK_FAST) {
             mCblk->flags |= CBLK_FAST;  // atomic op not needed yet
             ALOG_ASSERT(thread->mFastTrackAvailMask != 0);
@@ -4309,14 +4318,6 @@
             mObservedUnderruns = thread->getFastTrackUnderruns(i);
             thread->mFastTrackAvailMask &= ~(1 << i);
         }
-        // to avoid leaking a track name, do not allocate one unless there is an mCblk
-        mName = thread->getTrackName_l((audio_channel_mask_t)channelMask);
-        if (mName < 0) {
-            ALOGE("no more track names available");
-            // FIXME bug - if sufficient fast track indices, but insufficient normal mixer names,
-            // then we leak a fast track index.  Should swap these two sections, or better yet
-            // only allocate a normal mixer name for normal tracks.
-        }
     }
     ALOGV("Track constructor name %d, calling pid %d", mName, IPCThreadState::self()->getCallingPid());
 }
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 19390b1..160e4cd 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -778,6 +778,7 @@
             int                 mName;      // track name on the normal mixer,
                                             // allocated statically at track creation time,
                                             // and is even allocated (though unused) for fast tracks
+                                            // FIXME don't allocate track name for fast tracks
             int16_t             *mMainBuffer;
             int32_t             *mAuxBuffer;
             int                 mAuxEffectId;
@@ -789,7 +790,7 @@
 
             // The following fields are only for fast tracks, and should be in a subclass
             int                 mFastIndex; // index within FastMixerState::mFastTracks[];
-                                            // either mFastIndex == -1
+                                            // either mFastIndex == -1 if not isFastTrack()
                                             // or 0 < mFastIndex < FastMixerState::kMaxFast because
                                             // index 0 is reserved for normal mixer's submix;
                                             // index is allocated statically at track creation time
diff --git a/services/audioflinger/MonoPipe.cpp b/services/audioflinger/MonoPipe.cpp
index fd16e92..6efb8b1 100644
--- a/services/audioflinger/MonoPipe.cpp
+++ b/services/audioflinger/MonoPipe.cpp
@@ -25,9 +25,10 @@
 
 namespace android {
 
-MonoPipe::MonoPipe(size_t maxFrames, NBAIO_Format format, bool writeCanBlock) :
+MonoPipe::MonoPipe(size_t reqFrames, NBAIO_Format format, bool writeCanBlock) :
         NBAIO_Sink(format),
-        mMaxFrames(roundup(maxFrames)),
+        mReqFrames(reqFrames),
+        mMaxFrames(roundup(reqFrames)),
         mBuffer(malloc(mMaxFrames * Format_frameSize(format))),
         mFront(0),
         mRear(0),
@@ -45,6 +46,7 @@
     if (CC_UNLIKELY(!mNegotiated)) {
         return NEGOTIATE;
     }
+    // uses mMaxFrames not mReqFrames, so allows "over-filling" the pipe beyond requested limit
     ssize_t ret = mMaxFrames - (mRear - android_atomic_acquire_load(&mFront));
     ALOG_ASSERT((0 <= ret) && (ret <= mMaxFrames));
     return ret;
@@ -57,6 +59,7 @@
     }
     size_t totalFramesWritten = 0;
     while (count > 0) {
+        // can't return a negative value, as we already checked for !mNegotiated
         size_t avail = availableToWrite();
         size_t written = avail;
         if (CC_LIKELY(written > count)) {
@@ -84,50 +87,29 @@
         count -= written;
         buffer = (char *) buffer + (written << mBitShift);
         // Simulate blocking I/O by sleeping at different rates, depending on a throttle.
-        // The throttle tries to keep the pipe about 5/8 full on average, with a slight jitter.
-        uint64_t ns;
-        enum {
-            THROTTLE_VERY_FAST, // pipe is (nearly) empty, fill quickly
-            THROTTLE_FAST,      // pipe is normal, fill at slightly faster rate
-            THROTTLE_NOMINAL,   // pipe is normal, fill at nominal rate
-            THROTTLE_SLOW,      // pipe is normal, fill at slightly slower rate
-            THROTTLE_VERY_SLOW, // pipe is (nearly) full, fill slowly
-        } throttle;
-        avail -= written;
-        // FIXME cache these values to avoid re-computation
-        if (avail >= (mMaxFrames * 3) / 4) {
-            throttle = THROTTLE_VERY_FAST;
-        } else if (avail >= mMaxFrames / 2) {
-            throttle = THROTTLE_FAST;
-        } else if (avail >= (mMaxFrames * 3) / 8) {
-            throttle = THROTTLE_NOMINAL;
-        } else if (avail >= mMaxFrames / 4) {
-            throttle = THROTTLE_SLOW;
-        } else {
-            throttle = THROTTLE_VERY_SLOW;
-        }
+        // The throttle tries to keep the pipe about 11/16 full on average, with a slight jitter.
+        uint32_t ns;
         if (written > 0) {
-            // FIXME cache these values also
-            switch (throttle) {
-            case THROTTLE_VERY_FAST:
-            default:
+            size_t filled = (mMaxFrames - avail) + written;
+            // FIXME cache these values to avoid re-computation
+            if (filled <= mReqFrames / 4) {
+                // pipe is (nearly) empty, fill quickly
                 ns = written * ( 500000000 / Format_sampleRate(mFormat));
-                break;
-            case THROTTLE_FAST:
+            } else if (filled <= mReqFrames / 2) {
+                // pipe is normal, fill at slightly faster rate
                 ns = written * ( 750000000 / Format_sampleRate(mFormat));
-                break;
-            case THROTTLE_NOMINAL:
+            } else if (filled <= (mReqFrames * 5) / 8) {
+                // pipe is normal, fill at nominal rate
                 ns = written * (1000000000 / Format_sampleRate(mFormat));
-                break;
-            case THROTTLE_SLOW:
+            } else if (filled <= (mReqFrames * 3) / 4) {
+                // pipe is normal, fill at slightly slower rate
                 ns = written * (1100000000 / Format_sampleRate(mFormat));
-                break;
-            case THROTTLE_VERY_SLOW:
+            } else {
+                // pipe is (nearly) full, fill slowly
                 ns = written * (1250000000 / Format_sampleRate(mFormat));
-                break;
             }
         } else {
-            ns = mMaxFrames * (250000000 / Format_sampleRate(mFormat));
+            ns = mReqFrames * (250000000 / Format_sampleRate(mFormat));
         }
         if (ns > 999999999) {
             ns = 999999999;
diff --git a/services/audioflinger/MonoPipe.h b/services/audioflinger/MonoPipe.h
index 545d6ac..aaaa51f 100644
--- a/services/audioflinger/MonoPipe.h
+++ b/services/audioflinger/MonoPipe.h
@@ -33,11 +33,11 @@
     friend class MonoPipeReader;
 
 public:
-    // maxFrames will be rounded up to a power of 2, and all slots are available. Must be >= 2.
+    // reqFrames will be rounded up to a power of 2, and all slots are available. Must be >= 2.
     // Note: whatever shares this object with another thread needs to do so in an SMP-safe way (like
     // creating it the object before creating the other thread, or storing the object with a
     // release_store). Otherwise the other thread could see a partially-constructed object.
-    MonoPipe(size_t maxFrames, NBAIO_Format format, bool writeCanBlock = false);
+    MonoPipe(size_t reqFrames, NBAIO_Format format, bool writeCanBlock = false);
     virtual ~MonoPipe();
 
     // NBAIO_Port interface
@@ -58,9 +58,10 @@
 
             // average number of frames present in the pipe under normal conditions.
             // See throttling mechanism in MonoPipe::write()
-            size_t  getAvgFrames() const { return (mMaxFrames * 11) / 16; }
+            size_t  getAvgFrames() const { return (mReqFrames * 11) / 16; }
 
 private:
+    const size_t    mReqFrames;     // as requested in constructor, unrounded
     const size_t    mMaxFrames;     // always a power of 2
     void * const    mBuffer;
     // mFront and mRear will never be separated by more than mMaxFrames.