Implement server side playback timestamps with 64 bit accuracy
Provide server timestamps if the HAL doesn't provide it.
Provide monotonic - boottime translation.
Integrate record timestamps and playback timestamps together.
Bug: 17472992
Bug: 22871200
Bug: 26400089
Bug: 26682703
Change-Id: If1974f94232fcce7ba0bbcdf63d9e54ed51918ff
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 1446d19..d31b8d3 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -141,6 +141,10 @@
FastMixerDumpState * const dumpState = (FastMixerDumpState *) mDumpState;
const size_t frameCount = current->mFrameCount;
+ // update boottime offset, in case it has changed
+ mTimestamp.mTimebaseOffset[ExtendedTimestamp::TIMEBASE_BOOTTIME] =
+ mBoottimeOffset.load();
+
// handle state change here, but since we want to diff the state,
// we're prepared for previous == &sInitial the first time through
unsigned previousTrackMask;
@@ -341,21 +345,23 @@
currentTrackMask &= ~(1 << i);
const FastTrack* fastTrack = ¤t->mFastTracks[i];
- // Refresh the per-track timestamp
- if (mTimestampStatus == NO_ERROR) {
- uint32_t trackFramesWrittenButNotPresented =
- mNativeFramesWrittenButNotPresented;
- uint32_t trackFramesWritten = fastTrack->mBufferProvider->framesReleased();
- // Can't provide an AudioTimestamp before first frame presented,
- // or during the brief 32-bit wraparound window
- if (trackFramesWritten >= trackFramesWrittenButNotPresented) {
- AudioTimestamp perTrackTimestamp;
- perTrackTimestamp.mPosition =
- trackFramesWritten - trackFramesWrittenButNotPresented;
- perTrackTimestamp.mTime = mTimestamp.mTime;
- fastTrack->mBufferProvider->onTimestamp(perTrackTimestamp);
- }
+ const int64_t trackFramesWrittenButNotPresented =
+ mNativeFramesWrittenButNotPresented;
+ const int64_t trackFramesWritten = fastTrack->mBufferProvider->framesReleased();
+ ExtendedTimestamp perTrackTimestamp(mTimestamp);
+
+ // Can't provide an ExtendedTimestamp before first frame presented.
+ // Also, timestamp may not go to very last frame on stop().
+ if (trackFramesWritten >= trackFramesWrittenButNotPresented &&
+ perTrackTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] > 0) {
+ perTrackTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] =
+ trackFramesWritten - trackFramesWrittenButNotPresented;
+ } else {
+ perTrackTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = 0;
+ perTrackTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = -1;
}
+ perTrackTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = trackFramesWritten;
+ fastTrack->mBufferProvider->onTimestamp(perTrackTimestamp);
int name = mFastTrackNames[i];
ALOG_ASSERT(name >= 0);
@@ -449,17 +455,34 @@
mAttemptedWrite = true;
// FIXME count # of writes blocked excessively, CPU usage, etc. for dump
- mTimestampStatus = mOutputSink->getTimestamp(mTimestamp);
- if (mTimestampStatus == NO_ERROR) {
- uint32_t totalNativeFramesPresented = mTimestamp.mPosition;
+ ExtendedTimestamp timestamp; // local
+ status_t status = mOutputSink->getTimestamp(timestamp);
+ if (status == NO_ERROR) {
+ const int64_t totalNativeFramesPresented =
+ timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
if (totalNativeFramesPresented <= mTotalNativeFramesWritten) {
mNativeFramesWrittenButNotPresented =
mTotalNativeFramesWritten - totalNativeFramesPresented;
+ mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] =
+ timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
+ mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] =
+ timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];
} else {
// HAL reported that more frames were presented than were written
- mTimestampStatus = INVALID_OPERATION;
+ mNativeFramesWrittenButNotPresented = 0;
+ mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = 0;
+ mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = -1;
+ status = INVALID_OPERATION;
}
}
+ if (status == NO_ERROR) {
+ mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] =
+ mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];
+ } else {
+ // fetch server time if we can't get timestamp
+ mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] =
+ systemTime(SYSTEM_TIME_MONOTONIC);
+ }
}
}