summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Eric Laurent <elaurent@google.com> 2011-11-22 18:50:29 -0800
committer Eric Laurent <elaurent@google.com> 2011-11-22 18:50:29 -0800
commitf1f5fc85b07fe74cfa12789fefa126cac7a499a9 (patch)
tree747ded89a6c7366e2f809ecd8e2e43d5c9edcbc4
parent7257a32b9ac7cbbb47659ed7bea4ab47e74ac3ec (diff)
audioflinger: reduce sleep time to avoid underrun
Progressively reduce the sleep time applied in MixerThread::threadLoop() in case of consecutive application underruns to avoid starving the audio HAL. As the default sleep time is longer than the duration of an audio buffer we ended up writing less data than needed by the audio HAL if the condition persisted. Issue 5553055. Change-Id: I2b23ee79c032efa945025db228beaecd1e07a2e5
-rw-r--r--services/audioflinger/AudioFlinger.cpp24
1 files changed, 23 insertions, 1 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 780c0d2c9b23..aea31a81bdc1 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -89,6 +89,12 @@ static const int kRecordThreadSleepUs = 5000;
static const nsecs_t kSetParametersTimeout = seconds(2);
+// minimum sleep time for the mixer thread loop when tracks are active but in underrun
+static const uint32_t kMinThreadSleepTimeUs = 5000;
+// maximum divider applied to the active sleep time in the mixer thread loop
+static const uint32_t kMaxThreadSleepTimeShift = 2;
+
+
// ----------------------------------------------------------------------------
static bool recordingAllowed() {
@@ -1846,6 +1852,7 @@ bool AudioFlinger::MixerThread::threadLoop()
uint32_t activeSleepTime = activeSleepTimeUs();
uint32_t idleSleepTime = idleSleepTimeUs();
uint32_t sleepTime = idleSleepTime;
+ uint32_t sleepTimeShift = 0;
Vector< sp<EffectChain> > effectChains;
#ifdef DEBUG_CPU_USAGE
ThreadCpuUsage cpu;
@@ -1937,6 +1944,7 @@ bool AudioFlinger::MixerThread::threadLoop()
standbyTime = systemTime() + kStandbyTimeInNsecs;
sleepTime = idleSleepTime;
+ sleepTimeShift = 0;
continue;
}
}
@@ -1953,6 +1961,10 @@ bool AudioFlinger::MixerThread::threadLoop()
// mix buffers...
mAudioMixer->process();
sleepTime = 0;
+ // increase sleep time progressively when application underrun condition clears
+ if (sleepTimeShift > 0) {
+ sleepTimeShift--;
+ }
standbyTime = systemTime() + kStandbyTimeInNsecs;
//TODO: delay standby when effects have a tail
} else {
@@ -1960,7 +1972,17 @@ bool AudioFlinger::MixerThread::threadLoop()
// buffer size, then write 0s to the output
if (sleepTime == 0) {
if (mixerStatus == MIXER_TRACKS_ENABLED) {
- sleepTime = activeSleepTime;
+ sleepTime = activeSleepTime >> sleepTimeShift;
+ if (sleepTime < kMinThreadSleepTimeUs) {
+ sleepTime = kMinThreadSleepTimeUs;
+ }
+ // reduce sleep time in case of consecutive application underruns to avoid
+ // starving the audio HAL. As activeSleepTimeUs() is larger than a buffer
+ // duration we would end up writing less data than needed by the audio HAL if
+ // the condition persists.
+ if (sleepTimeShift < kMaxThreadSleepTimeShift) {
+ sleepTimeShift++;
+ }
} else {
sleepTime = idleSleepTime;
}