summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/FastMixer.cpp
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2013-09-03 16:11:24 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2013-09-03 16:11:24 -0700
commitb9258d930d67fc314373f94ab4423974e5f87e1a (patch)
treeb1ff07dab920a778fe73ecc6b6e8d2ac9c198e47 /services/audioflinger/FastMixer.cpp
parent1462a2b84a578b5541683c824e0f77ebf2aa82ae (diff)
parent97992cc71fd0bbd4aa22e5195ee7e5cde09ac254 (diff)
downloadframeworks_av-b9258d930d67fc314373f94ab4423974e5f87e1a.zip
frameworks_av-b9258d930d67fc314373f94ab4423974e5f87e1a.tar.gz
frameworks_av-b9258d930d67fc314373f94ab4423974e5f87e1a.tar.bz2
am 97992cc7: am 732845c7: FastMixer computes presentation timestamps for fast tracks
* commit '97992cc71fd0bbd4aa22e5195ee7e5cde09ac254': FastMixer computes presentation timestamps for fast tracks
Diffstat (limited to 'services/audioflinger/FastMixer.cpp')
-rw-r--r--services/audioflinger/FastMixer.cpp47
1 files changed, 46 insertions, 1 deletions
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 4b36987..7126e92 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -96,6 +96,12 @@ bool FastMixer::threadLoop()
uint32_t warmupCycles = 0; // counter of number of loop cycles required to warmup
NBAIO_Sink* teeSink = NULL; // if non-NULL, then duplicate write() to this non-blocking sink
NBLog::Writer dummyLogWriter, *logWriter = &dummyLogWriter;
+ uint32_t totalNativeFramesWritten = 0; // copied to dumpState->mFramesWritten
+
+ // next 2 fields are valid only when timestampStatus == NO_ERROR
+ AudioTimestamp timestamp;
+ uint32_t nativeFramesWrittenButNotPresented = 0; // the = 0 is to silence the compiler
+ status_t timestampStatus = INVALID_OPERATION;
for (;;) {
@@ -192,6 +198,7 @@ bool FastMixer::threadLoop()
full = false;
#endif
oldTsValid = !clock_gettime(CLOCK_MONOTONIC, &oldTs);
+ timestampStatus = INVALID_OPERATION;
} else {
sleepNs = FAST_HOT_IDLE_NS;
}
@@ -382,6 +389,31 @@ bool FastMixer::threadLoop()
i = __builtin_ctz(currentTrackMask);
currentTrackMask &= ~(1 << i);
const FastTrack* fastTrack = &current->mFastTracks[i];
+
+ // Refresh the per-track timestamp
+ if (timestampStatus == NO_ERROR) {
+ uint32_t trackFramesWrittenButNotPresented;
+ uint32_t trackSampleRate = fastTrack->mSampleRate;
+ // There is currently no sample rate conversion for fast tracks currently
+ if (trackSampleRate != 0 && trackSampleRate != sampleRate) {
+ trackFramesWrittenButNotPresented =
+ ((int64_t) nativeFramesWrittenButNotPresented * trackSampleRate) /
+ sampleRate;
+ } else {
+ trackFramesWrittenButNotPresented = nativeFramesWrittenButNotPresented;
+ }
+ 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 = timestamp.mTime;
+ fastTrack->mBufferProvider->onTimestamp(perTrackTimestamp);
+ }
+ }
+
int name = fastTrackNames[i];
ALOG_ASSERT(name >= 0);
if (fastTrack->mVolumeProvider != NULL) {
@@ -456,7 +488,8 @@ bool FastMixer::threadLoop()
dumpState->mWriteSequence++;
if (framesWritten >= 0) {
ALOG_ASSERT((size_t) framesWritten <= frameCount);
- dumpState->mFramesWritten += framesWritten;
+ totalNativeFramesWritten += framesWritten;
+ dumpState->mFramesWritten = totalNativeFramesWritten;
//if ((size_t) framesWritten == frameCount) {
// didFullWrite = true;
//}
@@ -465,6 +498,18 @@ bool FastMixer::threadLoop()
}
attemptedWrite = true;
// FIXME count # of writes blocked excessively, CPU usage, etc. for dump
+
+ timestampStatus = outputSink->getTimestamp(timestamp);
+ if (timestampStatus == NO_ERROR) {
+ uint32_t totalNativeFramesPresented = timestamp.mPosition;
+ if (totalNativeFramesPresented <= totalNativeFramesWritten) {
+ nativeFramesWrittenButNotPresented =
+ totalNativeFramesWritten - totalNativeFramesPresented;
+ } else {
+ // HAL reported that more frames were presented than were written
+ timestampStatus = INVALID_OPERATION;
+ }
+ }
}
// To be exactly periodic, compute the next sleep time based on current time.