diff options
author | Glenn Kasten <gkasten@google.com> | 2013-10-30 14:37:01 -0700 |
---|---|---|
committer | Jean-Michel Trivi <jmtrivi@google.com> | 2013-11-06 18:05:09 +0000 |
commit | 49c34acbef91800930b0fe561e0787145a10cfcc (patch) | |
tree | 53e636df1a5868bbea112ec3bd36e19862208adf /services | |
parent | d21952fe5bc94f7bb6ee729f806c0e641fdb1a0d (diff) | |
download | frameworks_av-49c34acbef91800930b0fe561e0787145a10cfcc.zip frameworks_av-49c34acbef91800930b0fe561e0787145a10cfcc.tar.gz frameworks_av-49c34acbef91800930b0fe561e0787145a10cfcc.tar.bz2 |
Fix race condition in initializing downmix
The code that initializes downmix GUID searches for an effect of
the right type. If two or more AudioMixers are created, there is a
possibility that the GUID will temporarily have the wrong value.
Now the initialization is only done once, regardless of how many
AudioMixers there are.
Other minor changes:
- use naming convention of leading 's' for static member variables
- log message for no downmix effect is now a warning instead of an error,
since it is not an error until there is actual content to downmix
without a downmix effect
Change-Id: I33ab0e51cf9d24ecaf8ae868883736b0772178c4
Diffstat (limited to 'services')
-rw-r--r-- | services/audioflinger/AudioMixer.cpp | 51 | ||||
-rw-r--r-- | services/audioflinger/AudioMixer.h | 4 |
2 files changed, 28 insertions, 27 deletions
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index 91aedbb..5fe5fcb 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -90,9 +90,9 @@ void AudioMixer::DownmixerBufferProvider::releaseBuffer(AudioBufferProvider::Buf // ---------------------------------------------------------------------------- -bool AudioMixer::isMultichannelCapable = false; +bool AudioMixer::sIsMultichannelCapable = false; -effect_descriptor_t AudioMixer::dwnmFxDesc; +effect_descriptor_t AudioMixer::sDwnmFxDesc; // Ensure mConfiguredNames bitmask is initialized properly on all architectures. // The value of 1 << x is undefined in C when x >= 32. @@ -136,27 +136,6 @@ AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTr t++; } - // find multichannel downmix effect if we have to play multichannel content - uint32_t numEffects = 0; - int ret = EffectQueryNumberEffects(&numEffects); - if (ret != 0) { - ALOGE("AudioMixer() error %d querying number of effects", ret); - return; - } - ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects); - - for (uint32_t i = 0 ; i < numEffects ; i++) { - if (EffectQueryEffect(i, &dwnmFxDesc) == 0) { - ALOGV("effect %d is called %s", i, dwnmFxDesc.name); - if (memcmp(&dwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) { - ALOGI("found effect \"%s\" from %s", - dwnmFxDesc.name, dwnmFxDesc.implementor); - isMultichannelCapable = true; - break; - } - } - } - ALOGE_IF(!isMultichannelCapable, "unable to find downmix effect"); } AudioMixer::~AudioMixer() @@ -276,13 +255,13 @@ status_t AudioMixer::prepareTrackForDownmix(track_t* pTrack, int trackName) DownmixerBufferProvider* pDbp = new DownmixerBufferProvider(); int32_t status; - if (!isMultichannelCapable) { + if (!sIsMultichannelCapable) { ALOGE("prepareTrackForDownmix(%d) fails: mixer doesn't support multichannel content", trackName); goto noDownmixForActiveTrack; } - if (EffectCreate(&dwnmFxDesc.uuid, + if (EffectCreate(&sDwnmFxDesc.uuid, pTrack->sessionId /*sessionId*/, -2 /*ioId not relevant here, using random value*/, &pDbp->mDownmixHandle/*pHandle*/) != 0) { ALOGE("prepareTrackForDownmix(%d) fails: error creating downmixer effect", trackName); @@ -1459,6 +1438,28 @@ int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS, { LocalClock lc; sLocalTimeFreq = lc.getLocalFreq(); + + // find multichannel downmix effect if we have to play multichannel content + uint32_t numEffects = 0; + int ret = EffectQueryNumberEffects(&numEffects); + if (ret != 0) { + ALOGE("AudioMixer() error %d querying number of effects", ret); + return; + } + ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects); + + for (uint32_t i = 0 ; i < numEffects ; i++) { + if (EffectQueryEffect(i, &sDwnmFxDesc) == 0) { + ALOGV("effect %d is called %s", i, sDwnmFxDesc.name); + if (memcmp(&sDwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) { + ALOGI("found effect \"%s\" from %s", + sDwnmFxDesc.name, sDwnmFxDesc.implementor); + sIsMultichannelCapable = true; + break; + } + } + } + ALOGW_IF(!sIsMultichannelCapable, "unable to find downmix effect"); } // ---------------------------------------------------------------------------- diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h index 43aeb86..a15bdca 100644 --- a/services/audioflinger/AudioMixer.h +++ b/services/audioflinger/AudioMixer.h @@ -256,9 +256,9 @@ private: state_t mState __attribute__((aligned(32))); // effect descriptor for the downmixer used by the mixer - static effect_descriptor_t dwnmFxDesc; + static effect_descriptor_t sDwnmFxDesc; // indicates whether a downmix effect has been found and is usable by this mixer - static bool isMultichannelCapable; + static bool sIsMultichannelCapable; // Call after changing either the enabled status of a track, or parameters of an enabled track. // OK to call more often than that, but unnecessary. |