summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2015-03-30 20:51:47 -0700
committerEric Laurent <elaurent@google.com>2015-04-01 00:03:48 +0000
commitb369cafd67beb63dd0278dba543f519956208a7f (patch)
treec50687a52df6b28cb071b36a5377cae9054bbefa /services
parent253930b927d375413a42f170fa1ef8d98b8f7cb4 (diff)
downloadframeworks_av-b369cafd67beb63dd0278dba543f519956208a7f.zip
frameworks_av-b369cafd67beb63dd0278dba543f519956208a7f.tar.gz
frameworks_av-b369cafd67beb63dd0278dba543f519956208a7f.tar.bz2
audio flinger: fix standby on output with HW A/V sync
Fix a bug in audio HAL pause logic on output threads with HW A/V sync preventing the HAL to enter standby when the audio track is stopped and detroyed. Bug: 19980184. Change-Id: Ia497dad23159038b447fcbc18a67bb61b70b79cc
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/Threads.cpp14
-rw-r--r--services/audioflinger/Tracks.cpp1
2 files changed, 13 insertions, 2 deletions
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 5988d2c..4efb3d7 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -4316,6 +4316,10 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
}
if (track->isStopping_1()) {
track->mState = TrackBase::STOPPING_2;
+ if (last && mHwPaused) {
+ doHwResume = true;
+ mHwPaused = false;
+ }
}
if ((track->sharedBuffer() != 0) || track->isStopped() ||
track->isStopping_2() || track->isPaused()) {
@@ -4455,14 +4459,17 @@ void AudioFlinger::DirectOutputThread::threadLoop_exit()
bool AudioFlinger::DirectOutputThread::shouldStandby_l()
{
bool trackPaused = false;
+ bool trackStopped = false;
// do not put the HAL in standby when paused. AwesomePlayer clear the offloaded AudioTrack
// after a timeout and we will enter standby then.
if (mTracks.size() > 0) {
trackPaused = mTracks[mTracks.size() - 1]->isPaused();
+ trackStopped = mTracks[mTracks.size() - 1]->isStopped() ||
+ mTracks[mTracks.size() - 1]->mState == TrackBase::IDLE;
}
- return !mStandby && !(trackPaused || (usesHwAvSync() && mHwPaused));
+ return !mStandby && !(trackPaused || (usesHwAvSync() && mHwPaused && !trackStopped));
}
// getTrackName_l() must be called with ThreadBase::mLock held
@@ -4565,7 +4572,10 @@ void AudioFlinger::DirectOutputThread::cacheParameters_l()
// use shorter standby delay as on normal output to release
// hardware resources as soon as possible
- if (audio_is_linear_pcm(mFormat)) {
+ // no delay on outputs with HW A/V sync
+ if (usesHwAvSync()) {
+ standbyDelay = 0;
+ } else if (audio_is_linear_pcm(mFormat)) {
standbyDelay = microseconds(activeSleepTime*2);
} else {
standbyDelay = kOffloadStandbyDelayNs;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 7692315..dc9f249 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -745,6 +745,7 @@ void AudioFlinger::PlaybackThread::Track::stop()
// move to STOPPING_2 when drain completes and then STOPPED
mState = STOPPING_1;
}
+ playbackThread->broadcast_l();
ALOGV("not stopping/stopped => stopping/stopped (%d) on thread %p", mName,
playbackThread);
}