diff options
author | Glenn Kasten <gkasten@google.com> | 2012-01-10 09:01:19 -0800 |
---|---|---|
committer | Glenn Kasten <gkasten@google.com> | 2012-01-10 15:43:48 -0800 |
commit | f8c1a6f7ef515810356816b50bfe18af95f3ec32 (patch) | |
tree | 39adc0cad7ded05219a3d4ca9f9388511bbe7c97 /media | |
parent | c1dc1cb1d1eaf84e88669f1a5f22579a0d9237c2 (diff) | |
download | frameworks_av-f8c1a6f7ef515810356816b50bfe18af95f3ec32.zip frameworks_av-f8c1a6f7ef515810356816b50bfe18af95f3ec32.tar.gz frameworks_av-f8c1a6f7ef515810356816b50bfe18af95f3ec32.tar.bz2 |
Fix race in AudioSystem::getInputBufferSize
It was caching the recording parameters without a mutex.
Change-Id: Ic4b9f621cbc080d224c2233cf3ca3454fc0f19bd
Diffstat (limited to 'media')
-rw-r--r-- | media/libmedia/AudioSystem.cpp | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index f7f129c..caa3d30 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -38,7 +38,7 @@ audio_error_callback AudioSystem::gAudioErrorCallback = NULL; DefaultKeyedVector<int, audio_io_handle_t> AudioSystem::gStreamOutputMap(0); DefaultKeyedVector<audio_io_handle_t, AudioSystem::OutputDescriptor *> AudioSystem::gOutputs(0); -// Cached values for recording queries +// Cached values for recording queries, all protected by gLock uint32_t AudioSystem::gPrevInSamplingRate = 16000; int AudioSystem::gPrevInFormat = AUDIO_FORMAT_PCM_16_BIT; int AudioSystem::gPrevInChannelCount = 1; @@ -301,22 +301,27 @@ status_t AudioSystem::getOutputLatency(uint32_t* latency, int streamType) status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, int format, int channelCount, size_t* buffSize) { + gLock.lock(); // Do we have a stale gInBufferSize or are we requesting the input buffer size for new values - if ((gInBuffSize == 0) || (sampleRate != gPrevInSamplingRate) || (format != gPrevInFormat) + size_t inBuffSize = gInBuffSize; + if ((inBuffSize == 0) || (sampleRate != gPrevInSamplingRate) || (format != gPrevInFormat) || (channelCount != gPrevInChannelCount)) { + gLock.unlock(); + const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); + if (af == 0) { + return PERMISSION_DENIED; + } + inBuffSize = af->getInputBufferSize(sampleRate, format, channelCount); + gLock.lock(); // save the request params gPrevInSamplingRate = sampleRate; gPrevInFormat = format; gPrevInChannelCount = channelCount; - gInBuffSize = 0; - const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) { - return PERMISSION_DENIED; - } - gInBuffSize = af->getInputBufferSize(sampleRate, format, channelCount); + gInBuffSize = inBuffSize; } - *buffSize = gInBuffSize; + gLock.unlock(); + *buffSize = inBuffSize; return NO_ERROR; } |