RecordThread: Adjust sleep time to pipe frames free.
This fixes FastCapture pipe overrun for normal AudioRecord clients.
Test: instrumented CTS AudioRecord, Photos record.
Bug: 71330194
Bug: 77281929
Change-Id: I186017aec8d0acb3aefe9e4eb378b71b32f8ad59
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index c47aa01..bfa72ae 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -6614,11 +6614,16 @@
if (framesRead != OVERRUN) break;
}
- // since pipe is non-blocking, simulate blocking input by waiting for 1/2 of
- // buffer size or at least for 20ms.
- size_t sleepFrames = max(
- min(mPipeFramesP2, mRsmpInFramesP2) / 2, FMS_20 * mSampleRate / 1000);
- if (framesRead <= (ssize_t) sleepFrames) {
+ const ssize_t availableToRead = mPipeSource->availableToRead();
+ if (availableToRead >= 0) {
+ // PipeSource is the master clock. It is up to the AudioRecord client to keep up.
+ LOG_ALWAYS_FATAL_IF((size_t)availableToRead > mPipeFramesP2,
+ "more frames to read than fifo size, %zd > %zu",
+ availableToRead, mPipeFramesP2);
+ const size_t pipeFramesFree = mPipeFramesP2 - availableToRead;
+ const size_t sleepFrames = min(pipeFramesFree, mRsmpInFramesP2) / 2;
+ ALOGVV("mPipeFramesP2:%zu mRsmpInFramesP2:%zu sleepFrames:%zu availableToRead:%zd",
+ mPipeFramesP2, mRsmpInFramesP2, sleepFrames, availableToRead);
sleepUs = (sleepFrames * 1000000LL) / mSampleRate;
}
if (framesRead < 0) {