Move frame count calculations for fast tracks

For fast tracks: move the default and minimum frame count calculations
from client to server.  If accepted, the default and minimum frame count
is the fast mixer (HAL) frame count.  If denied, the default and minimum
frame count is the same as it currently is for normal tracks.

For normal tracks: there is no change yet, preserve legacy behavior for
now but add a FIXME to change this later.

Bug fix: the test for buffer alignment matches channelCount was wrong.

Bug fix: check for 8-bit data in shared memory, which isn't supported.

Optimizations:
 - in set(), only call AudioSystem::getOutputSamplingRate() when needed
 - in createTrack_l(), only call AudioSystem::getSamplingRate() and
   AudioSystem::getFrameCount() when needed

Change-Id: I79d2fe507db1a8f7bb094c71da8a129951dbb82f
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 6eeda9a..1c277ce 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1623,8 +1623,8 @@
     bool isTimed = (flags & IAudioFlinger::TRACK_TIMED) != 0;
 
     // client expresses a preference for FAST, but we get the final say
-    if ((flags & IAudioFlinger::TRACK_FAST) &&
-          !(
+    if (flags & IAudioFlinger::TRACK_FAST) {
+      if (
             // not timed
             (!isTimed) &&
             // either of these use cases:
@@ -1633,11 +1633,11 @@
               (
                 (sharedBuffer != 0)
               ) ||
-              // use case 2: callback handler and frame count at least as large as HAL
+              // use case 2: callback handler and frame count is default or at least as large as HAL
               (
                 (tid != -1) &&
-                // FIXME supported frame counts should not be hard-coded
-                frameCount >= (int) mFrameCount // FIXME int cast is due to wrong parameter type
+                ((frameCount == 0) ||
+                (frameCount >= (int) mFrameCount)) // FIXME int cast is due to wrong parameter type
               )
             ) &&
             // PCM data
@@ -1655,17 +1655,35 @@
             (mFastTrackAvailMask != 0)
             // FIXME test that MixerThread for this fast track has a capable output HAL
             // FIXME add a permission test also?
-          ) ) {
-        ALOGW("AUDIO_POLICY_FLAG_FAST denied: isTimed=%d sharedBuffer=%p frameCount=%d "
+        ) {
+        ALOGI("AUDIO_OUTPUT_FLAG_FAST accepted: frameCount=%d mFrameCount=%d",
+                frameCount, mFrameCount);
+        // if frameCount not specified, then it defaults to fast mixer (HAL) frame count
+        if (frameCount == 0) {
+            frameCount = mFrameCount;
+        }
+      } else {
+        ALOGW("AUDIO_OUTPUT_FLAG_FAST denied: isTimed=%d sharedBuffer=%p frameCount=%d "
                 "mFrameCount=%d format=%d isLinear=%d channelMask=%d sampleRate=%d mSampleRate=%d "
                 "hasFastMixer=%d tid=%d fastTrackAvailMask=%#x",
                 isTimed, sharedBuffer.get(), frameCount, mFrameCount, format,
                 audio_is_linear_pcm(format),
                 channelMask, sampleRate, mSampleRate, hasFastMixer(), tid, mFastTrackAvailMask);
         flags &= ~IAudioFlinger::TRACK_FAST;
-        if (0 < frameCount && frameCount < (int) mNormalFrameCount) {
-            frameCount = mNormalFrameCount;
+        // For compatibility with AudioTrack calculation, buffer depth is forced
+        // to be at least 2 x the normal mixer frame count and cover audio hardware latency.
+        // This is probably too conservative, but legacy application code may depend on it.
+        // If you change this calculation, also review the start threshold which is related.
+        uint32_t latencyMs = mOutput->stream->get_latency(mOutput->stream);
+        uint32_t minBufCount = latencyMs / ((1000 * mNormalFrameCount) / mSampleRate);
+        if (minBufCount < 2) {
+            minBufCount = 2;
         }
+        int minFrameCount = mNormalFrameCount * minBufCount;
+        if (frameCount < minFrameCount) {
+            frameCount = minFrameCount;
+        }
+      }
     }
 
     if (mType == DIRECT) {