diff options
author | Glenn Kasten <gkasten@google.com> | 2013-09-03 16:11:24 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-09-03 16:11:24 -0700 |
commit | b9258d930d67fc314373f94ab4423974e5f87e1a (patch) | |
tree | b1ff07dab920a778fe73ecc6b6e8d2ac9c198e47 /services | |
parent | 1462a2b84a578b5541683c824e0f77ebf2aa82ae (diff) | |
parent | 97992cc71fd0bbd4aa22e5195ee7e5cde09ac254 (diff) | |
download | frameworks_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')
-rw-r--r-- | services/audioflinger/FastMixer.cpp | 47 |
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 = ¤t->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. |