summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2013-10-28 17:18:53 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2013-10-28 17:18:53 -0700
commitd21952fe5bc94f7bb6ee729f806c0e641fdb1a0d (patch)
treecc3ae62392a01c054b61af9ef606245854090394
parent1dfca7775f0b8352a0fd6cfed1e70075e5fa4e75 (diff)
parent7f8f758506a95d6fe5c0e52aa7b5ef82fb18861a (diff)
downloadframeworks_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.cpp39
-rw-r--r--services/audioflinger/Threads.h1
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.