Fix wait time for audio threads in suspend mode
Better estimation of wait time in suspended audio threads.
Bug: 34772697
Test: phone calls with BT headset.
Change-Id: Icf99c0671def810b57332a321e4de4680697715b
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 8d018d1..a6857fe 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2962,6 +2962,10 @@
// and then that string will be logged at the next convenient opportunity.
const char *logString = NULL;
+ // Estimated time for next buffer to be written to hal. This is used only on
+ // suspended mode (for now) to help schedule the wait time until next iteration.
+ nsecs_t timeLoopNextNs = 0;
+
checkSilentMode_l();
#if 0
int z = 0; // used in logFormat example
@@ -3327,6 +3331,29 @@
} else {
ATRACE_BEGIN("sleep");
Mutex::Autolock _l(mLock);
+ // suspended requires accurate metering of sleep time.
+ if (isSuspended()) {
+ // advance by expected sleepTime
+ timeLoopNextNs += microseconds((nsecs_t)mSleepTimeUs);
+ const nsecs_t nowNs = systemTime();
+
+ // compute expected next time vs current time.
+ // (negative deltas are treated as delays).
+ nsecs_t deltaNs = timeLoopNextNs - nowNs;
+ if (deltaNs < -kMaxNextBufferDelayNs) {
+ // Delays longer than the max allowed trigger a reset.
+ ALOGV("DelayNs: %lld, resetting timeLoopNextNs", (long long) deltaNs);
+ deltaNs = microseconds((nsecs_t)mSleepTimeUs);
+ timeLoopNextNs = nowNs + deltaNs;
+ } else if (deltaNs < 0) {
+ // Delays within the max delay allowed: zero the delta/sleepTime
+ // to help the system catch up in the next iteration(s)
+ ALOGV("DelayNs: %lld, catching-up", (long long) deltaNs);
+ deltaNs = 0;
+ }
+ // update sleep time (which is >= 0)
+ mSleepTimeUs = deltaNs / 1000;
+ }
if (!mSignalPending && mConfigEvents.isEmpty() && !exitPending()) {
mWaitWorkCV.waitRelative(mLock, microseconds((nsecs_t)mSleepTimeUs));
}
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 7469710..80b368e 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -623,6 +623,12 @@
// 14 tracks max per client allows for 2 misbehaving application leaving 4 available tracks.
static const uint32_t kMaxTracksPerUid = 14;
+ // Maximum delay (in nanoseconds) for upcoming buffers in suspend mode, otherwise
+ // if delay is greater, the estimated time for timeLoopNextNs is reset.
+ // This allows for catch-up to be done for small delays, while resetting the estimate
+ // for initial conditions or large delays.
+ static const nsecs_t kMaxNextBufferDelayNs = 100000000;
+
PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
audio_io_handle_t id, audio_devices_t device, type_t type, bool systemReady);
virtual ~PlaybackThread();