Add AudioRecord timestamps
Bug: 13569372
Bug: 22886739
Change-Id: Ibc81afefb733d23676a632a0f2da31163fdbe05f
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 1c0d904..ec57d96 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -284,6 +284,8 @@
mSequence = 1;
mObservedSequence = mSequence;
mInOverrun = false;
+ mFramesRead = 0;
+ mFramesReadServerOffset = 0;
return NO_ERROR;
}
@@ -299,6 +301,12 @@
return NO_ERROR;
}
+ // discard data in buffer
+ const uint32_t framesFlushed = mProxy->flush();
+ mFramesReadServerOffset -= mFramesRead + framesFlushed;
+ mFramesRead = 0;
+ mProxy->clearTimestamp(); // timestamp is invalid until next server push
+
// reset current position as seen by client to 0
mProxy->setEpoch(mProxy->getEpoch() - mProxy->getPosition());
// force refresh of remaining frames by processAudioBuffer() as last
@@ -449,6 +457,27 @@
return AudioSystem::getInputFramesLost(getInputPrivate());
}
+status_t AudioRecord::getTimestamp(ExtendedTimestamp *timestamp)
+{
+ if (timestamp == nullptr) {
+ return BAD_VALUE;
+ }
+ AutoMutex lock(mLock);
+ status_t status = mProxy->getTimestamp(timestamp);
+ if (status == OK) {
+ timestamp->mPosition[ExtendedTimestamp::LOCATION_CLIENT] = mFramesRead;
+ timestamp->mTimeNs[ExtendedTimestamp::LOCATION_CLIENT] = 0;
+ // server side frame offset in case AudioRecord has been restored.
+ for (int i = ExtendedTimestamp::LOCATION_SERVER;
+ i < ExtendedTimestamp::LOCATION_MAX; ++i) {
+ if (timestamp->mTimeNs[i] >= 0) {
+ timestamp->mPosition[i] += mFramesReadServerOffset;
+ }
+ }
+ }
+ return status;
+}
+
// ---- Explicit Routing ---------------------------------------------------
status_t AudioRecord::setInputDevice(audio_port_handle_t deviceId) {
AutoMutex lock(mLock);
@@ -837,7 +866,10 @@
releaseBuffer(&audioBuffer);
}
-
+ if (read > 0) {
+ mFramesRead += read / mFrameSize;
+ // mFramesReadTime = systemTime(SYSTEM_TIME_MONOTONIC); // not provided at this time.
+ }
return read;
}
@@ -988,6 +1020,7 @@
requested = &timeout;
}
+ size_t readFrames = 0;
while (mRemainingFrames > 0) {
Buffer audioBuffer;
@@ -1049,6 +1082,7 @@
}
releaseBuffer(&audioBuffer);
+ readFrames += releasedFrames;
// FIXME here is where we would repeat EVENT_MORE_DATA again on same advanced buffer
// if callback doesn't like to accept the full chunk
@@ -1072,6 +1106,11 @@
#endif
}
+ if (readFrames > 0) {
+ AutoMutex lock(mLock);
+ mFramesRead += readFrames;
+ // mFramesReadTime = systemTime(SYSTEM_TIME_MONOTONIC); // not provided at this time.
+ }
mRemainingFrames = notificationFrames;
mRetryOnPartialBuffer = true;
@@ -1096,6 +1135,7 @@
// FIXME this fails if we have a new AudioFlinger instance
result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
}
+ mFramesReadServerOffset = mFramesRead; // server resets to zero so we need an offset.
}
if (result != NO_ERROR) {
ALOGW("restoreRecord_l() failed status %d", result);
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index d75ad87..988386e 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -597,7 +597,7 @@
ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
size_t frameSize, bool isOut, bool clientInServer)
: Proxy(cblk, buffers, frameCount, frameSize, isOut, clientInServer),
- mAvailToClient(0), mFlush(0)
+ mAvailToClient(0), mFlush(0), mReleased(0)
{
}
@@ -733,6 +733,7 @@
}
cblk->mServer += stepCount;
+ mReleased += stepCount;
size_t half = mFrameCount / 2;
if (half == 0) {
@@ -1033,6 +1034,8 @@
mFramesReadySafe = clampToSize(mFramesReady);
cblk->mServer += stepCount;
+ mReleased += stepCount;
+
// This may overflow, but client is not supposed to rely on it
StaticAudioTrackPosLoop posLoop;
posLoop.mBufferPosition = mState.mPosition;