diff options
author | Glenn Kasten <gkasten@google.com> | 2013-09-20 09:20:45 -0700 |
---|---|---|
committer | Glenn Kasten <gkasten@google.com> | 2013-09-20 12:22:29 -0700 |
commit | 5a6cd224d07c05b496b6aca050ce5ecf96f125af (patch) | |
tree | c5d2fe55f0080c9660d283d040616d9a9fb6decc /media/libmedia/AudioRecord.cpp | |
parent | a3b97ad288e6808c54c6275eaac1bd53108d8f11 (diff) | |
download | frameworks_av-5a6cd224d07c05b496b6aca050ce5ecf96f125af.zip frameworks_av-5a6cd224d07c05b496b6aca050ce5ecf96f125af.tar.gz frameworks_av-5a6cd224d07c05b496b6aca050ce5ecf96f125af.tar.bz2 |
Fix slow AudioTrack and AudioRecord destruction
There were two causes for the slowness:
When thread was paused, it used nanosleep and sleep. These usually
run to completion (except for POSIX signal, which we avoid because it
is low-level). Instead, replace the nanosleep and sleep by condition
timed wait, as that can be made to return early by a condition signal.
Another advantage of condition timed wait is that a condition wait was
already being used at top of thread loop, so it is a simpler change.
The AudioRecord destructor was missing a proxy interrupt that was correct
in AudioTrack. This proxy interrupt is needed in case another thread
is blocked in proxy obtainBuffer.
Does not address the 1 second polling for NS_WHENEVER.
Bug: 10822765
Change-Id: Id665994551e87e4d7da9c7b015f424fd7a0b5560
Diffstat (limited to 'media/libmedia/AudioRecord.cpp')
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index e934a3e..fb731b9 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -105,6 +105,7 @@ AudioRecord::~AudioRecord() // Otherwise the callback thread will never exit. stop(); if (mAudioRecordThread != 0) { + mProxy->interrupt(); mAudioRecordThread->requestExit(); // see comment in AudioRecord.h mAudioRecordThread->requestExitAndWait(); mAudioRecordThread.clear(); @@ -960,7 +961,7 @@ void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who) // ========================================================================= AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava) - : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mResumeLatch(false) + : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL) { } @@ -977,25 +978,32 @@ bool AudioRecord::AudioRecordThread::threadLoop() // caller will check for exitPending() return true; } + if (mPausedInt) { + mPausedInt = false; + if (mPausedNs > 0) { + (void) mMyCond.waitRelative(mMyLock, mPausedNs); + } else { + mMyCond.wait(mMyLock); + } + return true; + } } nsecs_t ns = mReceiver.processAudioBuffer(this); switch (ns) { case 0: return true; - case NS_WHENEVER: - sleep(1); - return true; case NS_INACTIVE: - pauseConditional(); + pauseInternal(); return true; case NS_NEVER: return false; + case NS_WHENEVER: + // FIXME increase poll interval, or make event-driven + ns = 1000000000LL; + // fall through default: LOG_ALWAYS_FATAL_IF(ns < 0, "processAudioBuffer() returned %lld", ns); - struct timespec req; - req.tv_sec = ns / 1000000000LL; - req.tv_nsec = ns % 1000000000LL; - nanosleep(&req, NULL /*rem*/); + pauseInternal(ns); return true; } } @@ -1004,24 +1012,18 @@ void AudioRecord::AudioRecordThread::requestExit() { // must be in this order to avoid a race condition Thread::requestExit(); - resume(); + AutoMutex _l(mMyLock); + if (mPaused || mPausedInt) { + mPaused = false; + mPausedInt = false; + mMyCond.signal(); + } } void AudioRecord::AudioRecordThread::pause() { AutoMutex _l(mMyLock); mPaused = true; - mResumeLatch = false; -} - -void AudioRecord::AudioRecordThread::pauseConditional() -{ - AutoMutex _l(mMyLock); - if (mResumeLatch) { - mResumeLatch = false; - } else { - mPaused = true; - } } void AudioRecord::AudioRecordThread::resume() @@ -1029,13 +1031,17 @@ void AudioRecord::AudioRecordThread::resume() AutoMutex _l(mMyLock); if (mPaused) { mPaused = false; - mResumeLatch = false; mMyCond.signal(); - } else { - mResumeLatch = true; } } +void AudioRecord::AudioRecordThread::pauseInternal(nsecs_t ns) +{ + AutoMutex _l(mMyLock); + mPausedInt = true; + mPausedNs = ns; +} + // ------------------------------------------------------------------------- }; // namespace android |