Skip to content

Commit f1f5fc8

Browse files
author
Eric Laurent
committed
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
1 parent 7257a32 commit f1f5fc8

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

services/audioflinger/AudioFlinger.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ static const int kRecordThreadSleepUs = 5000;
8989

9090
static const nsecs_t kSetParametersTimeout = seconds(2);
9191

92+
// minimum sleep time for the mixer thread loop when tracks are active but in underrun
93+
static const uint32_t kMinThreadSleepTimeUs = 5000;
94+
// maximum divider applied to the active sleep time in the mixer thread loop
95+
static const uint32_t kMaxThreadSleepTimeShift = 2;
96+
97+
9298
// ----------------------------------------------------------------------------
9399

94100
static bool recordingAllowed() {
@@ -1846,6 +1852,7 @@ bool AudioFlinger::MixerThread::threadLoop()
18461852
uint32_t activeSleepTime = activeSleepTimeUs();
18471853
uint32_t idleSleepTime = idleSleepTimeUs();
18481854
uint32_t sleepTime = idleSleepTime;
1855+
uint32_t sleepTimeShift = 0;
18491856
Vector< sp<EffectChain> > effectChains;
18501857
#ifdef DEBUG_CPU_USAGE
18511858
ThreadCpuUsage cpu;
@@ -1937,6 +1944,7 @@ bool AudioFlinger::MixerThread::threadLoop()
19371944

19381945
standbyTime = systemTime() + kStandbyTimeInNsecs;
19391946
sleepTime = idleSleepTime;
1947+
sleepTimeShift = 0;
19401948
continue;
19411949
}
19421950
}
@@ -1953,14 +1961,28 @@ bool AudioFlinger::MixerThread::threadLoop()
19531961
// mix buffers...
19541962
mAudioMixer->process();
19551963
sleepTime = 0;
1964+
// increase sleep time progressively when application underrun condition clears
1965+
if (sleepTimeShift > 0) {
1966+
sleepTimeShift--;
1967+
}
19561968
standbyTime = systemTime() + kStandbyTimeInNsecs;
19571969
//TODO: delay standby when effects have a tail
19581970
} else {
19591971
// If no tracks are ready, sleep once for the duration of an output
19601972
// buffer size, then write 0s to the output
19611973
if (sleepTime == 0) {
19621974
if (mixerStatus == MIXER_TRACKS_ENABLED) {
1963-
sleepTime = activeSleepTime;
1975+
sleepTime = activeSleepTime >> sleepTimeShift;
1976+
if (sleepTime < kMinThreadSleepTimeUs) {
1977+
sleepTime = kMinThreadSleepTimeUs;
1978+
}
1979+
// reduce sleep time in case of consecutive application underruns to avoid
1980+
// starving the audio HAL. As activeSleepTimeUs() is larger than a buffer
1981+
// duration we would end up writing less data than needed by the audio HAL if
1982+
// the condition persists.
1983+
if (sleepTimeShift < kMaxThreadSleepTimeShift) {
1984+
sleepTimeShift++;
1985+
}
19641986
} else {
19651987
sleepTime = idleSleepTime;
19661988
}

0 commit comments

Comments
 (0)