Add format parameter to getTrackName() and track_t

Change-Id: Ia152a839014e235fbfb656104c15d7c1b456d02e
Signed-off-by: Andy Hung <hunga@google.com>
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 805eaa4..342364e 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -153,8 +153,13 @@
     mState.mLog = log;
 }
 
-int AudioMixer::getTrackName(audio_channel_mask_t channelMask, int sessionId)
+int AudioMixer::getTrackName(audio_channel_mask_t channelMask,
+        audio_format_t format, int sessionId)
 {
+    if (!isValidPcmTrackFormat(format)) {
+        ALOGE("AudioMixer::getTrackName invalid format (%#x)", format);
+        return -1;
+    }
     uint32_t names = (~mTrackNames) & mConfiguredNames;
     if (names != 0) {
         int n = __builtin_ctz(names);
@@ -193,7 +198,7 @@
         t->auxBuffer = NULL;
         t->downmixerBufferProvider = NULL;
         t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
-
+        t->mFormat = format;
         status_t status = initTrackDownmix(&mState.tracks[n], n, channelMask);
         if (status != OK) {
             ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index e5e120c..c945c2b 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -100,7 +100,10 @@
     // For all APIs with "name": TRACK0 <= name < TRACK0 + MAX_NUM_TRACKS
 
     // Allocate a track name.  Returns new track name if successful, -1 on failure.
-    int         getTrackName(audio_channel_mask_t channelMask, int sessionId);
+    // The failure could be because of an invalid channelMask or format, or that
+    // the track capacity of the mixer is exceeded.
+    int         getTrackName(audio_channel_mask_t channelMask,
+                             audio_format_t format, int sessionId);
 
     // Free an allocated track by name
     void        deleteTrackName(int name);
@@ -118,6 +121,10 @@
 
     size_t      getUnreleasedFrames(int name) const;
 
+    static inline bool isValidPcmTrackFormat(audio_format_t format) {
+        return format == AUDIO_FORMAT_PCM_16_BIT;
+    }
+
 private:
 
     enum {
@@ -194,9 +201,8 @@
 
         int32_t     sessionId;
 
-        audio_format_t mMixerFormat; // at this time: AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
-
-        int32_t     padding[1];
+        audio_format_t mMixerFormat;     // output mix format: AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
+        audio_format_t mFormat;          // input track format
 
         // 16-byte boundary
 
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index b909904..9e9f20d 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -224,7 +224,8 @@
             AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
             ALOG_ASSERT(bufferProvider != NULL && fastTrackNames[i] == -1);
             if (mixer != NULL) {
-                name = mixer->getTrackName(fastTrack->mChannelMask, AUDIO_SESSION_OUTPUT_MIX);
+                name = mixer->getTrackName(fastTrack->mChannelMask,
+                        fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
                 ALOG_ASSERT(name >= 0);
                 fastTrackNames[i] = name;
                 mixer->setBufferProvider(name, bufferProvider);
diff --git a/services/audioflinger/FastMixerState.cpp b/services/audioflinger/FastMixerState.cpp
index 8e6d0d4..3aa8dad 100644
--- a/services/audioflinger/FastMixerState.cpp
+++ b/services/audioflinger/FastMixerState.cpp
@@ -20,7 +20,7 @@
 
 FastTrack::FastTrack() :
     mBufferProvider(NULL), mVolumeProvider(NULL),
-    mChannelMask(AUDIO_CHANNEL_OUT_STEREO), mGeneration(0)
+    mChannelMask(AUDIO_CHANNEL_OUT_STEREO), mFormat(AUDIO_FORMAT_INVALID), mGeneration(0)
 {
 }
 
diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h
index be1a376..cb54ff1 100644
--- a/services/audioflinger/FastMixerState.h
+++ b/services/audioflinger/FastMixerState.h
@@ -45,6 +45,7 @@
     ExtendedAudioBufferProvider* mBufferProvider; // must be NULL if inactive, or non-NULL if active
     VolumeProvider*         mVolumeProvider; // optional; if NULL then full-scale
     audio_channel_mask_t    mChannelMask;    // AUDIO_CHANNEL_OUT_MONO or AUDIO_CHANNEL_OUT_STEREO
+    audio_format_t          mFormat;         // track format
     int                     mGeneration;     // increment when any field is assigned
 };
 
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 8d9ccd0..0a18433 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2682,6 +2682,8 @@
         // wrap the source side of the MonoPipe to make it an AudioBufferProvider
         fastTrack->mBufferProvider = new SourceAudioBufferProvider(new MonoPipeReader(monoPipe));
         fastTrack->mVolumeProvider = NULL;
+        fastTrack->mChannelMask = mChannelMask; // mPipeSink channel mask for audio to FastMixer
+        fastTrack->mFormat = mFormat; // mPipeSink format for audio to FastMixer
         fastTrack->mGeneration++;
         state->mFastTracksGen++;
         state->mTrackMask = 1;
@@ -3134,6 +3136,7 @@
                     fastTrack->mBufferProvider = eabp;
                     fastTrack->mVolumeProvider = vp;
                     fastTrack->mChannelMask = track->mChannelMask;
+                    fastTrack->mFormat = track->mFormat;
                     fastTrack->mGeneration++;
                     state->mTrackMask |= 1 << j;
                     didModify = true;
@@ -3522,9 +3525,10 @@
 }
 
 // getTrackName_l() must be called with ThreadBase::mLock held
-int AudioFlinger::MixerThread::getTrackName_l(audio_channel_mask_t channelMask, int sessionId)
+int AudioFlinger::MixerThread::getTrackName_l(audio_channel_mask_t channelMask,
+        audio_format_t format, int sessionId)
 {
-    return mAudioMixer->getTrackName(channelMask, sessionId);
+    return mAudioMixer->getTrackName(channelMask, format, sessionId);
 }
 
 // deleteTrackName_l() must be called with ThreadBase::mLock held
@@ -3637,7 +3641,8 @@
             delete mAudioMixer;
             mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate);
             for (size_t i = 0; i < mTracks.size() ; i++) {
-                int name = getTrackName_l(mTracks[i]->mChannelMask, mTracks[i]->mSessionId);
+                int name = getTrackName_l(mTracks[i]->mChannelMask,
+                        mTracks[i]->mFormat, mTracks[i]->mSessionId);
                 if (name < 0) {
                     break;
                 }
@@ -3924,7 +3929,7 @@
 
 // getTrackName_l() must be called with ThreadBase::mLock held
 int AudioFlinger::DirectOutputThread::getTrackName_l(audio_channel_mask_t channelMask __unused,
-        int sessionId __unused)
+        audio_format_t format __unused, int sessionId __unused)
 {
     return 0;
 }
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index cc2b246..1b01512 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -619,7 +619,8 @@
 
     // Allocate a track name for a given channel mask.
     //   Returns name >= 0 if successful, -1 on failure.
-    virtual int             getTrackName_l(audio_channel_mask_t channelMask, int sessionId) = 0;
+    virtual int             getTrackName_l(audio_channel_mask_t channelMask,
+                                           audio_format_t format, int sessionId) = 0;
     virtual void            deleteTrackName_l(int name) = 0;
 
     // Time to sleep between cycles when:
@@ -772,7 +773,8 @@
 
 protected:
     virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
-    virtual     int         getTrackName_l(audio_channel_mask_t channelMask, int sessionId);
+    virtual     int         getTrackName_l(audio_channel_mask_t channelMask,
+                                           audio_format_t format, int sessionId);
     virtual     void        deleteTrackName_l(int name);
     virtual     uint32_t    idleSleepTimeUs() const;
     virtual     uint32_t    suspendSleepTimeUs() const;
@@ -825,7 +827,8 @@
                                                    status_t& status);
 
 protected:
-    virtual     int         getTrackName_l(audio_channel_mask_t channelMask, int sessionId);
+    virtual     int         getTrackName_l(audio_channel_mask_t channelMask,
+                                           audio_format_t format, int sessionId);
     virtual     void        deleteTrackName_l(int name);
     virtual     uint32_t    activeSleepTimeUs() const;
     virtual     uint32_t    idleSleepTimeUs() const;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 1d46f87..222ec53 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -383,7 +383,7 @@
     }
     mServerProxy = mAudioTrackServerProxy;
 
-    mName = thread->getTrackName_l(channelMask, sessionId);
+    mName = thread->getTrackName_l(channelMask, format, sessionId);
     if (mName < 0) {
         ALOGE("no more track names available");
         return;