diff options
author | Glenn Kasten <gkasten@google.com> | 2013-08-29 17:12:45 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-08-29 17:12:45 -0700 |
commit | f557872b594d15599bdb65efd91eb5adeb1d0840 (patch) | |
tree | 8df16a0c49bac71163035d11562e06bcc12a2490 | |
parent | 30c296c153447f5c2bb5251928bf4d3c4e28e552 (diff) | |
parent | 908d3c09ca7f2ccb280aa5dc8d876099ff9a9d0f (diff) | |
download | frameworks_av-f557872b594d15599bdb65efd91eb5adeb1d0840.zip frameworks_av-f557872b594d15599bdb65efd91eb5adeb1d0840.tar.gz frameworks_av-f557872b594d15599bdb65efd91eb5adeb1d0840.tar.bz2 |
am 908d3c09: am 51ec03c2: Merge "Implement Track::getTimestamp()" into klp-dev
* commit '908d3c09ca7f2ccb280aa5dc8d876099ff9a9d0f':
Implement Track::getTimestamp()
-rw-r--r-- | include/private/media/AudioTrackShared.h | 3 | ||||
-rw-r--r-- | services/audioflinger/Threads.cpp | 18 | ||||
-rw-r--r-- | services/audioflinger/Threads.h | 11 | ||||
-rw-r--r-- | services/audioflinger/Tracks.cpp | 14 |
4 files changed, 44 insertions, 2 deletions
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h index ad00c6d..d6e7ac4 100644 --- a/include/private/media/AudioTrackShared.h +++ b/include/private/media/AudioTrackShared.h @@ -422,6 +422,9 @@ public: // Return the total number of frames which AudioFlinger desired but were unavailable, // and thus which resulted in an underrun. virtual uint32_t getUnderrunFrames() const { return mCblk->u.mStreaming.mUnderrunFrames; } + + // Return the total number of frames that AudioFlinger has obtained and released + virtual size_t framesReleased() const { return mCblk->mServer; } }; class StaticAudioTrackServerProxy : public AudioTrackServerProxy { diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 8bc70ba..99d0ac2 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -958,7 +958,9 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge mDraining(false), mScreenState(AudioFlinger::mScreenState), // index 0 is reserved for normal mixer's submix - mFastTrackAvailMask(((1 << FastMixerState::kMaxFastTracks) - 1) & ~1) + mFastTrackAvailMask(((1 << FastMixerState::kMaxFastTracks) - 1) & ~1), + // mLatchD, mLatchQ, + mLatchDValid(false), mLatchQValid(false) { snprintf(mName, kNameLength, "AudioOut_%X", id); mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mName); @@ -1826,6 +1828,14 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write() } else { bytesWritten = framesWritten; } + status_t status = INVALID_OPERATION; // mLatchD.mTimestamp is invalid + if (status == NO_ERROR) { + size_t totalFramesWritten = mNormalSink->framesWritten(); + if (totalFramesWritten >= mLatchD.mTimestamp.mPosition) { + mLatchD.mUnpresentedFrames = totalFramesWritten - mLatchD.mTimestamp.mPosition; + mLatchDValid = true; + } + } // otherwise use the HAL / AudioStreamOut directly } else { // Direct output and offload threads @@ -2104,6 +2114,12 @@ bool AudioFlinger::PlaybackThread::threadLoop() logString = NULL; } + if (mLatchDValid) { + mLatchQ = mLatchD; + mLatchDValid = false; + mLatchQValid = true; + } + if (checkForNewParameters_l()) { cacheParameters_l(); } diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index 176314a..15278ce 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -608,6 +608,17 @@ protected: // accessed by both binder threads and within threadLoop(), lock on mutex needed unsigned mFastTrackAvailMask; // bit i set if fast track [i] is available virtual void flushOutput_l(); + +private: + // timestamp latch: + // D input is written by threadLoop_write while mutex is unlocked, and read while locked + // Q output is written while locked, and read while locked + struct { + AudioTimestamp mTimestamp; + uint32_t mUnpresentedFrames; + } mLatchD, mLatchQ; + bool mLatchDValid; // true means mLatchD is valid, and clock it into latch at next opportunity + bool mLatchQValid; // true means mLatchQ is valid }; class MixerThread : public PlaybackThread { diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp index 392707b..690f1dd 100644 --- a/services/audioflinger/Tracks.cpp +++ b/services/audioflinger/Tracks.cpp @@ -733,7 +733,19 @@ status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& times } Mutex::Autolock _l(thread->mLock); PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); - return INVALID_OPERATION; + if (!playbackThread->mLatchQValid) { + return INVALID_OPERATION; + } + uint32_t unpresentedFrames = + ((int64_t) playbackThread->mLatchQ.mUnpresentedFrames * mSampleRate) / + playbackThread->mSampleRate; + uint32_t framesWritten = mAudioTrackServerProxy->framesReleased(); + if (framesWritten < unpresentedFrames) { + return INVALID_OPERATION; + } + timestamp.mPosition = framesWritten - unpresentedFrames; + timestamp.mTime = playbackThread->mLatchQ.mTimestamp.mTime; + return NO_ERROR; } status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId) |