aaudio: reduce glitching by improving sleep timing
ALways sleep a minimum time to avoid busy wait in real-time thread.
Account for wakeup jitter in threads on the other side of a FIFO.
Avoid race condition that caused a longer sleep than necessary.
Fix calculation of mFreeRunning for capture mode.
Also added systrace logging, which was used to debug this.
Bug: 63814792
Test: Run GStomper on Walleye with MMAP on, see bug
Change-Id: I7b20098580ff454365425bd21e43c17ade532a0a
diff --git a/services/oboeservice/AAudioMixer.cpp b/services/oboeservice/AAudioMixer.cpp
index 43203d4..8222734 100644
--- a/services/oboeservice/AAudioMixer.cpp
+++ b/services/oboeservice/AAudioMixer.cpp
@@ -18,9 +18,17 @@
//#define LOG_NDEBUG 0
#include <utils/Log.h>
+#define ATRACE_TAG ATRACE_TAG_AUDIO
+
#include <cstring>
+#include <utils/Trace.h>
+
#include "AAudioMixer.h"
+#ifndef AAUDIO_MIXER_ATRACE_ENABLED
+#define AAUDIO_MIXER_ATRACE_ENABLED 1
+#endif
+
using android::WrappingBuffer;
using android::FifoBuffer;
using android::fifo_frames_t;
@@ -41,13 +49,28 @@
memset(mOutputBuffer, 0, mBufferSizeInBytes);
}
-bool AAudioMixer::mix(FifoBuffer *fifo, float volume) {
+bool AAudioMixer::mix(int trackIndex, FifoBuffer *fifo, float volume) {
WrappingBuffer wrappingBuffer;
float *destination = mOutputBuffer;
fifo_frames_t framesLeft = mFramesPerBurst;
+#if AAUDIO_MIXER_ATRACE_ENABLED
+ ATRACE_BEGIN("aaMix");
+#endif /* AAUDIO_MIXER_ATRACE_ENABLED */
+
// Gather the data from the client. May be in two parts.
- fifo->getFullDataAvailable(&wrappingBuffer);
+ fifo_frames_t fullFrames = fifo->getFullDataAvailable(&wrappingBuffer);
+#if AAUDIO_MIXER_ATRACE_ENABLED
+ if (ATRACE_ENABLED()) {
+ char rdyText[] = "aaMixRdy#";
+ char letter = 'A' + (trackIndex % 26);
+ rdyText[sizeof(rdyText) - 2] = letter;
+ ATRACE_INT(rdyText, fullFrames);
+ }
+#else /* MIXER_ATRACE_ENABLED */
+ (void) trackIndex;
+ (void) fullFrames;
+#endif /* AAUDIO_MIXER_ATRACE_ENABLED */
// Mix data in one or two parts.
int partIndex = 0;
@@ -70,6 +93,10 @@
//ALOGW("AAudioMixer::mix() UNDERFLOW by %d / %d frames ----- UNDERFLOW !!!!!!!!!!",
// framesLeft, mFramesPerBurst);
}
+#if AAUDIO_MIXER_ATRACE_ENABLED
+ ATRACE_END();
+#endif /* AAUDIO_MIXER_ATRACE_ENABLED */
+
return (framesLeft > 0); // did not get all the frames we needed, ie. "underflow"
}
diff --git a/services/oboeservice/AAudioMixer.h b/services/oboeservice/AAudioMixer.h
index 9155fec..a8090bc 100644
--- a/services/oboeservice/AAudioMixer.h
+++ b/services/oboeservice/AAudioMixer.h
@@ -37,7 +37,7 @@
* @param volume
* @return true if underflowed
*/
- bool mix(android::FifoBuffer *fifo, float volume);
+ bool mix(int trackIndex, android::FifoBuffer *fifo, float volume);
void mixPart(float *destination, float *source, int32_t numFrames, float volume);
diff --git a/services/oboeservice/AAudioServiceEndpointPlay.cpp b/services/oboeservice/AAudioServiceEndpointPlay.cpp
index e609ab5..b83b918 100644
--- a/services/oboeservice/AAudioServiceEndpointPlay.cpp
+++ b/services/oboeservice/AAudioServiceEndpointPlay.cpp
@@ -74,16 +74,18 @@
// Mix data from each active stream.
mMixer.clear();
{ // use lock guard
+ int index = 0;
std::lock_guard <std::mutex> lock(mLockStreams);
for (sp<AAudioServiceStreamShared> sharedStream : mRegisteredStreams) {
if (sharedStream->isRunning()) {
FifoBuffer *fifo = sharedStream->getDataFifoBuffer();
float volume = 1.0; // to match legacy volume
- bool underflowed = mMixer.mix(fifo, volume);
+ bool underflowed = mMixer.mix(index, fifo, volume);
underflowCount += underflowed ? 1 : 0;
// TODO log underflows in each stream
sharedStream->markTransferTime(AudioClock::getNanoseconds());
}
+ index++;
}
}
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp
index afa2ff0..ff02c0f 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.cpp
+++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp
@@ -154,7 +154,7 @@
status);
return AAUDIO_ERROR_UNAVAILABLE;
} else {
- ALOGD("createMmapBuffer status %d, buffer_size, %d burst_size %d"
+ ALOGD("createMmapBuffer status = %d, buffer_size = %d, burst_size %d"
", Sharable FD: %s",
status,
abs(mMmapBufferinfo.buffer_size_frames),