aaudio: improve accuracy of timestamps
Account for latency added by the AAudio service.
Fix input timestamps.
Bug: 37080396
Test: test_timestamps.cpp input_monitor.cpp
Change-Id: I1053cd21af722bb9b9371df4e5731bf4a0a57b0b
diff --git a/services/oboeservice/AAudioServiceEndpointCapture.cpp b/services/oboeservice/AAudioServiceEndpointCapture.cpp
index 6a37330..6504cc1 100644
--- a/services/oboeservice/AAudioServiceEndpointCapture.cpp
+++ b/services/oboeservice/AAudioServiceEndpointCapture.cpp
@@ -62,6 +62,9 @@
// result might be a frame count
while (mCallbackEnabled.load() && getStreamInternal()->isActive() && (result >= 0)) {
+
+ int64_t mmapFramesRead = getStreamInternal()->getFramesRead();
+
// Read audio data from stream using a blocking read.
result = getStreamInternal()->read(mDistributionBuffer, getFramesPerBurst(), timeoutNanos);
if (result == AAUDIO_ERROR_DISCONNECTED) {
@@ -74,18 +77,32 @@
}
// Distribute data to each active stream.
- { // use lock guard
+ { // brackets are for lock_guard
+
std::lock_guard <std::mutex> lock(mLockStreams);
- for (sp<AAudioServiceStreamShared> sharedStream : mRegisteredStreams) {
- if (sharedStream->isRunning()) {
- FifoBuffer *fifo = sharedStream->getDataFifoBuffer();
+ for (sp<AAudioServiceStreamShared> clientStream : mRegisteredStreams) {
+ if (clientStream->isRunning()) {
+ FifoBuffer *fifo = clientStream->getDataFifoBuffer();
+
+ // Determine offset between framePosition in client's stream vs the underlying
+ // MMAP stream.
+ int64_t clientFramesWritten = fifo->getWriteCounter();
+ // There are two indices that refer to the same frame.
+ int64_t positionOffset = mmapFramesRead - clientFramesWritten;
+ clientStream->setTimestampPositionOffset(positionOffset);
+
if (fifo->getFifoControllerBase()->getEmptyFramesAvailable() <
getFramesPerBurst()) {
underflowCount++;
} else {
fifo->write(mDistributionBuffer, getFramesPerBurst());
}
- sharedStream->markTransferTime(AudioClock::getNanoseconds());
+
+ // This timestamp represents the completion of data being written into the
+ // client buffer. It is sent to the client and used in the timing model
+ // to decide when data will be available to read.
+ Timestamp timestamp(fifo->getWriteCounter(), AudioClock::getNanoseconds());
+ clientStream->markTransferTime(timestamp);
}
}
}