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/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 2db902d..9885655 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -684,6 +684,7 @@
virtual status_t createMmapBuffer(int32_t minSizeFrames,
struct audio_mmap_buffer_info *info);
virtual status_t getMmapPosition(struct audio_mmap_position *position);
+ virtual status_t getExternalPosition(uint64_t *position, int64_t *timeNanos);
virtual status_t start(const AudioClient& client,
const audio_attributes_t *attr,
audio_port_handle_t *handle);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 2a6aeac..59489ca 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -8742,6 +8742,11 @@
return mThread->getMmapPosition(position);
}
+status_t AudioFlinger::MmapThreadHandle::getExternalPosition(uint64_t *position,
+ int64_t *timeNanos) {
+ return mThread->getExternalPosition(position, timeNanos);
+}
+
status_t AudioFlinger::MmapThreadHandle::start(const AudioClient& client,
const audio_attributes_t *attr, audio_port_handle_t *handle)
@@ -9696,6 +9701,20 @@
}
}
+status_t AudioFlinger::MmapPlaybackThread::getExternalPosition(uint64_t *position,
+ int64_t *timeNanos)
+{
+ if (mOutput == nullptr) {
+ return NO_INIT;
+ }
+ struct timespec timestamp;
+ status_t status = mOutput->getPresentationPosition(position, ×tamp);
+ if (status == NO_ERROR) {
+ *timeNanos = timestamp.tv_sec * NANOS_PER_SECOND + timestamp.tv_nsec;
+ }
+ return status;
+}
+
void AudioFlinger::MmapPlaybackThread::dumpInternals_l(int fd, const Vector<String16>& args)
{
MmapThread::dumpInternals_l(fd, args);
@@ -9800,4 +9819,13 @@
}
}
+status_t AudioFlinger::MmapCaptureThread::getExternalPosition(
+ uint64_t *position, int64_t *timeNanos)
+{
+ if (mInput == nullptr) {
+ return NO_INIT;
+ }
+ return mInput->getCapturePosition((int64_t*)position, timeNanos);
+}
+
} // namespace android
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index d59b702..be92769 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1824,6 +1824,7 @@
audio_port_handle_t *handle);
status_t stop(audio_port_handle_t handle);
status_t standby();
+ virtual status_t getExternalPosition(uint64_t *position, int64_t *timeNaos) = 0;
// RefBase
virtual void onFirstRef();
@@ -1935,6 +1936,8 @@
virtual void toAudioPortConfig(struct audio_port_config *config);
+ status_t getExternalPosition(uint64_t *position, int64_t *timeNanos) override;
+
protected:
void dumpInternals_l(int fd, const Vector<String16>& args) override;
@@ -1965,6 +1968,8 @@
virtual void toAudioPortConfig(struct audio_port_config *config);
+ status_t getExternalPosition(uint64_t *position, int64_t *timeNanos) override;
+
protected:
AudioStreamIn* mInput;