Loading services/audioflinger/Threads.cpp +40 −22 Original line number Diff line number Diff line Loading @@ -4459,6 +4459,17 @@ void AudioFlinger::DirectOutputThread::processVolume_l(Track *track, bool lastTr } } void AudioFlinger::DirectOutputThread::onAddNewTrack_l() { sp<Track> previousTrack = mPreviousTrack.promote(); sp<Track> latestTrack = mLatestActiveTrack.promote(); if (previousTrack != 0 && latestTrack != 0 && (previousTrack->sessionId() != latestTrack->sessionId())) { mFlushPending = true; } PlaybackThread::onAddNewTrack_l(); } AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prepareTracks_l( Vector< sp<Track> > *tracksToRemove Loading @@ -4468,7 +4479,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep mixer_state mixerStatus = MIXER_IDLE; bool doHwPause = false; bool doHwResume = false; bool flushPending = false; // find out which tracks need to be processed for (size_t i = 0; i < count; i++) { Loading @@ -4478,6 +4488,12 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep continue; } if (t->isInvalid()) { ALOGW("An invalidated track shouldn't be in active list"); tracksToRemove->add(t); continue; } Track* const track = t.get(); audio_track_cblk_t* cblk = track->cblk(); // Only consider last track started for volume and mixer state control. Loading @@ -4497,7 +4513,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep } else if (track->isFlushPending()) { track->flushAck(); if (last) { flushPending = true; mFlushPending = true; } } else if (track->isResumePending()) { track->resumeAck(); Loading Loading @@ -4538,6 +4554,21 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep // compute volume for this track processVolume_l(track, last); if (last) { sp<Track> previousTrack = mPreviousTrack.promote(); if (previousTrack != 0) { if (track != previousTrack.get()) { // Flush any data still being written from last track mBytesRemaining = 0; // flush data already sent if changing audio session as audio // comes from a different source. Also invalidate previous track to force a // seek when resuming. if (previousTrack->sessionId() != track->sessionId()) { previousTrack->invalidate(); } } } mPreviousTrack = track; // reset retry count track->mRetryCount = kMaxTrackRetriesDirect; mActiveTrack = t; Loading Loading @@ -4604,11 +4635,11 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep } // if an active track did not command a flush, check for pending flush on stopped tracks if (!flushPending) { if (!mFlushPending) { for (size_t i = 0; i < mTracks.size(); i++) { if (mTracks[i]->isFlushPending()) { mTracks[i]->flushAck(); flushPending = true; mFlushPending = true; } } } Loading @@ -4618,10 +4649,10 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep // before flush and then resume HW. This can happen in case of pause/flush/resume // if resume is received before pause is executed. if (mHwSupportsPause && !mStandby && (doHwPause || (flushPending && !mHwPaused && (count != 0)))) { (doHwPause || (mFlushPending && !mHwPaused && (count != 0)))) { mOutput->stream->pause(mOutput->stream); } if (flushPending) { if (mFlushPending) { flushHw_l(); } if (mHwSupportsPause && !mStandby && doHwResume) { Loading Loading @@ -4680,14 +4711,13 @@ void AudioFlinger::DirectOutputThread::threadLoop_exit() { { Mutex::Autolock _l(mLock); bool flushPending = false; for (size_t i = 0; i < mTracks.size(); i++) { if (mTracks[i]->isFlushPending()) { mTracks[i]->flushAck(); flushPending = true; mFlushPending = true; } } if (flushPending) { if (mFlushPending) { flushHw_l(); } } Loading Loading @@ -4825,6 +4855,7 @@ void AudioFlinger::DirectOutputThread::flushHw_l() { mOutput->flush(); mHwPaused = false; mFlushPending = false; } // ---------------------------------------------------------------------------- Loading Loading @@ -5146,7 +5177,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr } if (mFlushPending) { flushHw_l(); mFlushPending = false; } if (!mStandby && doHwResume) { mOutput->stream->resume(mOutput->stream); Loading Loading @@ -5194,18 +5224,6 @@ void AudioFlinger::OffloadThread::flushHw_l() } } void AudioFlinger::OffloadThread::onAddNewTrack_l() { sp<Track> previousTrack = mPreviousTrack.promote(); sp<Track> latestTrack = mLatestActiveTrack.promote(); if (previousTrack != 0 && latestTrack != 0 && (previousTrack->sessionId() != latestTrack->sessionId())) { mFlushPending = true; } PlaybackThread::onAddNewTrack_l(); } // ---------------------------------------------------------------------------- AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, Loading services/audioflinger/Threads.h +5 −2 Original line number Diff line number Diff line Loading @@ -941,6 +941,8 @@ protected: virtual void threadLoop_exit(); virtual bool shouldStandby_l(); virtual void onAddNewTrack_l(); // volumes last sent to audio HAL with stream->set_volume() float mLeftVolFloat; float mRightVolFloat; Loading @@ -952,6 +954,9 @@ protected: // prepareTracks_l() tells threadLoop_mix() the name of the single active track sp<Track> mActiveTrack; wp<Track> mPreviousTrack; // used to detect track switch public: virtual bool hasFastMixer() const { return false; } }; Loading @@ -971,12 +976,10 @@ protected: virtual bool waitingAsyncCallback(); virtual bool waitingAsyncCallback_l(); virtual void onAddNewTrack_l(); private: size_t mPausedWriteLength; // length in bytes of write interrupted by pause size_t mPausedBytesRemaining; // bytes still waiting in mixbuffer after resume wp<Track> mPreviousTrack; // used to detect track switch }; class AsyncCallbackThread : public Thread { Loading Loading
services/audioflinger/Threads.cpp +40 −22 Original line number Diff line number Diff line Loading @@ -4459,6 +4459,17 @@ void AudioFlinger::DirectOutputThread::processVolume_l(Track *track, bool lastTr } } void AudioFlinger::DirectOutputThread::onAddNewTrack_l() { sp<Track> previousTrack = mPreviousTrack.promote(); sp<Track> latestTrack = mLatestActiveTrack.promote(); if (previousTrack != 0 && latestTrack != 0 && (previousTrack->sessionId() != latestTrack->sessionId())) { mFlushPending = true; } PlaybackThread::onAddNewTrack_l(); } AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prepareTracks_l( Vector< sp<Track> > *tracksToRemove Loading @@ -4468,7 +4479,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep mixer_state mixerStatus = MIXER_IDLE; bool doHwPause = false; bool doHwResume = false; bool flushPending = false; // find out which tracks need to be processed for (size_t i = 0; i < count; i++) { Loading @@ -4478,6 +4488,12 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep continue; } if (t->isInvalid()) { ALOGW("An invalidated track shouldn't be in active list"); tracksToRemove->add(t); continue; } Track* const track = t.get(); audio_track_cblk_t* cblk = track->cblk(); // Only consider last track started for volume and mixer state control. Loading @@ -4497,7 +4513,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep } else if (track->isFlushPending()) { track->flushAck(); if (last) { flushPending = true; mFlushPending = true; } } else if (track->isResumePending()) { track->resumeAck(); Loading Loading @@ -4538,6 +4554,21 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep // compute volume for this track processVolume_l(track, last); if (last) { sp<Track> previousTrack = mPreviousTrack.promote(); if (previousTrack != 0) { if (track != previousTrack.get()) { // Flush any data still being written from last track mBytesRemaining = 0; // flush data already sent if changing audio session as audio // comes from a different source. Also invalidate previous track to force a // seek when resuming. if (previousTrack->sessionId() != track->sessionId()) { previousTrack->invalidate(); } } } mPreviousTrack = track; // reset retry count track->mRetryCount = kMaxTrackRetriesDirect; mActiveTrack = t; Loading Loading @@ -4604,11 +4635,11 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep } // if an active track did not command a flush, check for pending flush on stopped tracks if (!flushPending) { if (!mFlushPending) { for (size_t i = 0; i < mTracks.size(); i++) { if (mTracks[i]->isFlushPending()) { mTracks[i]->flushAck(); flushPending = true; mFlushPending = true; } } } Loading @@ -4618,10 +4649,10 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep // before flush and then resume HW. This can happen in case of pause/flush/resume // if resume is received before pause is executed. if (mHwSupportsPause && !mStandby && (doHwPause || (flushPending && !mHwPaused && (count != 0)))) { (doHwPause || (mFlushPending && !mHwPaused && (count != 0)))) { mOutput->stream->pause(mOutput->stream); } if (flushPending) { if (mFlushPending) { flushHw_l(); } if (mHwSupportsPause && !mStandby && doHwResume) { Loading Loading @@ -4680,14 +4711,13 @@ void AudioFlinger::DirectOutputThread::threadLoop_exit() { { Mutex::Autolock _l(mLock); bool flushPending = false; for (size_t i = 0; i < mTracks.size(); i++) { if (mTracks[i]->isFlushPending()) { mTracks[i]->flushAck(); flushPending = true; mFlushPending = true; } } if (flushPending) { if (mFlushPending) { flushHw_l(); } } Loading Loading @@ -4825,6 +4855,7 @@ void AudioFlinger::DirectOutputThread::flushHw_l() { mOutput->flush(); mHwPaused = false; mFlushPending = false; } // ---------------------------------------------------------------------------- Loading Loading @@ -5146,7 +5177,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr } if (mFlushPending) { flushHw_l(); mFlushPending = false; } if (!mStandby && doHwResume) { mOutput->stream->resume(mOutput->stream); Loading Loading @@ -5194,18 +5224,6 @@ void AudioFlinger::OffloadThread::flushHw_l() } } void AudioFlinger::OffloadThread::onAddNewTrack_l() { sp<Track> previousTrack = mPreviousTrack.promote(); sp<Track> latestTrack = mLatestActiveTrack.promote(); if (previousTrack != 0 && latestTrack != 0 && (previousTrack->sessionId() != latestTrack->sessionId())) { mFlushPending = true; } PlaybackThread::onAddNewTrack_l(); } // ---------------------------------------------------------------------------- AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, Loading
services/audioflinger/Threads.h +5 −2 Original line number Diff line number Diff line Loading @@ -941,6 +941,8 @@ protected: virtual void threadLoop_exit(); virtual bool shouldStandby_l(); virtual void onAddNewTrack_l(); // volumes last sent to audio HAL with stream->set_volume() float mLeftVolFloat; float mRightVolFloat; Loading @@ -952,6 +954,9 @@ protected: // prepareTracks_l() tells threadLoop_mix() the name of the single active track sp<Track> mActiveTrack; wp<Track> mPreviousTrack; // used to detect track switch public: virtual bool hasFastMixer() const { return false; } }; Loading @@ -971,12 +976,10 @@ protected: virtual bool waitingAsyncCallback(); virtual bool waitingAsyncCallback_l(); virtual void onAddNewTrack_l(); private: size_t mPausedWriteLength; // length in bytes of write interrupted by pause size_t mPausedBytesRemaining; // bytes still waiting in mixbuffer after resume wp<Track> mPreviousTrack; // used to detect track switch }; class AsyncCallbackThread : public Thread { Loading