Implement client playback timestamps with 64 bit accuracy
Provide server timestamps if the HAL doesn't provide it.
Provide monotonic - boottime translation.
Bug: 17472992
Bug: 26682703
Bug: 27749434
Change-Id: I6c9b213d9f9284092e34d57f52870e02c72df62a
diff --git a/include/media/AudioTimestamp.h b/include/media/AudioTimestamp.h
index 531b548..969003c 100644
--- a/include/media/AudioTimestamp.h
+++ b/include/media/AudioTimestamp.h
@@ -69,12 +69,23 @@
// or NTP adjustment.
int64_t mTimebaseOffset[TIMEBASE_MAX];
+ // Playback only:
+ // mFlushed is number of flushed frames before entering the server mix;
+ // hence not included in mPosition. This is used for adjusting server positions
+ // information for frames "dropped".
+ // FIXME: This variable should be eliminated, with the offset added on the server side
+ // before sending to client, but differences in legacy position offset handling
+ // and new extended timestamps require this to be maintained as a separate quantity.
+ int64_t mFlushed;
+
+ // Call to reset the timestamp to the original (invalid) state
void clear() {
memset(mPosition, 0, sizeof(mPosition)); // actually not necessary if time is -1
for (int i = 0; i < LOCATION_MAX; ++i) {
mTimeNs[i] = -1;
}
memset(mTimebaseOffset, 0, sizeof(mTimebaseOffset));
+ mFlushed = 0;
}
// Returns the best timestamp as judged from the closest-to-hw stage in the
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index bdd6372..b96a450 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -727,12 +727,51 @@
* because the audio device changed or AudioFlinger died.
* This typically occurs for direct or offload tracks
* or if mDoNotReconnect is true.
- * INVALID_OPERATION if called on a FastTrack, wrong state, or some other error.
+ * INVALID_OPERATION wrong state, or some other error.
*
* The timestamp parameter is undefined on return, if status is not NO_ERROR.
*/
status_t getTimestamp(AudioTimestamp& timestamp);
+ /* Return the extended timestamp, with additional timebase info and improved drain behavior.
+ *
+ * This is similar to the AudioTrack.java API:
+ * getTimestamp(@NonNull AudioTimestamp timestamp, @AudioTimestamp.Timebase int timebase)
+ *
+ * Some differences between this method and the getTimestamp(AudioTimestamp& timestamp) method
+ *
+ * 1. stop() by itself does not reset the frame position.
+ * A following start() resets the frame position to 0.
+ * 2. flush() by itself does not reset the frame position.
+ * The frame position advances by the number of frames flushed,
+ * when the first frame after flush reaches the audio sink.
+ * 3. BOOTTIME clock offsets are provided to help synchronize with
+ * non-audio streams, e.g. sensor data.
+ * 4. Position is returned with 64 bits of resolution.
+ *
+ * Parameters:
+ * timestamp: A pointer to the caller allocated ExtendedTimestamp.
+ *
+ * Returns NO_ERROR on success; timestamp is filled with valid data.
+ * BAD_VALUE if timestamp is NULL.
+ * WOULD_BLOCK if called immediately after start() when the number
+ * of frames consumed is less than the
+ * overall hardware latency to physical output. In WOULD_BLOCK cases,
+ * one might poll again, or use getPosition(), or use 0 position and
+ * current time for the timestamp.
+ * If WOULD_BLOCK is returned, the timestamp is still
+ * modified with the LOCATION_CLIENT portion filled.
+ * DEAD_OBJECT if AudioFlinger dies or the output device changes and
+ * the track cannot be automatically restored.
+ * The application needs to recreate the AudioTrack
+ * because the audio device changed or AudioFlinger died.
+ * This typically occurs for direct or offloaded tracks
+ * or if mDoNotReconnect is true.
+ * INVALID_OPERATION if called on a offloaded or direct track.
+ * Use getTimestamp(AudioTimestamp& timestamp) instead.
+ */
+ status_t getTimestamp(ExtendedTimestamp *timestamp);
+
/* Add an AudioDeviceCallback. The caller will be notified when the audio device to which this
* AudioTrack is routed is updated.
* Replaces any previously installed callback.
@@ -956,6 +995,13 @@
uint32_t mUnderrunCountOffset; // updated when restoring tracks
+ int64_t mFramesWritten; // total frames written. reset to zero after
+ // the start() following stop(). It is not
+ // changed after restoring the track or
+ // after flush.
+ int64_t mFramesWrittenServerOffset; // An offset to server frames due to
+ // restoring AudioTrack, or stop/start.
+
audio_output_flags_t mFlags; // same as mOrigFlags, except for bits that may
// be denied by client or server, such as
// AUDIO_OUTPUT_FLAG_FAST. mLock must be
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 92cf6bb..ffdb9b5 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -522,6 +522,9 @@
mTimestampMutator.push(timestamp);
}
+ // Total count of the number of flushed frames since creation (never reset).
+ virtual int64_t framesFlushed() const { return mFlushed; }
+
// Get dynamic buffer size from the shared control block.
uint32_t getBufferSizeInFrames() const {
return android_atomic_acquire_load((int32_t *)&mCblk->mBufferSizeInFrames);
@@ -531,7 +534,7 @@
size_t mAvailToClient; // estimated frames available to client prior to releaseBuffer()
int32_t mFlush; // our copy of cblk->u.mStreaming.mFlush, for streaming output only
int64_t mReleased; // our copy of cblk->mServer, at 64 bit resolution
-
+ int64_t mFlushed; // flushed frames to account for client-server discrepancy
ExtendedTimestampQueue::Mutator mTimestampMutator;
};