Loading include/private/media/AudioTrackShared.h +9 −0 Original line number Diff line number Diff line Loading @@ -415,6 +415,13 @@ public: virtual void framesReadyIsCalledByMultipleThreads() { } bool setStreamEndDone(); // and return previous value // Add to the tally of underrun frames, and inform client of underrun virtual void tallyUnderrunFrames(uint32_t frameCount); // 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; } }; class StaticAudioTrackServerProxy : public AudioTrackServerProxy { Loading @@ -429,6 +436,8 @@ public: virtual void framesReadyIsCalledByMultipleThreads(); virtual status_t obtainBuffer(Buffer* buffer); virtual void releaseBuffer(Buffer* buffer); virtual void tallyUnderrunFrames(uint32_t frameCount); virtual uint32_t getUnderrunFrames() const { return 0; } private: ssize_t pollPosition(); // poll for state queue update, and return current position Loading media/libmedia/AudioTrackShared.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -661,6 +661,14 @@ bool AudioTrackServerProxy::setStreamEndDone() { return old; } void AudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount) { mCblk->u.mStreaming.mUnderrunFrames += frameCount; // FIXME also wake futex so that underrun is noticed more quickly (void) android_atomic_or(CBLK_UNDERRUN, &mCblk->mFlags); } // --------------------------------------------------------------------------- StaticAudioTrackServerProxy::StaticAudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, Loading Loading @@ -817,6 +825,17 @@ void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer) buffer->mNonContig = 0; } void StaticAudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount) { // Unlike AudioTrackServerProxy::tallyUnderrunFrames() used for streaming tracks, // we don't have a location to count underrun frames. The underrun frame counter // only exists in AudioTrackSharedStreaming. Fortunately, underruns are not // possible for static buffer tracks other than at end of buffer, so this is not a loss. // FIXME also wake futex so that underrun is noticed more quickly (void) android_atomic_or(CBLK_UNDERRUN, &mCblk->mFlags); } // --------------------------------------------------------------------------- } // namespace android services/audioflinger/PlaybackTracks.h +0 −1 Original line number Diff line number Diff line Loading @@ -140,7 +140,6 @@ private: // but the slot is only used if track is active FastTrackUnderruns mObservedUnderruns; // Most recently observed value of // mFastMixerDumpState.mTracks[mFastIndex].mUnderruns uint32_t mUnderrunCount; // Counter of total number of underruns, never reset volatile float mCachedVolume; // combined master volume and stream type volume; // 'volatile' means accessed without lock or // barrier, but is read/written atomically Loading services/audioflinger/Threads.cpp +5 −8 Original line number Diff line number Diff line Loading @@ -2739,8 +2739,10 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac track->mObservedUnderruns = underruns; // don't count underruns that occur while stopping or pausing // or stopped which can occur when flush() is called while active if (!(track->isStopping() || track->isPausing() || track->isStopped())) { track->mUnderrunCount += recentUnderruns; if (!(track->isStopping() || track->isPausing() || track->isStopped()) && recentUnderruns > 0) { // FIXME fast mixer will pull & mix partial buffers, but we count as a full underrun track->mAudioTrackServerProxy->tallyUnderrunFrames(recentUnderruns * mFrameCount); } // This is similar to the state machine for normal tracks, Loading Loading @@ -3056,12 +3058,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac mixerStatus = MIXER_TRACKS_READY; } } else { // only implemented for normal tracks, not fast tracks if (framesReady < desiredFrames && !track->isStopped() && !track->isPaused()) { // we missed desiredFrames whatever the actual number of frames missing was cblk->u.mStreaming.mUnderrunFrames += desiredFrames; // FIXME also wake futex so that underrun is noticed more quickly (void) android_atomic_or(CBLK_UNDERRUN, &cblk->mFlags); track->mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames); } // clear effect chain input buffer if an active track underruns to avoid sending // previous audio buffer again to effects Loading @@ -3086,7 +3084,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac tracksToRemove->add(track); } } else { track->mUnderrunCount++; // No buffers for this track. Give it a few chances to // fill a buffer, then remove it from active list. if (--(track->mRetryCount) <= 0) { Loading services/audioflinger/Tracks.cpp +3 −7 Original line number Diff line number Diff line Loading @@ -316,7 +316,6 @@ AudioFlinger::PlaybackThread::Track::Track( mPresentationCompleteFrames(0), mFlags(flags), mFastIndex(-1), mUnderrunCount(0), mCachedVolume(1.0), mIsInvalid(false), mAudioTrackServerProxy(NULL), Loading Loading @@ -389,7 +388,7 @@ void AudioFlinger::PlaybackThread::Track::destroy() /*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result) { result.append(" Name Client Type Fmt Chn mask Session fCount S F SRate " "L dB R dB Server Main buf Aux Buf Flags Underruns\n"); "L dB R dB Server Main buf Aux Buf Flags UndFrmCnt\n"); } void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size) Loading Loading @@ -470,7 +469,7 @@ void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size) (int)mMainBuffer, (int)mAuxBuffer, mCblk->mFlags, mUnderrunCount, mAudioTrackServerProxy->getUnderrunFrames(), nowInUnderrun); } Loading @@ -489,10 +488,7 @@ status_t AudioFlinger::PlaybackThread::Track::getNextBuffer( buffer->frameCount = buf.mFrameCount; buffer->raw = buf.mRaw; if (buf.mFrameCount == 0) { // only implemented so far for normal tracks, not fast tracks mCblk->u.mStreaming.mUnderrunFrames += desiredFrames; // FIXME also wake futex so that underrun is noticed more quickly (void) android_atomic_or(CBLK_UNDERRUN, &mCblk->mFlags); mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames); } return status; } Loading Loading
include/private/media/AudioTrackShared.h +9 −0 Original line number Diff line number Diff line Loading @@ -415,6 +415,13 @@ public: virtual void framesReadyIsCalledByMultipleThreads() { } bool setStreamEndDone(); // and return previous value // Add to the tally of underrun frames, and inform client of underrun virtual void tallyUnderrunFrames(uint32_t frameCount); // 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; } }; class StaticAudioTrackServerProxy : public AudioTrackServerProxy { Loading @@ -429,6 +436,8 @@ public: virtual void framesReadyIsCalledByMultipleThreads(); virtual status_t obtainBuffer(Buffer* buffer); virtual void releaseBuffer(Buffer* buffer); virtual void tallyUnderrunFrames(uint32_t frameCount); virtual uint32_t getUnderrunFrames() const { return 0; } private: ssize_t pollPosition(); // poll for state queue update, and return current position Loading
media/libmedia/AudioTrackShared.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -661,6 +661,14 @@ bool AudioTrackServerProxy::setStreamEndDone() { return old; } void AudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount) { mCblk->u.mStreaming.mUnderrunFrames += frameCount; // FIXME also wake futex so that underrun is noticed more quickly (void) android_atomic_or(CBLK_UNDERRUN, &mCblk->mFlags); } // --------------------------------------------------------------------------- StaticAudioTrackServerProxy::StaticAudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, Loading Loading @@ -817,6 +825,17 @@ void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer) buffer->mNonContig = 0; } void StaticAudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount) { // Unlike AudioTrackServerProxy::tallyUnderrunFrames() used for streaming tracks, // we don't have a location to count underrun frames. The underrun frame counter // only exists in AudioTrackSharedStreaming. Fortunately, underruns are not // possible for static buffer tracks other than at end of buffer, so this is not a loss. // FIXME also wake futex so that underrun is noticed more quickly (void) android_atomic_or(CBLK_UNDERRUN, &mCblk->mFlags); } // --------------------------------------------------------------------------- } // namespace android
services/audioflinger/PlaybackTracks.h +0 −1 Original line number Diff line number Diff line Loading @@ -140,7 +140,6 @@ private: // but the slot is only used if track is active FastTrackUnderruns mObservedUnderruns; // Most recently observed value of // mFastMixerDumpState.mTracks[mFastIndex].mUnderruns uint32_t mUnderrunCount; // Counter of total number of underruns, never reset volatile float mCachedVolume; // combined master volume and stream type volume; // 'volatile' means accessed without lock or // barrier, but is read/written atomically Loading
services/audioflinger/Threads.cpp +5 −8 Original line number Diff line number Diff line Loading @@ -2739,8 +2739,10 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac track->mObservedUnderruns = underruns; // don't count underruns that occur while stopping or pausing // or stopped which can occur when flush() is called while active if (!(track->isStopping() || track->isPausing() || track->isStopped())) { track->mUnderrunCount += recentUnderruns; if (!(track->isStopping() || track->isPausing() || track->isStopped()) && recentUnderruns > 0) { // FIXME fast mixer will pull & mix partial buffers, but we count as a full underrun track->mAudioTrackServerProxy->tallyUnderrunFrames(recentUnderruns * mFrameCount); } // This is similar to the state machine for normal tracks, Loading Loading @@ -3056,12 +3058,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac mixerStatus = MIXER_TRACKS_READY; } } else { // only implemented for normal tracks, not fast tracks if (framesReady < desiredFrames && !track->isStopped() && !track->isPaused()) { // we missed desiredFrames whatever the actual number of frames missing was cblk->u.mStreaming.mUnderrunFrames += desiredFrames; // FIXME also wake futex so that underrun is noticed more quickly (void) android_atomic_or(CBLK_UNDERRUN, &cblk->mFlags); track->mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames); } // clear effect chain input buffer if an active track underruns to avoid sending // previous audio buffer again to effects Loading @@ -3086,7 +3084,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac tracksToRemove->add(track); } } else { track->mUnderrunCount++; // No buffers for this track. Give it a few chances to // fill a buffer, then remove it from active list. if (--(track->mRetryCount) <= 0) { Loading
services/audioflinger/Tracks.cpp +3 −7 Original line number Diff line number Diff line Loading @@ -316,7 +316,6 @@ AudioFlinger::PlaybackThread::Track::Track( mPresentationCompleteFrames(0), mFlags(flags), mFastIndex(-1), mUnderrunCount(0), mCachedVolume(1.0), mIsInvalid(false), mAudioTrackServerProxy(NULL), Loading Loading @@ -389,7 +388,7 @@ void AudioFlinger::PlaybackThread::Track::destroy() /*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result) { result.append(" Name Client Type Fmt Chn mask Session fCount S F SRate " "L dB R dB Server Main buf Aux Buf Flags Underruns\n"); "L dB R dB Server Main buf Aux Buf Flags UndFrmCnt\n"); } void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size) Loading Loading @@ -470,7 +469,7 @@ void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size) (int)mMainBuffer, (int)mAuxBuffer, mCblk->mFlags, mUnderrunCount, mAudioTrackServerProxy->getUnderrunFrames(), nowInUnderrun); } Loading @@ -489,10 +488,7 @@ status_t AudioFlinger::PlaybackThread::Track::getNextBuffer( buffer->frameCount = buf.mFrameCount; buffer->raw = buf.mRaw; if (buf.mFrameCount == 0) { // only implemented so far for normal tracks, not fast tracks mCblk->u.mStreaming.mUnderrunFrames += desiredFrames; // FIXME also wake futex so that underrun is noticed more quickly (void) android_atomic_or(CBLK_UNDERRUN, &mCblk->mFlags); mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames); } return status; } Loading