diff options
-rw-r--r-- | services/audioflinger/AudioMixer.cpp | 9 | ||||
-rw-r--r-- | services/audioflinger/AudioMixer.h | 14 | ||||
-rw-r--r-- | services/audioflinger/FastMixer.cpp | 3 | ||||
-rw-r--r-- | services/audioflinger/FastMixerState.cpp | 2 | ||||
-rw-r--r-- | services/audioflinger/FastMixerState.h | 1 | ||||
-rw-r--r-- | services/audioflinger/Threads.cpp | 13 | ||||
-rw-r--r-- | services/audioflinger/Threads.h | 9 | ||||
-rw-r--r-- | services/audioflinger/Tracks.cpp | 2 |
8 files changed, 37 insertions, 16 deletions
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 @@ void AudioMixer::setLog(NBLog::Writer *log) 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 @@ int AudioMixer::getTrackName(audio_channel_mask_t channelMask, int sessionId) 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 09e63a6..4a39f88 100644 --- a/services/audioflinger/AudioMixer.h +++ b/services/audioflinger/AudioMixer.h @@ -104,7 +104,10 @@ public: // 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); @@ -122,6 +125,10 @@ public: size_t getUnreleasedFrames(int name) const; + static inline bool isValidPcmTrackFormat(audio_format_t format) { + return format == AUDIO_FORMAT_PCM_16_BIT; + } + private: enum { @@ -198,9 +205,8 @@ private: 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 130a7e7..7e15bef 100644 --- a/services/audioflinger/FastMixer.cpp +++ b/services/audioflinger/FastMixer.cpp @@ -223,7 +223,8 @@ void FastMixer::onStateChange() 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 @@ namespace android { 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 e388fb3..661c9ca 100644 --- a/services/audioflinger/FastMixerState.h +++ b/services/audioflinger/FastMixerState.h @@ -45,6 +45,7 @@ struct FastTrack { 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 7ef5d78..0d81fa3 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -2682,6 +2682,8 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud // 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 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac fastTrack->mBufferProvider = eabp; fastTrack->mVolumeProvider = vp; fastTrack->mChannelMask = track->mChannelMask; + fastTrack->mFormat = track->mFormat; fastTrack->mGeneration++; state->mTrackMask |= 1 << j; didModify = true; @@ -3525,9 +3528,10 @@ track_is_ready: ; } // 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 @@ -3640,7 +3644,8 @@ bool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePa 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; } @@ -3931,7 +3936,7 @@ void AudioFlinger::DirectOutputThread::threadLoop_sleepTime() // 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 4683a13..44008e5 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -621,7 +621,8 @@ protected: // 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: @@ -774,7 +775,8 @@ public: 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; @@ -827,7 +829,8 @@ public: 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 1c55ac7..7ddc71c 100644 --- a/services/audioflinger/Tracks.cpp +++ b/services/audioflinger/Tracks.cpp @@ -397,7 +397,7 @@ AudioFlinger::PlaybackThread::Track::Track( } 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; |