diff options
author | Eric Laurent <elaurent@google.com> | 2013-10-28 17:18:53 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-10-28 17:18:53 -0700 |
commit | d21952fe5bc94f7bb6ee729f806c0e641fdb1a0d (patch) | |
tree | cc3ae62392a01c054b61af9ef606245854090394 | |
parent | 1dfca7775f0b8352a0fd6cfed1e70075e5fa4e75 (diff) | |
parent | 7f8f758506a95d6fe5c0e52aa7b5ef82fb18861a (diff) | |
download | frameworks_av-d21952fe5bc94f7bb6ee729f806c0e641fdb1a0d.zip frameworks_av-d21952fe5bc94f7bb6ee729f806c0e641fdb1a0d.tar.gz frameworks_av-d21952fe5bc94f7bb6ee729f806c0e641fdb1a0d.tar.bz2 |
am 7f8f7585: am fd477974: AudioFlinger: more fixes for offload audio lost
* commit '7f8f758506a95d6fe5c0e52aa7b5ef82fb18861a':
AudioFlinger: more fixes for offload audio lost
-rw-r--r-- | services/audioflinger/Threads.cpp | 39 | ||||
-rw-r--r-- | services/audioflinger/Threads.h | 1 |
2 files changed, 26 insertions, 14 deletions
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index ff7ccac..ef90952 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -272,6 +272,7 @@ AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio // mSampleRate, mFrameCount, mChannelMask, mChannelCount, mFrameSize, mFormat, mBufferSize // are set by PlaybackThread::readOutputParameters() or RecordThread::readInputParameters() mParamStatus(NO_ERROR), + //FIXME: mStandby should be true here. Is this some kind of hack? mStandby(false), mOutDevice(outDevice), mInDevice(inDevice), mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id), // mName will be set by concrete (non-virtual) subclass @@ -1468,6 +1469,7 @@ status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track) mActiveTracks.add(track); mWakeLockUids.add(track->uid()); mActiveTracksGeneration++; + mLatestActiveTrack = track; sp<EffectChain> chain = getEffectChain_l(track->sessionId()); if (chain != 0) { ALOGV("addTrack_l() starting track on chain %p for session %d", chain.get(), @@ -1942,7 +1944,7 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write() mNumWrites++; mInWrite = false; - + mStandby = false; return bytesWritten; } @@ -2365,7 +2367,6 @@ if (mType == MIXER) { } } - mStandby = false; } else { usleep(sleepTime); } @@ -3615,6 +3616,12 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep Track* const track = t.get(); audio_track_cblk_t* cblk = track->cblk(); + // Only consider last track started for volume and mixer state control. + // In theory an older track could underrun and restart after the new one starts + // but as we only care about the transition phase between two tracks on a + // direct output, it is not a problem to ignore the underrun case. + sp<Track> l = mLatestActiveTrack.promote(); + bool last = l.get() == track; // The first time a track is added we wait // for all its buffers to be filled before processing it @@ -3624,11 +3631,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep } else { minFrames = 1; } - // Only consider last track started for volume and mixer state control. - // This is the last entry in mActiveTracks unless a track underruns. - // As we only care about the transition phase between two tracks on a - // direct output, it is not a problem to ignore the underrun case. - bool last = (i == (count - 1)); if ((track->framesReady() >= minFrames) && track->isReady() && !track->isPaused() && !track->isTerminated()) @@ -3655,7 +3657,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep } else { // clear effect chain input buffer if the last active track started underruns // to avoid sending previous audio buffer again to effects - if (!mEffectChains.isEmpty() && (i == (count -1))) { + if (!mEffectChains.isEmpty() && last) { mEffectChains[0]->clearInputBuffer(); } @@ -3667,7 +3669,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep // TODO: implement behavior for compressed audio size_t audioHALFrames = (latency_l() * mSampleRate) / 1000; size_t framesWritten = mBytesWritten / mFrameSize; - if (mStandby || track->presentationComplete(framesWritten, audioHALFrames)) { + if (mStandby || !last || + track->presentationComplete(framesWritten, audioHALFrames)) { if (track->isStopped()) { track->reset(); } @@ -3943,6 +3946,8 @@ AudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger, mPausedBytesRemaining(0), mPreviousTrack(NULL) { + //FIXME: mStandby should be set to true by ThreadBase constructor + mStandby = true; } void AudioFlinger::OffloadThread::threadLoop_exit() @@ -3979,8 +3984,15 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr } Track* const track = t.get(); audio_track_cblk_t* cblk = track->cblk(); + // Only consider last track started for volume and mixer state control. + // In theory an older track could underrun and restart after the new one starts + // but as we only care about the transition phase between two tracks on a + // direct output, it is not a problem to ignore the underrun case. + sp<Track> l = mLatestActiveTrack.promote(); + bool last = l.get() == track; + if (mPreviousTrack != NULL) { - if (t.get() != mPreviousTrack) { + if (track != mPreviousTrack) { // Flush any data still being written from last track mBytesRemaining = 0; if (mPausedBytesRemaining) { @@ -3995,8 +4007,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr } } } - mPreviousTrack = t.get(); - bool last = (i == (count - 1)); + mPreviousTrack = track; if (track->isPausing()) { track->setPaused(); if (last) { @@ -4106,7 +4117,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr // If a flush is pending and a track is active but the HW is not paused, force a HW pause // before flush and then resume HW. This can happen in case of pause/flush/resume // if resume is received before pause is executed. - if (doHwPause || (mFlushPending && !mHwPaused && (count != 0))) { + if (!mStandby && (doHwPause || (mFlushPending && !mHwPaused && (count != 0)))) { mOutput->stream->pause(mOutput->stream); if (!doHwPause) { doHwResume = true; @@ -4116,7 +4127,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr flushHw_l(); mFlushPending = false; } - if (doHwResume) { + if (!mStandby && doHwResume) { mOutput->stream->resume(mOutput->stream); } diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index 2b4c9fd..8a859f5 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -503,6 +503,7 @@ protected: SortedVector< wp<Track> > mActiveTracks; // FIXME check if this could be sp<> SortedVector<int> mWakeLockUids; int mActiveTracksGeneration; + wp<Track> mLatestActiveTrack; // latest track added to mActiveTracks // Allocate a track name for a given channel mask. // Returns name >= 0 if successful, -1 on failure. |