diff options
-rw-r--r-- | include/media/AudioRecord.h | 10 | ||||
-rw-r--r-- | include/media/AudioTrack.h | 10 | ||||
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 54 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 53 |
4 files changed, 71 insertions, 56 deletions
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index 62f0c64..052064d 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -398,18 +398,20 @@ private: void pause(); // suspend thread from execution at next loop boundary void resume(); // allow thread to execute, if not requested to exit - void pauseConditional(); - // like pause(), but only if prior resume() wasn't latched private: + void pauseInternal(nsecs_t ns = 0LL); + // like pause(), but only used internally within thread + friend class AudioRecord; virtual bool threadLoop(); AudioRecord& mReceiver; virtual ~AudioRecordThread(); Mutex mMyLock; // Thread::mLock is private Condition mMyCond; // Thread::mThreadExitedCondition is private - bool mPaused; // whether thread is currently paused - bool mResumeLatch; // whether next pauseConditional() will be a nop + bool mPaused; // whether thread is requested to pause at next loop entry + bool mPausedInt; // whether thread internally requests pause + nsecs_t mPausedNs; // if mPausedInt then associated timeout, otherwise ignored }; // body of AudioRecordThread::threadLoop() diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index 453c106..22ad57e 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -598,18 +598,20 @@ protected: void pause(); // suspend thread from execution at next loop boundary void resume(); // allow thread to execute, if not requested to exit - void pauseConditional(); - // like pause(), but only if prior resume() wasn't latched private: + void pauseInternal(nsecs_t ns = 0LL); + // like pause(), but only used internally within thread + friend class AudioTrack; virtual bool threadLoop(); AudioTrack& mReceiver; virtual ~AudioTrackThread(); Mutex mMyLock; // Thread::mLock is private Condition mMyCond; // Thread::mThreadExitedCondition is private - bool mPaused; // whether thread is currently paused - bool mResumeLatch; // whether next pauseConditional() will be a nop + bool mPaused; // whether thread is requested to pause at next loop entry + bool mPausedInt; // whether thread internally requests pause + nsecs_t mPausedNs; // if mPausedInt then associated timeout, otherwise ignored }; // body of AudioTrackThread::threadLoop() 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 diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 15249a4..fdcf911 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -1782,7 +1782,7 @@ void AudioTrack::DeathNotifier::binderDied(const wp<IBinder>& who) // ========================================================================= AudioTrack::AudioTrackThread::AudioTrackThread(AudioTrack& receiver, bool bCanCallJava) - : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mResumeLatch(false) + : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL) { } @@ -1799,25 +1799,32 @@ bool AudioTrack::AudioTrackThread::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; } } @@ -1826,24 +1833,18 @@ void AudioTrack::AudioTrackThread::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 AudioTrack::AudioTrackThread::pause() { AutoMutex _l(mMyLock); mPaused = true; - mResumeLatch = false; -} - -void AudioTrack::AudioTrackThread::pauseConditional() -{ - AutoMutex _l(mMyLock); - if (mResumeLatch) { - mResumeLatch = false; - } else { - mPaused = true; - } } void AudioTrack::AudioTrackThread::resume() @@ -1851,11 +1852,15 @@ void AudioTrack::AudioTrackThread::resume() AutoMutex _l(mMyLock); if (mPaused) { mPaused = false; - mResumeLatch = false; mMyCond.signal(); - } else { - mResumeLatch = true; } } +void AudioTrack::AudioTrackThread::pauseInternal(nsecs_t ns) +{ + AutoMutex _l(mMyLock); + mPausedInt = true; + mPausedNs = ns; +} + }; // namespace android |