summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/Threads.cpp
diff options
context:
space:
mode:
authorPhil Burk <philburk@google.com>2015-06-11 18:22:43 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-06-11 18:22:44 +0000
commitad9ef61e770c0751a9983aa5c9844dfeb9ed665b (patch)
treee8ab7db05298c171c55954e4dffbf9a99d59953c /services/audioflinger/Threads.cpp
parentcd644a3f7bd16b25a6fd202ce3eb8c7138572712 (diff)
parent43b4dcc660e6da96285e4672ae371070ab845401 (diff)
downloadframeworks_av-ad9ef61e770c0751a9983aa5c9844dfeb9ed665b.zip
frameworks_av-ad9ef61e770c0751a9983aa5c9844dfeb9ed665b.tar.gz
frameworks_av-ad9ef61e770c0751a9983aa5c9844dfeb9ed665b.tar.bz2
Merge "AudioFlinger: flush stream when switching tracks" into mnc-dev
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 ad445a5..489f2d4 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -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
@@ -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++) {
@@ -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.
@@ -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();
@@ -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;
@@ -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;
}
}
}
@@ -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) {
@@ -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();
}
}
@@ -4825,6 +4855,7 @@ void AudioFlinger::DirectOutputThread::flushHw_l()
{
mOutput->flush();
mHwPaused = false;
+ mFlushPending = false;
}
// ----------------------------------------------------------------------------
@@ -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);
@@ -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,