diff options
author | Eric Laurent <elaurent@google.com> | 2011-01-18 13:50:39 -0800 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2011-01-18 14:30:12 -0800 |
commit | 0c5bf19e1535772bf837800536a2dbb25790964e (patch) | |
tree | 85e6abaeb3195830cfd7ece16554e450b78a8dfe /libaudio | |
parent | e93175d679a044f242962730ade8d133570c4ab1 (diff) | |
download | device_samsung_crespo-0c5bf19e1535772bf837800536a2dbb25790964e.zip device_samsung_crespo-0c5bf19e1535772bf837800536a2dbb25790964e.tar.gz device_samsung_crespo-0c5bf19e1535772bf837800536a2dbb25790964e.tar.bz2 |
Fix issue 3305305.
The problem is that when the voice search tone is started, audio capture
is still active and the output stream write function needs to place
the input stream in standby to reconfigure the kernel driver.
To do so it has to acquire the input stream mutex but as the input stream thread
holds the lock most of the time while sleeping in the driver waiting for more data,
this is very difficult and can take several seconds.
The fix consists in forcing a sleep in the next read() when another function needs
to acquire the input stream lock.
The same change is done for output stream write() function.
Also removed the workaround for issue 3201189 in setMode() (thread priority bump) as this
change addresses the same problem.
Change-Id: I3a5e672717752f83dfedce822a18748b165b0a5a
Diffstat (limited to 'libaudio')
-rw-r--r-- | libaudio/AudioHardware.cpp | 66 | ||||
-rw-r--r-- | libaudio/AudioHardware.h | 12 |
2 files changed, 62 insertions, 16 deletions
diff --git a/libaudio/AudioHardware.cpp b/libaudio/AudioHardware.cpp index 4cca932..585bb71 100644 --- a/libaudio/AudioHardware.cpp +++ b/libaudio/AudioHardware.cpp @@ -312,17 +312,13 @@ status_t AudioHardware::setMode(int mode) sp<AudioStreamInALSA> spIn; status_t status; - // bump thread priority to speed up mutex acquisition - int priority = getpriority(PRIO_PROCESS, 0); - setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_URGENT_AUDIO); - // Mutex acquisition order is always out -> in -> hw AutoMutex lock(mLock); spOut = mOutput; while (spOut != 0) { if (!spOut->checkStandby()) { - int cnt = spOut->standbyCnt(); + int cnt = spOut->prepareLock(); mLock.unlock(); spOut->lock(); mLock.lock(); @@ -341,7 +337,7 @@ status_t AudioHardware::setMode(int mode) spIn = getActiveInput_l(); while (spIn != 0) { - int cnt = spIn->standbyCnt(); + int cnt = spIn->prepareLock(); mLock.unlock(); spIn->lock(); mLock.lock(); @@ -355,8 +351,6 @@ status_t AudioHardware::setMode(int mode) } // spIn is not 0 here only if the input is active - setpriority(PRIO_PROCESS, 0, priority); - int prevMode = mMode; status = AudioHardwareBase::setMode(mode); LOGV("setMode() : new %d, old %d", mMode, prevMode); @@ -924,7 +918,7 @@ AudioHardware::AudioStreamOutALSA::AudioStreamOutALSA() : mHardware(0), mPcm(0), mMixer(0), mRouteCtl(0), mStandby(true), mDevices(0), mChannels(AUDIO_HW_OUT_CHANNELS), mSampleRate(AUDIO_HW_OUT_SAMPLERATE), mBufferSize(AUDIO_HW_OUT_PERIOD_BYTES), - mDriverOp(DRV_NONE), mStandbyCnt(0) + mDriverOp(DRV_NONE), mStandbyCnt(0), mSleepReq(false) { } @@ -979,6 +973,12 @@ ssize_t AudioHardware::AudioStreamOutALSA::write(const void* buffer, size_t byte if (mHardware == NULL) return NO_INIT; + if (mSleepReq) { + // 10ms are always shorter than the time to reconfigure the audio path + // which is the only condition when mSleepReq would be true. + usleep(10000); + } + { // scope for the lock AutoMutex lock(mLock); @@ -991,7 +991,7 @@ ssize_t AudioHardware::AudioStreamOutALSA::write(const void* buffer, size_t byte sp<AudioStreamInALSA> spIn = mHardware->getActiveInput_l(); while (spIn != 0) { - int cnt = spIn->standbyCnt(); + int cnt = spIn->prepareLock(); mHardware->lock().unlock(); // Mutex acquisition order is always out -> in -> hw spIn->lock(); @@ -1216,6 +1216,24 @@ status_t AudioHardware::AudioStreamOutALSA::getRenderPosition(uint32_t *dspFrame return INVALID_OPERATION; } +int AudioHardware::AudioStreamOutALSA::prepareLock() +{ + // request sleep next time write() is called so that caller can acquire + // mLock + mSleepReq = true; + return mStandbyCnt; +} + +void AudioHardware::AudioStreamOutALSA::lock() +{ + mLock.lock(); + mSleepReq = false; +} + +void AudioHardware::AudioStreamOutALSA::unlock() { + mLock.unlock(); +} + //------------------------------------------------------------------------------ // AudioStreamInALSA //------------------------------------------------------------------------------ @@ -1225,7 +1243,7 @@ AudioHardware::AudioStreamInALSA::AudioStreamInALSA() : mStandby(true), mDevices(0), mChannels(AUDIO_HW_IN_CHANNELS), mChannelCount(1), mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_PERIOD_BYTES), mDownSampler(NULL), mReadStatus(NO_ERROR), mDriverOp(DRV_NONE), - mStandbyCnt(0) + mStandbyCnt(0), mSleepReq(false) { } @@ -1297,6 +1315,12 @@ ssize_t AudioHardware::AudioStreamInALSA::read(void* buffer, ssize_t bytes) if (mHardware == NULL) return NO_INIT; + if (mSleepReq) { + // 10ms are always shorter than the time to reconfigure the audio path + // which is the only condition when mSleepReq would be true. + usleep(10000); + } + { // scope for the lock AutoMutex lock(mLock); @@ -1309,7 +1333,7 @@ ssize_t AudioHardware::AudioStreamInALSA::read(void* buffer, ssize_t bytes) sp<AudioStreamOutALSA> spOut = mHardware->output(); while (spOut != 0) { if (!spOut->checkStandby()) { - int cnt = spOut->standbyCnt(); + int cnt = spOut->prepareLock(); mHardware->lock().unlock(); mLock.unlock(); // Mutex acquisition order is always out -> in -> hw @@ -1635,6 +1659,24 @@ size_t AudioHardware::AudioStreamInALSA::getBufferSize(uint32_t sampleRate, int return (AUDIO_HW_IN_PERIOD_SZ*channelCount*sizeof(int16_t)) / ratio ; } +int AudioHardware::AudioStreamInALSA::prepareLock() +{ + // request sleep next time read() is called so that caller can acquire + // mLock + mSleepReq = true; + return mStandbyCnt; +} + +void AudioHardware::AudioStreamInALSA::lock() +{ + mLock.lock(); + mSleepReq = false; +} + +void AudioHardware::AudioStreamInALSA::unlock() { + mLock.unlock(); +} + //------------------------------------------------------------------------------ // DownSampler //------------------------------------------------------------------------------ diff --git a/libaudio/AudioHardware.h b/libaudio/AudioHardware.h index 1379495..a2c47bd 100644 --- a/libaudio/AudioHardware.h +++ b/libaudio/AudioHardware.h @@ -203,8 +203,9 @@ private: status_t open_l(); int standbyCnt() { return mStandbyCnt; } - void lock() { mLock.lock(); } - void unlock() { mLock.unlock(); } + int prepareLock(); + void lock(); + void unlock(); private: @@ -222,6 +223,7 @@ private: // trace driver operations for dump int mDriverOp; int mStandbyCnt; + bool mSleepReq; }; class DownSampler; @@ -316,8 +318,9 @@ private: virtual status_t getNextBuffer(BufferProvider::Buffer* buffer); virtual void releaseBuffer(BufferProvider::Buffer* buffer); - void lock() { mLock.lock(); } - void unlock() { mLock.unlock(); } + int prepareLock(); + void lock(); + void unlock(); private: Mutex mLock; @@ -339,6 +342,7 @@ private: // trace driver operations for dump int mDriverOp; int mStandbyCnt; + bool mSleepReq; }; }; |