diff options
author | Eric Laurent <elaurent@google.com> | 2015-05-01 19:10:25 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-05-01 19:10:26 +0000 |
commit | cc85abcf4ac398dca240db356b8b4db052b415a4 (patch) | |
tree | 65f9eccab6b0d9b9f3dcee48e2c44326b0edbef4 | |
parent | 0bbf8b213ad96051357e3ad6d6d2808bfa31a59a (diff) | |
parent | 73e26b661af50be2c0a4ff6c9ac85f7347a8b235 (diff) | |
download | frameworks_av-cc85abcf4ac398dca240db356b8b4db052b415a4.zip frameworks_av-cc85abcf4ac398dca240db356b8b4db052b415a4.tar.gz frameworks_av-cc85abcf4ac398dca240db356b8b4db052b415a4.tar.bz2 |
Merge "AudioSystem: refactor audio config cache and callbacks" into mnc-dev
-rw-r--r-- | include/media/AudioIoDescriptor.h | 52 | ||||
-rw-r--r-- | include/media/AudioSystem.h | 55 | ||||
-rw-r--r-- | include/media/IAudioFlingerClient.h | 4 | ||||
-rw-r--r-- | media/libmedia/AudioSystem.cpp | 210 | ||||
-rw-r--r-- | media/libmedia/IAudioFlingerClient.cpp | 49 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 25 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.h | 3 | ||||
-rw-r--r-- | services/audioflinger/Threads.cpp | 72 | ||||
-rw-r--r-- | services/audioflinger/Threads.h | 23 |
9 files changed, 254 insertions, 239 deletions
diff --git a/include/media/AudioIoDescriptor.h b/include/media/AudioIoDescriptor.h new file mode 100644 index 0000000..2437901 --- /dev/null +++ b/include/media/AudioIoDescriptor.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_AUDIO_IO_DESCRIPTOR_H +#define ANDROID_AUDIO_IO_DESCRIPTOR_H + +namespace android { + +enum audio_io_config_event { + AUDIO_OUTPUT_OPENED, + AUDIO_OUTPUT_CLOSED, + AUDIO_OUTPUT_CONFIG_CHANGED, + AUDIO_INPUT_OPENED, + AUDIO_INPUT_CLOSED, + AUDIO_INPUT_CONFIG_CHANGED, +}; + +// audio input/output descriptor used to cache output configurations in client process to avoid +// frequent calls through IAudioFlinger +class AudioIoDescriptor : public RefBase { +public: + AudioIoDescriptor() : + mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(AUDIO_CHANNEL_NONE), + mFrameCount(0), mLatency(0) {} + + virtual ~AudioIoDescriptor() {} + + audio_io_handle_t mIoHandle; + uint32_t mSamplingRate; + audio_format_t mFormat; + audio_channel_mask_t mChannelMask; + size_t mFrameCount; + uint32_t mLatency; +}; + + +}; // namespace android + +#endif /*ANDROID_AUDIO_IO_DESCRIPTOR_H*/ diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index b427036..0cbcdb1 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -19,6 +19,7 @@ #include <hardware/audio_effect.h> #include <media/AudioPolicy.h> +#include <media/AudioIoDescriptor.h> #include <media/IAudioFlingerClient.h> #include <media/IAudioPolicyServiceClient.h> #include <system/audio.h> @@ -157,33 +158,6 @@ public: // or no HW sync source is used. static audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId); - // types of io configuration change events received with ioConfigChanged() - enum io_config_event { - OUTPUT_OPENED, - OUTPUT_CLOSED, - OUTPUT_CONFIG_CHANGED, - INPUT_OPENED, - INPUT_CLOSED, - INPUT_CONFIG_CHANGED, - STREAM_CONFIG_CHANGED, - NUM_CONFIG_EVENTS - }; - - // audio output descriptor used to cache output configurations in client process to avoid - // frequent calls through IAudioFlinger - class OutputDescriptor { - public: - OutputDescriptor() - : samplingRate(0), format(AUDIO_FORMAT_DEFAULT), channelMask(0), frameCount(0), latency(0) - {} - - uint32_t samplingRate; - audio_format_t format; - audio_channel_mask_t channelMask; - size_t frameCount; - uint32_t latency; - }; - // Events used to synchronize actions between audio sessions. // For instance SYNC_EVENT_PRESENTATION_COMPLETE can be used to delay recording start until // playback is complete on another audio session. @@ -366,9 +340,16 @@ private: class AudioFlingerClient: public IBinder::DeathRecipient, public BnAudioFlingerClient { public: - AudioFlingerClient() { + AudioFlingerClient() : + mInBuffSize(0), mInSamplingRate(0), + mInFormat(AUDIO_FORMAT_DEFAULT), mInChannelMask(AUDIO_CHANNEL_NONE) { } + void clearIoCache(); + status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, + audio_channel_mask_t channelMask, size_t* buffSize); + sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle); + // DeathRecipient virtual void binderDied(const wp<IBinder>& who); @@ -376,7 +357,17 @@ private: // indicate a change in the configuration of an output or input: keeps the cached // values for output/input parameters up-to-date in client process - virtual void ioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2); + virtual void ioConfigChanged(audio_io_config_event event, + const sp<AudioIoDescriptor>& ioDesc); + private: + Mutex mLock; + DefaultKeyedVector<audio_io_handle_t, sp<AudioIoDescriptor> > mIoDescriptors; + + // cached values for recording getInputBufferSize() queries + size_t mInBuffSize; // zero indicates cache is invalid + uint32_t mInSamplingRate; + audio_format_t mInFormat; + audio_channel_mask_t mInChannelMask; }; class AudioPolicyServiceClient: public IBinder::DeathRecipient, @@ -408,8 +399,6 @@ private: friend class AudioPolicyServiceClient; static Mutex gLock; // protects gAudioFlinger and gAudioErrorCallback, - static Mutex gLockCache; // protects gOutputs, gPrevInSamplingRate, gPrevInFormat, - // gPrevInChannelMask and gInBuffSize static Mutex gLockAPS; // protects gAudioPolicyService and gAudioPolicyServiceClient static sp<IAudioFlinger> gAudioFlinger; static audio_error_callback gAudioErrorCallback; @@ -422,10 +411,6 @@ private: static audio_channel_mask_t gPrevInChannelMask; static sp<IAudioPolicyService> gAudioPolicyService; - - // list of output descriptors containing cached parameters - // (sampling rate, framecount, channel count...) - static DefaultKeyedVector<audio_io_handle_t, OutputDescriptor *> gOutputs; }; }; // namespace android diff --git a/include/media/IAudioFlingerClient.h b/include/media/IAudioFlingerClient.h index 75a9971..0080bc9 100644 --- a/include/media/IAudioFlingerClient.h +++ b/include/media/IAudioFlingerClient.h @@ -22,6 +22,7 @@ #include <binder/IInterface.h> #include <utils/KeyedVector.h> #include <system/audio.h> +#include <media/AudioIoDescriptor.h> namespace android { @@ -33,7 +34,8 @@ public: DECLARE_META_INTERFACE(AudioFlingerClient); // Notifies a change of audio input/output configuration. - virtual void ioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2) = 0; + virtual void ioConfigChanged(audio_io_config_event event, + const sp<AudioIoDescriptor>& ioDesc) = 0; }; diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 62d25b5..85ed2b1 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -32,21 +32,12 @@ namespace android { // client singleton for AudioFlinger binder interface Mutex AudioSystem::gLock; -Mutex AudioSystem::gLockCache; Mutex AudioSystem::gLockAPS; sp<IAudioFlinger> AudioSystem::gAudioFlinger; sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient; audio_error_callback AudioSystem::gAudioErrorCallback = NULL; dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL; -// Cached values for output handles -DefaultKeyedVector<audio_io_handle_t, AudioSystem::OutputDescriptor *> AudioSystem::gOutputs(NULL); - -// Cached values for recording queries, all protected by gLock -uint32_t AudioSystem::gPrevInSamplingRate; -audio_format_t AudioSystem::gPrevInFormat; -audio_channel_mask_t AudioSystem::gPrevInChannelMask; -size_t AudioSystem::gInBuffSize = 0; // zero indicates cache is invalid // establish binder interface to AudioFlinger service const sp<IAudioFlinger> AudioSystem::get_audio_flinger() @@ -259,17 +250,14 @@ status_t AudioSystem::getSamplingRate(audio_io_handle_t output, const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); if (af == 0) return PERMISSION_DENIED; - Mutex::Autolock _l(gLockCache); - - OutputDescriptor *outputDesc = AudioSystem::gOutputs.valueFor(output); - if (outputDesc == NULL) { + LOG_ALWAYS_FATAL_IF(gAudioFlingerClient == 0); + sp<AudioIoDescriptor> outputDesc = gAudioFlingerClient->getIoDescriptor(output); + if (outputDesc == 0) { ALOGV("getOutputSamplingRate() no output descriptor for output %d in gOutputs", output); - gLockCache.unlock(); *samplingRate = af->sampleRate(output); - gLockCache.lock(); } else { ALOGV("getOutputSamplingRate() reading from output desc"); - *samplingRate = outputDesc->samplingRate; + *samplingRate = outputDesc->mSamplingRate; } if (*samplingRate == 0) { ALOGE("AudioSystem::getSamplingRate failed for output %d", output); @@ -303,15 +291,12 @@ status_t AudioSystem::getFrameCount(audio_io_handle_t output, const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); if (af == 0) return PERMISSION_DENIED; - Mutex::Autolock _l(gLockCache); - - OutputDescriptor *outputDesc = AudioSystem::gOutputs.valueFor(output); - if (outputDesc == NULL) { - gLockCache.unlock(); + LOG_ALWAYS_FATAL_IF(gAudioFlingerClient == 0); + sp<AudioIoDescriptor> outputDesc = gAudioFlingerClient->getIoDescriptor(output); + if (outputDesc == 0) { *frameCount = af->frameCount(output); - gLockCache.lock(); } else { - *frameCount = outputDesc->frameCount; + *frameCount = outputDesc->mFrameCount; } if (*frameCount == 0) { ALOGE("AudioSystem::getFrameCount failed for output %d", output); @@ -345,15 +330,12 @@ status_t AudioSystem::getLatency(audio_io_handle_t output, const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); if (af == 0) return PERMISSION_DENIED; - Mutex::Autolock _l(gLockCache); - - OutputDescriptor *outputDesc = AudioSystem::gOutputs.valueFor(output); - if (outputDesc == NULL) { - gLockCache.unlock(); + LOG_ALWAYS_FATAL_IF(gAudioFlingerClient == 0); + sp<AudioIoDescriptor> outputDesc = gAudioFlingerClient->getIoDescriptor(output); + if (outputDesc == 0) { *latency = af->latency(output); - gLockCache.lock(); } else { - *latency = outputDesc->latency; + *latency = outputDesc->mLatency; } ALOGV("getLatency() output %d, latency %d", output, *latency); @@ -365,33 +347,9 @@ status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, audio_format_t for audio_channel_mask_t channelMask, size_t* buffSize) { const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); - if (af == 0) { - return PERMISSION_DENIED; - } - Mutex::Autolock _l(gLockCache); - // Do we have a stale gInBufferSize or are we requesting the input buffer size for new values - size_t inBuffSize = gInBuffSize; - if ((inBuffSize == 0) || (sampleRate != gPrevInSamplingRate) || (format != gPrevInFormat) - || (channelMask != gPrevInChannelMask)) { - gLockCache.unlock(); - inBuffSize = af->getInputBufferSize(sampleRate, format, channelMask); - gLockCache.lock(); - if (inBuffSize == 0) { - ALOGE("AudioSystem::getInputBufferSize failed sampleRate %d format %#x channelMask %x", - sampleRate, format, channelMask); - return BAD_VALUE; - } - // A benign race is possible here: we could overwrite a fresher cache entry - // save the request params - gPrevInSamplingRate = sampleRate; - gPrevInFormat = format; - gPrevInChannelMask = channelMask; - - gInBuffSize = inBuffSize; - } - *buffSize = inBuffSize; - - return NO_ERROR; + if (af == 0) return PERMISSION_DENIED; + LOG_ALWAYS_FATAL_IF(gAudioFlingerClient == 0); + return gAudioFlingerClient->getInputBufferSize(sampleRate, format, channelMask, buffSize); } status_t AudioSystem::setVoiceVolume(float value) @@ -453,6 +411,17 @@ audio_hw_sync_t AudioSystem::getAudioHwSyncForSession(audio_session_t sessionId) // --------------------------------------------------------------------------- + +void AudioSystem::AudioFlingerClient::clearIoCache() +{ + Mutex::Autolock _l(mLock); + mIoDescriptors.clear(); + mInBuffSize = 0; + mInSamplingRate = 0; + mInFormat = AUDIO_FORMAT_DEFAULT; + mInChannelMask = AUDIO_CHANNEL_NONE; +} + void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who __unused) { audio_error_callback cb = NULL; @@ -462,11 +431,8 @@ void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who __unused cb = gAudioErrorCallback; } - { - // clear output handles and stream to output map caches - Mutex::Autolock _l(gLockCache); - AudioSystem::gOutputs.clear(); - } + // clear output handles and stream to output map caches + clearIoCache(); if (cb) { cb(DEAD_OBJECT); @@ -474,67 +440,96 @@ void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who __unused ALOGW("AudioFlinger server died!"); } -void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, audio_io_handle_t ioHandle, - const void *param2) { +void AudioSystem::AudioFlingerClient::ioConfigChanged(audio_io_config_event event, + const sp<AudioIoDescriptor>& ioDesc) { ALOGV("ioConfigChanged() event %d", event); - const OutputDescriptor *desc; - if (ioHandle == AUDIO_IO_HANDLE_NONE) return; + if (ioDesc == 0 || ioDesc->mIoHandle == AUDIO_IO_HANDLE_NONE) return; - Mutex::Autolock _l(AudioSystem::gLockCache); + Mutex::Autolock _l(mLock); switch (event) { - case STREAM_CONFIG_CHANGED: - break; - case OUTPUT_OPENED: { - if (gOutputs.indexOfKey(ioHandle) >= 0) { - ALOGV("ioConfigChanged() opening already existing output! %d", ioHandle); + case AUDIO_OUTPUT_OPENED: + case AUDIO_INPUT_OPENED: { + if (getIoDescriptor(ioDesc->mIoHandle) != 0) { + ALOGV("ioConfigChanged() opening already existing output! %d", ioDesc->mIoHandle); break; } - if (param2 == NULL) break; - desc = (const OutputDescriptor *)param2; - - OutputDescriptor *outputDesc = new OutputDescriptor(*desc); - gOutputs.add(ioHandle, outputDesc); - ALOGV("ioConfigChanged() new output samplingRate %u, format %#x channel mask %#x " - "frameCount %zu latency %d", - outputDesc->samplingRate, outputDesc->format, outputDesc->channelMask, - outputDesc->frameCount, outputDesc->latency); + mIoDescriptors.add(ioDesc->mIoHandle, ioDesc); + ALOGV("ioConfigChanged() new %s opened %d samplingRate %u, format %#x channel mask %#x " + "frameCount %zu", event == AUDIO_OUTPUT_OPENED ? "output" : "input", + ioDesc->mIoHandle, ioDesc->mSamplingRate, ioDesc->mFormat, ioDesc->mChannelMask, + ioDesc->mFrameCount); } break; - case OUTPUT_CLOSED: { - if (gOutputs.indexOfKey(ioHandle) < 0) { - ALOGW("ioConfigChanged() closing unknown output! %d", ioHandle); + case AUDIO_OUTPUT_CLOSED: + case AUDIO_INPUT_CLOSED: { + if (getIoDescriptor(ioDesc->mIoHandle) == 0) { + ALOGW("ioConfigChanged() closing unknown %s %d", + event == AUDIO_OUTPUT_CLOSED ? "output" : "input", ioDesc->mIoHandle); break; } - ALOGV("ioConfigChanged() output %d closed", ioHandle); + ALOGV("ioConfigChanged() %s %d closed", event == AUDIO_OUTPUT_CLOSED ? "output" : "input", + ioDesc->mIoHandle); - gOutputs.removeItem(ioHandle); + mIoDescriptors.removeItem(ioDesc->mIoHandle); } break; - case OUTPUT_CONFIG_CHANGED: { - int index = gOutputs.indexOfKey(ioHandle); - if (index < 0) { - ALOGW("ioConfigChanged() modifying unknown output! %d", ioHandle); + case AUDIO_OUTPUT_CONFIG_CHANGED: + case AUDIO_INPUT_CONFIG_CHANGED: { + if (getIoDescriptor(ioDesc->mIoHandle) == 0) { + ALOGW("ioConfigChanged() modifying unknown output! %d", ioDesc->mIoHandle); break; } - if (param2 == NULL) break; - desc = (const OutputDescriptor *)param2; - - ALOGV("ioConfigChanged() new config for output %d samplingRate %u, format %#x " - "channel mask %#x frameCount %zu latency %d", - ioHandle, desc->samplingRate, desc->format, - desc->channelMask, desc->frameCount, desc->latency); - OutputDescriptor *outputDesc = gOutputs.valueAt(index); - delete outputDesc; - outputDesc = new OutputDescriptor(*desc); - gOutputs.replaceValueFor(ioHandle, outputDesc); + mIoDescriptors.replaceValueFor(ioDesc->mIoHandle, ioDesc); + ALOGV("ioConfigChanged() new config for %s %d samplingRate %u, format %#x " + "channel mask %#x frameCount %zu", + event == AUDIO_OUTPUT_CONFIG_CHANGED ? "output" : "input", + ioDesc->mIoHandle, ioDesc->mSamplingRate, ioDesc->mFormat, + ioDesc->mChannelMask, ioDesc->mFrameCount); } break; - case INPUT_OPENED: - case INPUT_CLOSED: - case INPUT_CONFIG_CHANGED: - break; + } +} +status_t AudioSystem::AudioFlingerClient::getInputBufferSize( + uint32_t sampleRate, audio_format_t format, + audio_channel_mask_t channelMask, size_t* buffSize) +{ + const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); + if (af == 0) { + return PERMISSION_DENIED; } + Mutex::Autolock _l(mLock); + // Do we have a stale mInBuffSize or are we requesting the input buffer size for new values + if ((mInBuffSize == 0) || (sampleRate != mInSamplingRate) || (format != mInFormat) + || (channelMask != mInChannelMask)) { + size_t inBuffSize = af->getInputBufferSize(sampleRate, format, channelMask); + if (inBuffSize == 0) { + ALOGE("AudioSystem::getInputBufferSize failed sampleRate %d format %#x channelMask %x", + sampleRate, format, channelMask); + return BAD_VALUE; + } + // A benign race is possible here: we could overwrite a fresher cache entry + // save the request params + mInSamplingRate = sampleRate; + mInFormat = format; + mInChannelMask = channelMask; + + mInBuffSize = inBuffSize; + } + + *buffSize = mInBuffSize; + + return NO_ERROR; +} + +sp<AudioIoDescriptor> AudioSystem::AudioFlingerClient::getIoDescriptor(audio_io_handle_t ioHandle) +{ + sp<AudioIoDescriptor> desc; + ssize_t index = mIoDescriptors.indexOfKey(ioHandle); + if (index >= 0) { + desc = mIoDescriptors.valueAt(index); + } + return desc; } /*static*/ void AudioSystem::setErrorCallback(audio_error_callback cb) @@ -869,9 +864,8 @@ void AudioSystem::clearAudioConfigCache() { // called by restoreTrack_l(), which needs new IAudioFlinger and IAudioPolicyService instances ALOGV("clearAudioConfigCache()"); - { - Mutex::Autolock _l(gLockCache); - gOutputs.clear(); + if (gAudioFlingerClient != 0) { + gAudioFlingerClient->clearIoCache(); } { Mutex::Autolock _l(gLock); diff --git a/media/libmedia/IAudioFlingerClient.cpp b/media/libmedia/IAudioFlingerClient.cpp index 641e6c1..a622241 100644 --- a/media/libmedia/IAudioFlingerClient.cpp +++ b/media/libmedia/IAudioFlingerClient.cpp @@ -39,25 +39,17 @@ public: { } - void ioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2) + void ioConfigChanged(audio_io_config_event event, const sp<AudioIoDescriptor>& ioDesc) { Parcel data, reply; data.writeInterfaceToken(IAudioFlingerClient::getInterfaceDescriptor()); data.writeInt32(event); - data.writeInt32((int32_t) ioHandle); - if (event == AudioSystem::STREAM_CONFIG_CHANGED) { - uint32_t stream = *(const uint32_t *)param2; - ALOGV("ioConfigChanged stream %d", stream); - data.writeInt32(stream); - } else if (event != AudioSystem::OUTPUT_CLOSED && event != AudioSystem::INPUT_CLOSED) { - const AudioSystem::OutputDescriptor *desc = - (const AudioSystem::OutputDescriptor *)param2; - data.writeInt32(desc->samplingRate); - data.writeInt32(desc->format); - data.writeInt32(desc->channelMask); - data.writeInt64(desc->frameCount); - data.writeInt32(desc->latency); - } + data.writeInt32((int32_t)ioDesc->mIoHandle); + data.writeInt32(ioDesc->mSamplingRate); + data.writeInt32(ioDesc->mFormat); + data.writeInt32(ioDesc->mChannelMask); + data.writeInt64(ioDesc->mFrameCount); + data.writeInt32(ioDesc->mLatency); remote()->transact(IO_CONFIG_CHANGED, data, &reply, IBinder::FLAG_ONEWAY); } }; @@ -72,24 +64,15 @@ status_t BnAudioFlingerClient::onTransact( switch (code) { case IO_CONFIG_CHANGED: { CHECK_INTERFACE(IAudioFlingerClient, data, reply); - int event = data.readInt32(); - audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32(); - const void *param2 = NULL; - AudioSystem::OutputDescriptor desc; - uint32_t stream; - if (event == AudioSystem::STREAM_CONFIG_CHANGED) { - stream = data.readInt32(); - param2 = &stream; - ALOGV("STREAM_CONFIG_CHANGED stream %d", stream); - } else if (event != AudioSystem::OUTPUT_CLOSED && event != AudioSystem::INPUT_CLOSED) { - desc.samplingRate = data.readInt32(); - desc.format = (audio_format_t) data.readInt32(); - desc.channelMask = (audio_channel_mask_t) data.readInt32(); - desc.frameCount = data.readInt64(); - desc.latency = data.readInt32(); - param2 = &desc; - } - ioConfigChanged(event, ioHandle, param2); + audio_io_config_event event = (audio_io_config_event)data.readInt32(); + sp<AudioIoDescriptor> ioDesc = new AudioIoDescriptor(); + ioDesc->mIoHandle = (audio_io_handle_t) data.readInt32(); + ioDesc->mSamplingRate = data.readInt32(); + ioDesc->mFormat = (audio_format_t) data.readInt32(); + ioDesc->mChannelMask = (audio_channel_mask_t) data.readInt32(); + ioDesc->mFrameCount = data.readInt64(); + ioDesc->mLatency = data.readInt32(); + ioConfigChanged(event, ioDesc); return NO_ERROR; } break; default: diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 64e9fea..bd6889d 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1268,11 +1268,11 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client) // the config change is always sent from playback or record threads to avoid deadlock // with AudioSystem::gLock for (size_t i = 0; i < mPlaybackThreads.size(); i++) { - mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AudioSystem::OUTPUT_OPENED); + mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_OPENED); } for (size_t i = 0; i < mRecordThreads.size(); i++) { - mRecordThreads.valueAt(i)->sendIoConfigEvent(AudioSystem::INPUT_OPENED); + mRecordThreads.valueAt(i)->sendIoConfigEvent(AUDIO_INPUT_OPENED); } } } @@ -1306,14 +1306,13 @@ void AudioFlinger::removeNotificationClient(pid_t pid) } } -void AudioFlinger::audioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2) +void AudioFlinger::ioConfigChanged(audio_io_config_event event, + const sp<AudioIoDescriptor>& ioDesc) { Mutex::Autolock _l(mClientLock); size_t size = mNotificationClients.size(); for (size_t i = 0; i < size; i++) { - mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, - ioHandle, - param2); + mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, ioDesc); } } @@ -1832,7 +1831,7 @@ status_t AudioFlinger::openOutput(audio_module_handle_t module, *latencyMs = thread->latency(); // notify client processes of the new output creation - thread->audioConfigChanged(AudioSystem::OUTPUT_OPENED); + thread->ioConfigChanged(AUDIO_OUTPUT_OPENED); // the first primary output opened designates the primary hw device if ((mPrimaryHardwareDev == NULL) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) { @@ -1870,7 +1869,7 @@ audio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1, thread->addOutputTrack(thread2); mPlaybackThreads.add(id, thread); // notify client processes of the new output creation - thread->audioConfigChanged(AudioSystem::OUTPUT_OPENED); + thread->ioConfigChanged(AUDIO_OUTPUT_OPENED); return id; } @@ -1920,7 +1919,9 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output) } } } - audioConfigChanged(AudioSystem::OUTPUT_CLOSED, output, NULL); + const sp<AudioIoDescriptor> ioDesc = new AudioIoDescriptor(); + ioDesc->mIoHandle = output; + ioConfigChanged(AUDIO_OUTPUT_CLOSED, ioDesc); } thread->exit(); // The thread entity (active unit of execution) is no longer running here, @@ -1998,7 +1999,7 @@ status_t AudioFlinger::openInput(audio_module_handle_t module, if (thread != 0) { // notify client processes of the new input creation - thread->audioConfigChanged(AudioSystem::INPUT_OPENED); + thread->ioConfigChanged(AUDIO_INPUT_OPENED); return NO_ERROR; } return NO_INIT; @@ -2181,7 +2182,9 @@ status_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input) putOrphanEffectChain_l(chain); } } - audioConfigChanged(AudioSystem::INPUT_CLOSED, input, NULL); + const sp<AudioIoDescriptor> ioDesc = new AudioIoDescriptor(); + ioDesc->mIoHandle = input; + ioConfigChanged(AUDIO_INPUT_CLOSED, ioDesc); mRecordThreads.removeItem(input); } // FIXME: calling thread->exit() without mLock held should not be needed anymore now that diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 34ec2b1..8085ec2 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -545,7 +545,8 @@ private: // no range check, doesn't check per-thread stream volume, AudioFlinger::mLock held float streamVolume_l(audio_stream_type_t stream) const { return mStreamTypes[stream].volume; } - void audioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2); + void ioConfigChanged(audio_io_config_event event, + const sp<AudioIoDescriptor>& ioDesc); // Allocate an audio_io_handle_t, session ID, effect ID, or audio_module_handle_t. // They all share the same ID space, but the namespaces are actually independent diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 234e45f..fa00b47 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -584,16 +584,16 @@ status_t AudioFlinger::ThreadBase::sendConfigEvent_l(sp<ConfigEvent>& event) return status; } -void AudioFlinger::ThreadBase::sendIoConfigEvent(int event, int param) +void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event) { Mutex::Autolock _l(mLock); - sendIoConfigEvent_l(event, param); + sendIoConfigEvent_l(event); } // sendIoConfigEvent_l() must be called with ThreadBase::mLock held -void AudioFlinger::ThreadBase::sendIoConfigEvent_l(int event, int param) +void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event) { - sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event, param); + sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event); sendConfigEvent_l(configEvent); } @@ -657,7 +657,7 @@ void AudioFlinger::ThreadBase::processConfigEvents_l() } break; case CFG_EVENT_IO: { IoConfigEventData *data = (IoConfigEventData *)event->mData.get(); - audioConfigChanged(data->mEvent, data->mParam); + ioConfigChanged(data->mEvent); } break; case CFG_EVENT_SET_PARAMETER: { SetParameterConfigEventData *data = (SetParameterConfigEventData *)event->mData.get(); @@ -1921,32 +1921,28 @@ String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys) return out_s8; } -void AudioFlinger::PlaybackThread::audioConfigChanged(int event, int param) { - AudioSystem::OutputDescriptor desc; - void *param2 = NULL; +void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event) { + sp<AudioIoDescriptor> desc = new AudioIoDescriptor(); + ALOGV("PlaybackThread::ioConfigChanged, thread %p, event %d", this, event); - ALOGV("PlaybackThread::audioConfigChanged, thread %p, event %d, param %d", this, event, - param); + desc->mIoHandle = mId; switch (event) { - case AudioSystem::OUTPUT_OPENED: - case AudioSystem::OUTPUT_CONFIG_CHANGED: - desc.channelMask = mChannelMask; - desc.samplingRate = mSampleRate; - desc.format = mFormat; - desc.frameCount = mNormalFrameCount; // FIXME see + case AUDIO_OUTPUT_OPENED: + case AUDIO_OUTPUT_CONFIG_CHANGED: + desc->mChannelMask = mChannelMask; + desc->mSamplingRate = mSampleRate; + desc->mFormat = mFormat; + desc->mFrameCount = mNormalFrameCount; // FIXME see // AudioFlinger::frameCount(audio_io_handle_t) - desc.latency = latency_l(); - param2 = &desc; + desc->mLatency = latency_l(); break; - case AudioSystem::STREAM_CONFIG_CHANGED: - param2 = ¶m; - case AudioSystem::OUTPUT_CLOSED: + case AUDIO_OUTPUT_CLOSED: default: break; } - mAudioFlinger->audioConfigChanged(event, mId, param2); + mAudioFlinger->ioConfigChanged(event, desc); } void AudioFlinger::PlaybackThread::writeCallback() @@ -4203,7 +4199,7 @@ bool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePa } mTracks[i]->mName = name; } - sendIoConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED); + sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); } } @@ -4655,7 +4651,7 @@ bool AudioFlinger::DirectOutputThread::checkForNewParameter_l(const String8& key } if (status == NO_ERROR && reconfig) { readOutputParameters_l(); - sendIoConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED); + sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); } } @@ -6701,7 +6697,7 @@ bool AudioFlinger::RecordThread::checkForNewParameter_l(const String8& keyValueP } if (status == NO_ERROR) { readInputParameters_l(); - sendIoConfigEvent_l(AudioSystem::INPUT_CONFIG_CHANGED); + sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED); } } } @@ -6722,26 +6718,26 @@ String8 AudioFlinger::RecordThread::getParameters(const String8& keys) return out_s8; } -void AudioFlinger::RecordThread::audioConfigChanged(int event, int param __unused) { - AudioSystem::OutputDescriptor desc; - const void *param2 = NULL; +void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event) { + sp<AudioIoDescriptor> desc = new AudioIoDescriptor(); + + desc->mIoHandle = mId; switch (event) { - case AudioSystem::INPUT_OPENED: - case AudioSystem::INPUT_CONFIG_CHANGED: - desc.channelMask = mChannelMask; - desc.samplingRate = mSampleRate; - desc.format = mFormat; - desc.frameCount = mFrameCount; - desc.latency = 0; - param2 = &desc; + case AUDIO_INPUT_OPENED: + case AUDIO_INPUT_CONFIG_CHANGED: + desc->mChannelMask = mChannelMask; + desc->mSamplingRate = mSampleRate; + desc->mFormat = mFormat; + desc->mFrameCount = mFrameCount; + desc->mLatency = 0; break; - case AudioSystem::INPUT_CLOSED: + case AUDIO_INPUT_CLOSED: default: break; } - mAudioFlinger->audioConfigChanged(event, mId, param2); + mAudioFlinger->ioConfigChanged(event, desc); } void AudioFlinger::RecordThread::readInputParameters_l() diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index 2c514f8..066090b 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -100,22 +100,21 @@ public: class IoConfigEventData : public ConfigEventData { public: - IoConfigEventData(int event, int param) : - mEvent(event), mParam(param) {} + IoConfigEventData(audio_io_config_event event) : + mEvent(event) {} virtual void dump(char *buffer, size_t size) { - snprintf(buffer, size, "IO event: event %d, param %d\n", mEvent, mParam); + snprintf(buffer, size, "IO event: event %d\n", mEvent); } - const int mEvent; - const int mParam; + const audio_io_config_event mEvent; }; class IoConfigEvent : public ConfigEvent { public: - IoConfigEvent(int event, int param) : + IoConfigEvent(audio_io_config_event event) : ConfigEvent(CFG_EVENT_IO) { - mData = new IoConfigEventData(event, param); + mData = new IoConfigEventData(event); } virtual ~IoConfigEvent() {} }; @@ -250,13 +249,13 @@ public: status_t& status) = 0; virtual status_t setParameters(const String8& keyValuePairs); virtual String8 getParameters(const String8& keys) = 0; - virtual void audioConfigChanged(int event, int param = 0) = 0; + virtual void ioConfigChanged(audio_io_config_event event) = 0; // sendConfigEvent_l() must be called with ThreadBase::mLock held // Can temporarily release the lock if waiting for a reply from // processConfigEvents_l(). status_t sendConfigEvent_l(sp<ConfigEvent>& event); - void sendIoConfigEvent(int event, int param = 0); - void sendIoConfigEvent_l(int event, int param = 0); + void sendIoConfigEvent(audio_io_config_event event); + void sendIoConfigEvent_l(audio_io_config_event event); void sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio); status_t sendSetParameterConfigEvent_l(const String8& keyValuePair); status_t sendCreateAudioPatchConfigEvent(const struct audio_patch *patch, @@ -560,7 +559,7 @@ public: { return android_atomic_acquire_load(&mSuspended) > 0; } virtual String8 getParameters(const String8& keys); - virtual void audioConfigChanged(int event, int param = 0); + virtual void ioConfigChanged(audio_io_config_event event); status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames); // FIXME rename mixBuffer() to sinkBuffer() and remove int16_t* dependency. // Consider also removing and passing an explicit mMainBuffer initialization @@ -1230,7 +1229,7 @@ public: status_t& status); virtual void cacheParameters_l() {} virtual String8 getParameters(const String8& keys); - virtual void audioConfigChanged(int event, int param = 0); + virtual void ioConfigChanged(audio_io_config_event event); virtual status_t createAudioPatch_l(const struct audio_patch *patch, audio_patch_handle_t *handle); virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle); |