Loading services/audioflinger/Threads.cpp +35 −19 Original line number Diff line number Diff line Loading @@ -1145,7 +1145,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge AudioFlinger::PlaybackThread::~PlaybackThread() { mAudioFlinger->unregisterWriter(mNBLogWriter); delete[] mSinkBuffer; free(mSinkBuffer); free(mMixerBuffer); free(mEffectBuffer); } Loading Loading @@ -1782,11 +1782,13 @@ void AudioFlinger::PlaybackThread::readOutputParameters_l() ALOGI("HAL output buffer size %u frames, normal sink buffer size %u frames", mFrameCount, mNormalFrameCount); delete[] mSinkBuffer; size_t normalBufferSize = mNormalFrameCount * mFrameSize; // For historical reasons mSinkBuffer is int16_t[], but mFrameSize can be odd (such as 1) mSinkBuffer = new int16_t[(normalBufferSize + 1) >> 1]; memset(mSinkBuffer, 0, normalBufferSize); // mSinkBuffer is the sink buffer. Size is always multiple-of-16 frames. // Originally this was int16_t[] array, need to remove legacy implications. free(mSinkBuffer); mSinkBuffer = NULL; const size_t sinkBufferSize = mNormalFrameCount * mChannelCount * audio_bytes_per_sample(mFormat); (void)posix_memalign(&mSinkBuffer, 32, sinkBufferSize); // We resize the mMixerBuffer according to the requirements of the sink buffer which // drives the output. Loading Loading @@ -1984,12 +1986,12 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write() mLastWriteTime = systemTime(); mInWrite = true; ssize_t bytesWritten; const size_t offset = mCurrentWriteLength - mBytesRemaining; // If an NBAIO sink is present, use it to write the normal mixer's submix if (mNormalSink != 0) { #define mBitShift 2 // FIXME size_t count = mBytesRemaining >> mBitShift; size_t offset = (mCurrentWriteLength - mBytesRemaining) >> 1; const size_t count = mBytesRemaining / mFrameSize; ATRACE_BEGIN("write"); // update the setpoint when AudioFlinger::mScreenState changes uint32_t screenState = AudioFlinger::mScreenState; Loading @@ -2001,10 +2003,10 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write() (pipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2); } } ssize_t framesWritten = mNormalSink->write(mSinkBuffer + offset, count); ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count); ATRACE_END(); if (framesWritten > 0) { bytesWritten = framesWritten << mBitShift; bytesWritten = framesWritten * mFrameSize; } else { bytesWritten = framesWritten; } Loading @@ -2019,7 +2021,7 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write() // otherwise use the HAL / AudioStreamOut directly } else { // Direct output and offload threads size_t offset = (mCurrentWriteLength - mBytesRemaining); if (mUseAsyncWrite) { ALOGW_IF(mWriteAckSequence & 1, "threadLoop_write(): out of sequence write request"); mWriteAckSequence += 2; Loading Loading @@ -2111,8 +2113,8 @@ void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamTy status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& chain) { int session = chain->sessionId(); int16_t *buffer = mEffectBufferEnabled ? reinterpret_cast<int16_t*>(mEffectBuffer) : mSinkBuffer; int16_t* buffer = reinterpret_cast<int16_t*>(mEffectBufferEnabled ? mEffectBuffer : mSinkBuffer); bool ownsBuffer = false; ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session); Loading Loading @@ -2152,8 +2154,8 @@ status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& c } chain->setInBuffer(buffer, ownsBuffer); chain->setOutBuffer(mEffectBufferEnabled ? reinterpret_cast<int16_t*>(mEffectBuffer) : mSinkBuffer); chain->setOutBuffer(reinterpret_cast<int16_t*>(mEffectBufferEnabled ? mEffectBuffer : mSinkBuffer)); // Effect chain for session AUDIO_SESSION_OUTPUT_STAGE is inserted at end of effect // chains list in order to be processed last as it contains output stage effects // Effect chain for session AUDIO_SESSION_OUTPUT_MIX is inserted before Loading Loading @@ -2203,7 +2205,7 @@ size_t AudioFlinger::PlaybackThread::removeEffectChain_l(const sp<EffectChain>& for (size_t i = 0; i < mTracks.size(); ++i) { sp<Track> track = mTracks[i]; if (session == track->sessionId()) { track->setMainBuffer(mSinkBuffer); track->setMainBuffer(reinterpret_cast<int16_t*>(mSinkBuffer)); chain->decTrackCnt(); } } Loading Loading @@ -4471,7 +4473,15 @@ void AudioFlinger::DuplicatingThread::threadLoop_sleepTime() ssize_t AudioFlinger::DuplicatingThread::threadLoop_write() { for (size_t i = 0; i < outputTracks.size(); i++) { outputTracks[i]->write(mSinkBuffer, writeFrames); // We convert the duplicating thread format to AUDIO_FORMAT_PCM_16_BIT // for delivery downstream as needed. This in-place conversion is safe as // AUDIO_FORMAT_PCM_16_BIT is smaller than any other supported format // (AUDIO_FORMAT_PCM_8_BIT is not allowed here). if (mFormat != AUDIO_FORMAT_PCM_16_BIT) { memcpy_by_audio_format(mSinkBuffer, AUDIO_FORMAT_PCM_16_BIT, mSinkBuffer, mFormat, writeFrames * mChannelCount); } outputTracks[i]->write(reinterpret_cast<int16_t*>(mSinkBuffer), writeFrames); } mStandby = false; return (ssize_t)mSinkBufferSize; Loading Loading @@ -4500,10 +4510,16 @@ void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread) Mutex::Autolock _l(mLock); // FIXME explain this formula size_t frameCount = (3 * mNormalFrameCount * mSampleRate) / thread->sampleRate(); // OutputTrack is forced to AUDIO_FORMAT_PCM_16_BIT regardless of mFormat // due to current usage case and restrictions on the AudioBufferProvider. // Actual buffer conversion is done in threadLoop_write(). // // TODO: This may change in the future, depending on multichannel // (and non int16_t*) support on AF::PlaybackThread::OutputTrack OutputTrack *outputTrack = new OutputTrack(thread, this, mSampleRate, mFormat, AUDIO_FORMAT_PCM_16_BIT, mChannelMask, frameCount, IPCThreadState::self()->getCallingUid()); Loading services/audioflinger/Threads.h +6 −3 Original line number Diff line number Diff line Loading @@ -450,8 +450,11 @@ public: virtual String8 getParameters(const String8& keys); virtual void audioConfigChanged_l(int event, int param = 0); status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames); // TODO: rename mixBuffer() to sinkBuffer() or try to remove external use. int16_t *mixBuffer() const { return mSinkBuffer; }; // FIXME rename mixBuffer() to sinkBuffer() and remove int16_t* dependency. // Consider also removing and passing an explicit mMainBuffer initialization // parameter to AF::PlaybackThread::Track::Track(). int16_t *mixBuffer() const { return reinterpret_cast<int16_t *>(mSinkBuffer); }; virtual void detachAuxEffect_l(int effectId); status_t attachAuxEffect(const sp<AudioFlinger::PlaybackThread::Track> track, Loading Loading @@ -482,7 +485,7 @@ protected: // updated by readOutputParameters_l() size_t mNormalFrameCount; // normal mixer and effects int16_t* mSinkBuffer; // frame size aligned sink buffer void* mSinkBuffer; // frame size aligned sink buffer // TODO: // Rearrange the buffer info into a struct/class with Loading Loading
services/audioflinger/Threads.cpp +35 −19 Original line number Diff line number Diff line Loading @@ -1145,7 +1145,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge AudioFlinger::PlaybackThread::~PlaybackThread() { mAudioFlinger->unregisterWriter(mNBLogWriter); delete[] mSinkBuffer; free(mSinkBuffer); free(mMixerBuffer); free(mEffectBuffer); } Loading Loading @@ -1782,11 +1782,13 @@ void AudioFlinger::PlaybackThread::readOutputParameters_l() ALOGI("HAL output buffer size %u frames, normal sink buffer size %u frames", mFrameCount, mNormalFrameCount); delete[] mSinkBuffer; size_t normalBufferSize = mNormalFrameCount * mFrameSize; // For historical reasons mSinkBuffer is int16_t[], but mFrameSize can be odd (such as 1) mSinkBuffer = new int16_t[(normalBufferSize + 1) >> 1]; memset(mSinkBuffer, 0, normalBufferSize); // mSinkBuffer is the sink buffer. Size is always multiple-of-16 frames. // Originally this was int16_t[] array, need to remove legacy implications. free(mSinkBuffer); mSinkBuffer = NULL; const size_t sinkBufferSize = mNormalFrameCount * mChannelCount * audio_bytes_per_sample(mFormat); (void)posix_memalign(&mSinkBuffer, 32, sinkBufferSize); // We resize the mMixerBuffer according to the requirements of the sink buffer which // drives the output. Loading Loading @@ -1984,12 +1986,12 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write() mLastWriteTime = systemTime(); mInWrite = true; ssize_t bytesWritten; const size_t offset = mCurrentWriteLength - mBytesRemaining; // If an NBAIO sink is present, use it to write the normal mixer's submix if (mNormalSink != 0) { #define mBitShift 2 // FIXME size_t count = mBytesRemaining >> mBitShift; size_t offset = (mCurrentWriteLength - mBytesRemaining) >> 1; const size_t count = mBytesRemaining / mFrameSize; ATRACE_BEGIN("write"); // update the setpoint when AudioFlinger::mScreenState changes uint32_t screenState = AudioFlinger::mScreenState; Loading @@ -2001,10 +2003,10 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write() (pipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2); } } ssize_t framesWritten = mNormalSink->write(mSinkBuffer + offset, count); ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count); ATRACE_END(); if (framesWritten > 0) { bytesWritten = framesWritten << mBitShift; bytesWritten = framesWritten * mFrameSize; } else { bytesWritten = framesWritten; } Loading @@ -2019,7 +2021,7 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write() // otherwise use the HAL / AudioStreamOut directly } else { // Direct output and offload threads size_t offset = (mCurrentWriteLength - mBytesRemaining); if (mUseAsyncWrite) { ALOGW_IF(mWriteAckSequence & 1, "threadLoop_write(): out of sequence write request"); mWriteAckSequence += 2; Loading Loading @@ -2111,8 +2113,8 @@ void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamTy status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& chain) { int session = chain->sessionId(); int16_t *buffer = mEffectBufferEnabled ? reinterpret_cast<int16_t*>(mEffectBuffer) : mSinkBuffer; int16_t* buffer = reinterpret_cast<int16_t*>(mEffectBufferEnabled ? mEffectBuffer : mSinkBuffer); bool ownsBuffer = false; ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session); Loading Loading @@ -2152,8 +2154,8 @@ status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& c } chain->setInBuffer(buffer, ownsBuffer); chain->setOutBuffer(mEffectBufferEnabled ? reinterpret_cast<int16_t*>(mEffectBuffer) : mSinkBuffer); chain->setOutBuffer(reinterpret_cast<int16_t*>(mEffectBufferEnabled ? mEffectBuffer : mSinkBuffer)); // Effect chain for session AUDIO_SESSION_OUTPUT_STAGE is inserted at end of effect // chains list in order to be processed last as it contains output stage effects // Effect chain for session AUDIO_SESSION_OUTPUT_MIX is inserted before Loading Loading @@ -2203,7 +2205,7 @@ size_t AudioFlinger::PlaybackThread::removeEffectChain_l(const sp<EffectChain>& for (size_t i = 0; i < mTracks.size(); ++i) { sp<Track> track = mTracks[i]; if (session == track->sessionId()) { track->setMainBuffer(mSinkBuffer); track->setMainBuffer(reinterpret_cast<int16_t*>(mSinkBuffer)); chain->decTrackCnt(); } } Loading Loading @@ -4471,7 +4473,15 @@ void AudioFlinger::DuplicatingThread::threadLoop_sleepTime() ssize_t AudioFlinger::DuplicatingThread::threadLoop_write() { for (size_t i = 0; i < outputTracks.size(); i++) { outputTracks[i]->write(mSinkBuffer, writeFrames); // We convert the duplicating thread format to AUDIO_FORMAT_PCM_16_BIT // for delivery downstream as needed. This in-place conversion is safe as // AUDIO_FORMAT_PCM_16_BIT is smaller than any other supported format // (AUDIO_FORMAT_PCM_8_BIT is not allowed here). if (mFormat != AUDIO_FORMAT_PCM_16_BIT) { memcpy_by_audio_format(mSinkBuffer, AUDIO_FORMAT_PCM_16_BIT, mSinkBuffer, mFormat, writeFrames * mChannelCount); } outputTracks[i]->write(reinterpret_cast<int16_t*>(mSinkBuffer), writeFrames); } mStandby = false; return (ssize_t)mSinkBufferSize; Loading Loading @@ -4500,10 +4510,16 @@ void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread) Mutex::Autolock _l(mLock); // FIXME explain this formula size_t frameCount = (3 * mNormalFrameCount * mSampleRate) / thread->sampleRate(); // OutputTrack is forced to AUDIO_FORMAT_PCM_16_BIT regardless of mFormat // due to current usage case and restrictions on the AudioBufferProvider. // Actual buffer conversion is done in threadLoop_write(). // // TODO: This may change in the future, depending on multichannel // (and non int16_t*) support on AF::PlaybackThread::OutputTrack OutputTrack *outputTrack = new OutputTrack(thread, this, mSampleRate, mFormat, AUDIO_FORMAT_PCM_16_BIT, mChannelMask, frameCount, IPCThreadState::self()->getCallingUid()); Loading
services/audioflinger/Threads.h +6 −3 Original line number Diff line number Diff line Loading @@ -450,8 +450,11 @@ public: virtual String8 getParameters(const String8& keys); virtual void audioConfigChanged_l(int event, int param = 0); status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames); // TODO: rename mixBuffer() to sinkBuffer() or try to remove external use. int16_t *mixBuffer() const { return mSinkBuffer; }; // FIXME rename mixBuffer() to sinkBuffer() and remove int16_t* dependency. // Consider also removing and passing an explicit mMainBuffer initialization // parameter to AF::PlaybackThread::Track::Track(). int16_t *mixBuffer() const { return reinterpret_cast<int16_t *>(mSinkBuffer); }; virtual void detachAuxEffect_l(int effectId); status_t attachAuxEffect(const sp<AudioFlinger::PlaybackThread::Track> track, Loading Loading @@ -482,7 +485,7 @@ protected: // updated by readOutputParameters_l() size_t mNormalFrameCount; // normal mixer and effects int16_t* mSinkBuffer; // frame size aligned sink buffer void* mSinkBuffer; // frame size aligned sink buffer // TODO: // Rearrange the buffer info into a struct/class with Loading