AudioTrack: Add getUnderrunCount()
This allows an app to detect application-level output glitches.
Underrun counts survive track recreation.
Change-Id: I8eb14e92f6fc1007718a29b0666ab51ace30cdb8
Bug: 25641253
Signed-off-by: Phil Burk <philburk@google.com>
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 5e14940..31e88c3 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -493,6 +493,7 @@
mPreviousTimestampValid = false;
mTimestampStartupGlitchReported = false;
mRetrogradeMotionReported = false;
+ mUnderrunCountOffset = 0;
return NO_ERROR;
}
@@ -2112,6 +2113,9 @@
return DEAD_OBJECT;
}
+ // Save so we can return count since creation.
+ mUnderrunCountOffset = getUnderrunCount_l();
+
// save the old static buffer position
size_t bufferPosition = 0;
int loopCount = 0;
@@ -2427,6 +2431,17 @@
return NO_ERROR;
}
+uint32_t AudioTrack::getUnderrunCount() const
+{
+ AutoMutex lock(mLock);
+ return getUnderrunCount_l();
+}
+
+uint32_t AudioTrack::getUnderrunCount_l() const
+{
+ return mProxy->getUnderrunCount() + mUnderrunCountOffset;
+}
+
uint32_t AudioTrack::getUnderrunFrames() const
{
AutoMutex lock(mLock);
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index 9fad500..716a614 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -781,10 +781,25 @@
void AudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount)
{
audio_track_cblk_t* cblk = mCblk;
- cblk->u.mStreaming.mUnderrunFrames += frameCount;
+ if (frameCount > 0) {
+ cblk->u.mStreaming.mUnderrunFrames += frameCount;
- // FIXME also wake futex so that underrun is noticed more quickly
- (void) android_atomic_or(CBLK_UNDERRUN, &cblk->mFlags);
+ if (!mUnderrunning) { // start of underrun?
+ mUnderrunCount++;
+ cblk->u.mStreaming.mUnderrunCount = mUnderrunCount;
+ mUnderrunning = true;
+ ALOGV("tallyUnderrunFrames(%3u) at uf = %u, bump mUnderrunCount = %u",
+ frameCount, cblk->u.mStreaming.mUnderrunFrames, mUnderrunCount);
+ }
+
+ // FIXME also wake futex so that underrun is noticed more quickly
+ (void) android_atomic_or(CBLK_UNDERRUN, &cblk->mFlags);
+ } else {
+ ALOGV_IF(mUnderrunning,
+ "tallyUnderrunFrames(%3u) at uf = %u, underrun finished",
+ frameCount, cblk->u.mStreaming.mUnderrunFrames);
+ mUnderrunning = false; // so we can detect the next edge
+ }
}
AudioPlaybackRate AudioTrackServerProxy::getPlaybackRate()
@@ -1010,7 +1025,7 @@
buffer->mNonContig = 0;
}
-void StaticAudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount __unused)
+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
@@ -1018,7 +1033,9 @@
// 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);
+ if (frameCount > 0) {
+ (void) android_atomic_or(CBLK_UNDERRUN, &mCblk->mFlags);
+ }
}
// ---------------------------------------------------------------------------