summaryrefslogtreecommitdiffstats
path: root/libaudio
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2011-01-18 13:50:39 -0800
committerEric Laurent <elaurent@google.com>2011-01-18 14:30:12 -0800
commit0c5bf19e1535772bf837800536a2dbb25790964e (patch)
tree85e6abaeb3195830cfd7ece16554e450b78a8dfe /libaudio
parente93175d679a044f242962730ade8d133570c4ab1 (diff)
downloaddevice_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.cpp66
-rw-r--r--libaudio/AudioHardware.h12
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;
};
};