@@ -89,6 +89,12 @@ static const int kRecordThreadSleepUs = 5000;
8989
9090static 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
94100static 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