summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/Threads.cpp
diff options
context:
space:
mode:
authorPhil Burk <philburk@google.com>2015-06-09 16:53:44 -0700
committerPhil Burk <philburk@google.com>2015-06-11 10:37:21 -0700
commit43b4dcc660e6da96285e4672ae371070ab845401 (patch)
treef03f4f3817afd22eb759962cde571029f312e1b6 /services/audioflinger/Threads.cpp
parentafd492436efc7f66b958da14659b52232efa5910 (diff)
downloadframeworks_av-43b4dcc660e6da96285e4672ae371070ab845401.zip
frameworks_av-43b4dcc660e6da96285e4672ae371070ab845401.tar.gz
frameworks_av-43b4dcc660e6da96285e4672ae371070ab845401.tar.bz2
AudioFlinger: flush stream when switching tracks
For direct threads, when recycling a stream, perform a flush so that the frame position is reset. Bug: 21145353 Change-Id: I08611cd64bb249a9659c44f9e4c47e7455f4838f Signed-off-by: Phil Burk <philburk@google.com>
Diffstat (limited to 'services/audioflinger/Threads.cpp')
-rw-r--r--services/audioflinger/Threads.cpp62
1 files changed, 40 insertions, 22 deletions
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index dc6710f..84c4fcf 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -4458,6 +4458,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
@@ -4467,7 +4478,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++) {
@@ -4477,6 +4487,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.
@@ -4496,7 +4512,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();
@@ -4537,6 +4553,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;
@@ -4603,11 +4634,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;
}
}
}
@@ -4617,10 +4648,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) {
@@ -4679,14 +4710,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();
}
}
@@ -4824,6 +4854,7 @@ void AudioFlinger::DirectOutputThread::flushHw_l()
{
mOutput->flush();
mHwPaused = false;
+ mFlushPending = false;
}
// ----------------------------------------------------------------------------
@@ -5145,7 +5176,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr
}
if (mFlushPending) {
flushHw_l();
- mFlushPending = false;
}
if (!mStandby && doHwResume) {
mOutput->stream->resume(mOutput->stream);
@@ -5193,18 +5223,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,