summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2010-09-30 16:12:31 -0700
committerEric Laurent <elaurent@google.com>2010-09-30 17:21:23 -0700
commit44d9848d6656777a18019223e0d35f2fcc67719a (patch)
treefe71003d3400dcbdfe078f8d8fad1b1fde960b2c /services
parent922855214d0e8ae4159794d7f751f780b3243552 (diff)
downloadframeworks_av-44d9848d6656777a18019223e0d35f2fcc67719a.zip
frameworks_av-44d9848d6656777a18019223e0d35f2fcc67719a.tar.gz
frameworks_av-44d9848d6656777a18019223e0d35f2fcc67719a.tar.bz2
Issue 3032913: improve AudioTrack recovery time
This issue showed that when an AudioTrack underruns during a too long period of time and is therefore disabled by audioflinger mixer, it takes an additional delay of up to 3 seconds to recover. This fix adds a simple mechanism to recover immediately when the client application is ready to write data again in the AudioTrack buffer Also throttle warnings on record overflows Change-Id: I8b2c71578dd134b9e60a15ee4d91b70f3799cb3d
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp17
1 files changed, 13 insertions, 4 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 97b8086..8527059 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1856,6 +1856,8 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
if (--(track->mRetryCount) <= 0) {
LOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", track->name(), this);
tracksToRemove->add(track);
+ // indicate to client process that the track was disabled because of underrun
+ cblk->flags |= CBLK_DISABLED_ON;
} else if (mixerStatus != MIXER_TRACKS_READY) {
mixerStatus = MIXER_TRACKS_ENABLED;
}
@@ -2790,7 +2792,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
// Force underrun condition to avoid false underrun callback until first data is
- // written to buffer
+ // written to buffer (other flags are cleared)
mCblk->flags = CBLK_UNDERRUN_ON;
} else {
mBuffer = sharedBuffer->pointer();
@@ -2813,7 +2815,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
// Force underrun condition to avoid false underrun callback until first data is
- // written to buffer
+ // written to buffer (other flags are cleared)
mCblk->flags = CBLK_UNDERRUN_ON;
mBufferEnd = (uint8_t *)mBuffer + bufferSize;
}
@@ -3794,6 +3796,8 @@ bool AudioFlinger::RecordThread::threadLoop()
AudioBufferProvider::Buffer buffer;
sp<RecordTrack> activeTrack;
+ nsecs_t lastWarning = 0;
+
// start recording
while (!exitPending()) {
@@ -3935,8 +3939,13 @@ bool AudioFlinger::RecordThread::threadLoop()
}
// client isn't retrieving buffers fast enough
else {
- if (!mActiveTrack->setOverflow())
- LOGW("RecordThread: buffer overflow");
+ if (!mActiveTrack->setOverflow()) {
+ nsecs_t now = systemTime();
+ if ((now - lastWarning) > kWarningThrottle) {
+ LOGW("RecordThread: buffer overflow");
+ lastWarning = now;
+ }
+ }
// Release the processor for a while before asking for a new buffer.
// This will give the application more chance to read from the buffer and
// clear the overflow.