summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/private/media/AudioTrackShared.h9
-rw-r--r--media/libmedia/AudioTrackShared.cpp19
-rw-r--r--services/audioflinger/PlaybackTracks.h1
-rw-r--r--services/audioflinger/Threads.cpp13
-rw-r--r--services/audioflinger/Tracks.cpp10
5 files changed, 36 insertions, 16 deletions
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 6d778dd..1379379 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -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 {
@@ -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
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index 3b7616f..e7abb40 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -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,
@@ -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
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 628f5af..5600411c 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -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
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d9c312e..0c1cc35 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -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,
@@ -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
@@ -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) {
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 1f75468..e676365 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -316,7 +316,6 @@ AudioFlinger::PlaybackThread::Track::Track(
mPresentationCompleteFrames(0),
mFlags(flags),
mFastIndex(-1),
- mUnderrunCount(0),
mCachedVolume(1.0),
mIsInvalid(false),
mAudioTrackServerProxy(NULL),
@@ -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)
@@ -470,7 +469,7 @@ void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
(int)mMainBuffer,
(int)mAuxBuffer,
mCblk->mFlags,
- mUnderrunCount,
+ mAudioTrackServerProxy->getUnderrunFrames(),
nowInUnderrun);
}
@@ -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;
}