Add getExternalPosition in MMapStreamInterface.
GetExternalPosition will return a recent count of the number of
audio frames presented/received to/from an external observer. Using
the new API can return a precise timestamp to client, which can
help on A/V sync.
Test: atest AAudioTests
Bug: 158609200
Change-Id: If74e1d859a2bb2b4dba6af0e4e9164f05d19d962
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index 04c6453..5bccfd5 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -378,3 +378,18 @@
parcelable.mDownDataQueueParcelable.setCapacityInFrames(getBufferCapacity());
return AAUDIO_OK;
}
+
+aaudio_result_t AAudioServiceEndpointMMAP::getExternalPosition(uint64_t *positionFrames,
+ int64_t *timeNanos)
+{
+ if (!mExternalPositionSupported) {
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ status_t status = mMmapStream->getExternalPosition(positionFrames, timeNanos);
+ if (status == INVALID_OPERATION) {
+ // getExternalPosition is not supported. Set mExternalPositionSupported as false
+ // so that the call will not go to the HAL next time.
+ mExternalPositionSupported = false;
+ }
+ return AAudioConvert_androidToAAudioResult(status);
+}
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.h b/services/oboeservice/AAudioServiceEndpointMMAP.h
index b6003b6..a2a0922 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.h
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.h
@@ -85,6 +85,8 @@
return mHardwareTimeOffsetNanos;
}
+ aaudio_result_t getExternalPosition(uint64_t *positionFrames, int64_t *timeNanos);
+
private:
MonotonicCounter mFramesTransferred;
@@ -101,6 +103,8 @@
int64_t mHardwareTimeOffsetNanos = 0; // TODO get from HAL
+ bool mExternalPositionSupported = true;
+
};
} /* namespace aaudio */
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp
index 54d7d06..a4c064e 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.cpp
+++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp
@@ -162,7 +162,8 @@
return result;
}
-// Get timestamp that was written by getFreeRunningPosition()
+// Get timestamp from presentation position.
+// If fails, get time stamp that was written by getFreeRunningPosition()
aaudio_result_t AAudioServiceStreamMMAP::getHardwareTimestamp(int64_t *positionFrames,
int64_t *timeNanos) {
@@ -174,8 +175,11 @@
sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP =
static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
- // TODO Get presentation timestamp from the HAL
- if (mAtomicStreamTimestamp.isValid()) {
+ uint64_t position;
+ if (serviceEndpointMMAP->getExternalPosition(&position, timeNanos) == AAUDIO_OK) {
+ *positionFrames = (int64_t) position;
+ return AAUDIO_OK;
+ } else if (mAtomicStreamTimestamp.isValid()) {
Timestamp timestamp = mAtomicStreamTimestamp.read();
*positionFrames = timestamp.getPosition();
*timeNanos = timestamp.getNanoseconds() + serviceEndpointMMAP->getHardwareTimeOffsetNanos();