Loading include/private/media/AudioTrackShared.h +35 −3 Original line number Diff line number Diff line Loading @@ -119,8 +119,11 @@ struct AudioTrackSharedStatic { typedef SingleStateQueue<AudioPlaybackRate> PlaybackRateQueue; typedef SingleStateQueue<ExtendedTimestamp> ExtendedTimestampQueue; typedef SingleStateQueue<AudioTimestamp> TimestampQueue; // ---------------------------------------------------------------------------- // Important: do not add any virtual methods, including ~ Loading Loading @@ -175,7 +178,9 @@ private: uint16_t mPad2; // unused // server write-only, client read ExtendedTimestampQueue::Shared mExtendedTimestampQueue; ExtendedTimestampQueue::Shared mExtendedTimestampQueue; // capture TimestampQueue::Shared mTimestampQueue; // playback public: volatile int32_t mFlags; // combinations of CBLK_* Loading Loading @@ -333,7 +338,10 @@ public: size_t frameSize, bool clientInServer = false) : ClientProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer), mPlaybackRateMutator(&cblk->mPlaybackRateQueue) { } mPlaybackRateMutator(&cblk->mPlaybackRateQueue), mTimestampObserver(&cblk->mTimestampQueue) { } virtual ~AudioTrackClientProxy() { } // No barriers on the following operations, so the ordering of loads/stores Loading @@ -357,6 +365,20 @@ public: mPlaybackRateMutator.push(playbackRate); } status_t getTimestamp(AudioTimestamp *timestamp) { if (timestamp == nullptr) { return BAD_VALUE; } (void) mTimestampObserver.poll(mTimestamp); // if no data is pushed by server, mTimestamp should be initialized by its constructor // to all zero elements. if (mTimestamp.mTime.tv_sec == 0 && mTimestamp.mTime.tv_nsec == 0) { return WOULD_BLOCK; } *timestamp = mTimestamp; return OK; } virtual void flush(); virtual uint32_t getUnderrunFrames() const { Loading @@ -374,6 +396,8 @@ public: private: PlaybackRateQueue::Mutator mPlaybackRateMutator; TimestampQueue::Observer mTimestampObserver; AudioTimestamp mTimestamp; }; class StaticAudioTrackClientProxy : public AudioTrackClientProxy { Loading Loading @@ -522,7 +546,8 @@ public: size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0) : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer), mPlaybackRateObserver(&cblk->mPlaybackRateQueue), mUnderrunCount(0), mUnderrunning(false) { mUnderrunCount(0), mUnderrunning(false), mTimestampMutator(&cblk->mTimestampQueue) { mCblk->mSampleRate = sampleRate; mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT; } Loading Loading @@ -562,6 +587,11 @@ public: // Return the playback speed and pitch read atomically. Not multi-thread safe on server side. AudioPlaybackRate getPlaybackRate(); // Expose timestamp to client proxy. Should only be called by a single thread. void setTimestamp(const AudioTimestamp ×tamp) { mTimestampMutator.push(timestamp); } private: AudioPlaybackRate mPlaybackRate; // last observed playback rate PlaybackRateQueue::Observer mPlaybackRateObserver; Loading @@ -569,6 +599,8 @@ private: // The server keeps a copy here where it is safe from the client. uint32_t mUnderrunCount; // echoed to mCblk bool mUnderrunning; // used to detect edge of underrun TimestampQueue::Mutator mTimestampMutator; }; class StaticAudioTrackServerProxy : public AudioTrackServerProxy { Loading media/libmedia/AudioTrack.cpp +4 −6 Original line number Diff line number Diff line Loading @@ -2167,11 +2167,6 @@ status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp) // Set false here to cover all the error return cases. mPreviousTimestampValid = false; // FIXME not implemented for fast tracks; should use proxy and SSQ if (mFlags & AUDIO_OUTPUT_FLAG_FAST) { return INVALID_OPERATION; } switch (mState) { case STATE_ACTIVE: case STATE_PAUSED: Loading Loading @@ -2201,7 +2196,10 @@ status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp) // The presented frame count must always lag behind the consumed frame count. // To avoid a race, read the presented frames first. This ensures that presented <= consumed. status_t status = mAudioTrack->getTimestamp(timestamp); // FastTrack timestamps are read through shared memory; otherwise use Binder. status_t status = (mFlags & AUDIO_OUTPUT_FLAG_FAST) ? mProxy->getTimestamp(×tamp) : mAudioTrack->getTimestamp(timestamp); if (status != NO_ERROR) { ALOGV_IF(status != WOULD_BLOCK, "getTimestamp error:%#x", status); return status; Loading services/audioflinger/PlaybackTracks.h +1 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ protected: // ExtendedAudioBufferProvider interface virtual size_t framesReady() const; virtual size_t framesReleased() const; virtual void onTimestamp(const AudioTimestamp ×tamp); bool isPausing() const { return mState == PAUSING; } bool isPaused() const { return mState == PAUSED; } Loading services/audioflinger/Tracks.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -589,6 +589,11 @@ size_t AudioFlinger::PlaybackThread::Track::framesReleased() const return mAudioTrackServerProxy->framesReleased(); } void AudioFlinger::PlaybackThread::Track::onTimestamp(const AudioTimestamp ×tamp) { mAudioTrackServerProxy->setTimestamp(timestamp); } // Don't call for fast tracks; the framesReady() could result in priority inversion bool AudioFlinger::PlaybackThread::Track::isReady() const { if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) { Loading Loading @@ -846,7 +851,7 @@ status_t AudioFlinger::PlaybackThread::Track::setParameters(const String8& keyVa status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp) { // Client should implement this using SSQ; the unpresented frame count in latch is irrelevant // FastTrack timestamps are read through SSQ if (isFastTrack()) { return INVALID_OPERATION; } Loading Loading
include/private/media/AudioTrackShared.h +35 −3 Original line number Diff line number Diff line Loading @@ -119,8 +119,11 @@ struct AudioTrackSharedStatic { typedef SingleStateQueue<AudioPlaybackRate> PlaybackRateQueue; typedef SingleStateQueue<ExtendedTimestamp> ExtendedTimestampQueue; typedef SingleStateQueue<AudioTimestamp> TimestampQueue; // ---------------------------------------------------------------------------- // Important: do not add any virtual methods, including ~ Loading Loading @@ -175,7 +178,9 @@ private: uint16_t mPad2; // unused // server write-only, client read ExtendedTimestampQueue::Shared mExtendedTimestampQueue; ExtendedTimestampQueue::Shared mExtendedTimestampQueue; // capture TimestampQueue::Shared mTimestampQueue; // playback public: volatile int32_t mFlags; // combinations of CBLK_* Loading Loading @@ -333,7 +338,10 @@ public: size_t frameSize, bool clientInServer = false) : ClientProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer), mPlaybackRateMutator(&cblk->mPlaybackRateQueue) { } mPlaybackRateMutator(&cblk->mPlaybackRateQueue), mTimestampObserver(&cblk->mTimestampQueue) { } virtual ~AudioTrackClientProxy() { } // No barriers on the following operations, so the ordering of loads/stores Loading @@ -357,6 +365,20 @@ public: mPlaybackRateMutator.push(playbackRate); } status_t getTimestamp(AudioTimestamp *timestamp) { if (timestamp == nullptr) { return BAD_VALUE; } (void) mTimestampObserver.poll(mTimestamp); // if no data is pushed by server, mTimestamp should be initialized by its constructor // to all zero elements. if (mTimestamp.mTime.tv_sec == 0 && mTimestamp.mTime.tv_nsec == 0) { return WOULD_BLOCK; } *timestamp = mTimestamp; return OK; } virtual void flush(); virtual uint32_t getUnderrunFrames() const { Loading @@ -374,6 +396,8 @@ public: private: PlaybackRateQueue::Mutator mPlaybackRateMutator; TimestampQueue::Observer mTimestampObserver; AudioTimestamp mTimestamp; }; class StaticAudioTrackClientProxy : public AudioTrackClientProxy { Loading Loading @@ -522,7 +546,8 @@ public: size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0) : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer), mPlaybackRateObserver(&cblk->mPlaybackRateQueue), mUnderrunCount(0), mUnderrunning(false) { mUnderrunCount(0), mUnderrunning(false), mTimestampMutator(&cblk->mTimestampQueue) { mCblk->mSampleRate = sampleRate; mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT; } Loading Loading @@ -562,6 +587,11 @@ public: // Return the playback speed and pitch read atomically. Not multi-thread safe on server side. AudioPlaybackRate getPlaybackRate(); // Expose timestamp to client proxy. Should only be called by a single thread. void setTimestamp(const AudioTimestamp ×tamp) { mTimestampMutator.push(timestamp); } private: AudioPlaybackRate mPlaybackRate; // last observed playback rate PlaybackRateQueue::Observer mPlaybackRateObserver; Loading @@ -569,6 +599,8 @@ private: // The server keeps a copy here where it is safe from the client. uint32_t mUnderrunCount; // echoed to mCblk bool mUnderrunning; // used to detect edge of underrun TimestampQueue::Mutator mTimestampMutator; }; class StaticAudioTrackServerProxy : public AudioTrackServerProxy { Loading
media/libmedia/AudioTrack.cpp +4 −6 Original line number Diff line number Diff line Loading @@ -2167,11 +2167,6 @@ status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp) // Set false here to cover all the error return cases. mPreviousTimestampValid = false; // FIXME not implemented for fast tracks; should use proxy and SSQ if (mFlags & AUDIO_OUTPUT_FLAG_FAST) { return INVALID_OPERATION; } switch (mState) { case STATE_ACTIVE: case STATE_PAUSED: Loading Loading @@ -2201,7 +2196,10 @@ status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp) // The presented frame count must always lag behind the consumed frame count. // To avoid a race, read the presented frames first. This ensures that presented <= consumed. status_t status = mAudioTrack->getTimestamp(timestamp); // FastTrack timestamps are read through shared memory; otherwise use Binder. status_t status = (mFlags & AUDIO_OUTPUT_FLAG_FAST) ? mProxy->getTimestamp(×tamp) : mAudioTrack->getTimestamp(timestamp); if (status != NO_ERROR) { ALOGV_IF(status != WOULD_BLOCK, "getTimestamp error:%#x", status); return status; Loading
services/audioflinger/PlaybackTracks.h +1 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ protected: // ExtendedAudioBufferProvider interface virtual size_t framesReady() const; virtual size_t framesReleased() const; virtual void onTimestamp(const AudioTimestamp ×tamp); bool isPausing() const { return mState == PAUSING; } bool isPaused() const { return mState == PAUSED; } Loading
services/audioflinger/Tracks.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -589,6 +589,11 @@ size_t AudioFlinger::PlaybackThread::Track::framesReleased() const return mAudioTrackServerProxy->framesReleased(); } void AudioFlinger::PlaybackThread::Track::onTimestamp(const AudioTimestamp ×tamp) { mAudioTrackServerProxy->setTimestamp(timestamp); } // Don't call for fast tracks; the framesReady() could result in priority inversion bool AudioFlinger::PlaybackThread::Track::isReady() const { if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) { Loading Loading @@ -846,7 +851,7 @@ status_t AudioFlinger::PlaybackThread::Track::setParameters(const String8& keyVa status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp) { // Client should implement this using SSQ; the unpresented frame count in latch is irrelevant // FastTrack timestamps are read through SSQ if (isFastTrack()) { return INVALID_OPERATION; } Loading