diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp index b1cb0e7bdd..cb46b93c05 100644 --- a/media/libaudioclient/AudioEffect.cpp +++ b/media/libaudioclient/AudioEffect.cpp @@ -430,14 +430,15 @@ status_t AudioEffect::queryEffect(uint32_t index, effect_descriptor_t *descripto } status_t AudioEffect::getEffectDescriptor(const effect_uuid_t *uuid, - effect_descriptor_t *descriptor) /*const*/ + const effect_uuid_t *type, + uint32_t preferredTypeFlag, + effect_descriptor_t *descriptor) { const sp& af = AudioSystem::get_audio_flinger(); if (af == 0) return PERMISSION_DENIED; - return af->getEffectDescriptor(uuid, descriptor); + return af->getEffectDescriptor(uuid, type, preferredTypeFlag, descriptor); } - status_t AudioEffect::queryDefaultPreProcessing(audio_session_t audioSession, effect_descriptor_t *descriptors, uint32_t *count) diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp index 84e8beef17..aca95db0c9 100644 --- a/media/libaudioclient/IAudioFlinger.cpp +++ b/media/libaudioclient/IAudioFlinger.cpp @@ -598,14 +598,18 @@ public: } virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid, - effect_descriptor_t *pDescriptor) const + const effect_uuid_t *pType, + uint32_t preferredTypeFlag, + effect_descriptor_t *pDescriptor) const { - if (pUuid == NULL || pDescriptor == NULL) { + if (pUuid == NULL || pType == NULL || pDescriptor == NULL) { return BAD_VALUE; } Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); data.write(pUuid, sizeof(effect_uuid_t)); + data.write(pType, sizeof(effect_uuid_t)); + data.writeUint32(preferredTypeFlag); status_t status = remote()->transact(GET_EFFECT_DESCRIPTOR, data, &reply); if (status != NO_ERROR) { return status; @@ -1277,8 +1281,11 @@ status_t BnAudioFlinger::onTransact( CHECK_INTERFACE(IAudioFlinger, data, reply); effect_uuid_t uuid; data.read(&uuid, sizeof(effect_uuid_t)); + effect_uuid_t type; + data.read(&type, sizeof(effect_uuid_t)); + uint32_t preferredTypeFlag = data.readUint32(); effect_descriptor_t desc = {}; - status_t status = getEffectDescriptor(&uuid, &desc); + status_t status = getEffectDescriptor(&uuid, &type, preferredTypeFlag, &desc); reply->writeInt32(status); if (status == NO_ERROR) { reply->write(&desc, sizeof(effect_descriptor_t)); diff --git a/media/libaudioclient/include/media/AudioEffect.h b/media/libaudioclient/include/media/AudioEffect.h index bfc068b389..ae66e8f2d4 100644 --- a/media/libaudioclient/include/media/AudioEffect.h +++ b/media/libaudioclient/include/media/AudioEffect.h @@ -90,27 +90,34 @@ public: */ static status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor); - /* - * Returns the descriptor for the specified effect uuid. + * Returns a descriptor for the specified effect uuid or type. + * + * Lookup an effect by uuid, or if that's unspecified (EFFECT_UUID_NULL), + * do so by type and preferred flags instead. * * Parameters: * uuid: pointer to effect uuid. + * type: pointer to effect type uuid. + * preferredTypeFlags: if multiple effects of the given type exist, + * one with a matching type flag will be chosen over one without. + * Use EFFECT_FLAG_TYPE_MASK to indicate no preference. * descriptor: address where the effect descriptor should be returned. * * Returned status (from utils/Errors.h) can be: * NO_ERROR successful operation. * PERMISSION_DENIED could not get AudioFlinger interface * NO_INIT effect library failed to initialize - * BAD_VALUE invalid uuid or descriptor pointers + * BAD_VALUE invalid type or descriptor pointers * NAME_NOT_FOUND no effect with this uuid found * * Returned value * *descriptor updated with effect descriptor */ static status_t getEffectDescriptor(const effect_uuid_t *uuid, - effect_descriptor_t *descriptor) /*const*/; - + const effect_uuid_t *type, + uint32_t preferredTypeFlag, + effect_descriptor_t *descriptor); /* * Returns a list of descriptors corresponding to the pre processings enabled by default diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h index e6bf72f547..31326abf46 100644 --- a/media/libaudioclient/include/media/IAudioFlinger.h +++ b/media/libaudioclient/include/media/IAudioFlinger.h @@ -428,7 +428,9 @@ public: virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) const = 0; virtual status_t getEffectDescriptor(const effect_uuid_t *pEffectUUID, - effect_descriptor_t *pDescriptor) const = 0; + const effect_uuid_t *pTypeUUID, + uint32_t preferredTypeFlag, + effect_descriptor_t *pDescriptor) const = 0; virtual sp createEffect( effect_descriptor_t *pDesc, diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 9234364248..38483c35a5 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -2949,16 +2949,74 @@ status_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descript } status_t AudioFlinger::getEffectDescriptor(const effect_uuid_t *pUuid, - effect_descriptor_t *descriptor) const + const effect_uuid_t *pTypeUuid, + uint32_t preferredTypeFlag, + effect_descriptor_t *descriptor) const { + if (pUuid == NULL || pTypeUuid == NULL || descriptor == NULL) { + return BAD_VALUE; + } + Mutex::Autolock _l(mLock); - if (mEffectsFactoryHal.get()) { - return mEffectsFactoryHal->getDescriptor(pUuid, descriptor); - } else { + + if (!mEffectsFactoryHal.get()) { return -ENODEV; } -} + status_t status = NO_ERROR; + if (!EffectsFactoryHalInterface::isNullUuid(pUuid)) { + // If uuid is specified, request effect descriptor from that. + status = mEffectsFactoryHal->getDescriptor(pUuid, descriptor); + } else if (!EffectsFactoryHalInterface::isNullUuid(pTypeUuid)) { + // If uuid is not specified, look for an available implementation + // of the required type instead. + + // Use a temporary descriptor to avoid modifying |descriptor| in the failure case. + effect_descriptor_t desc; + desc.flags = 0; // prevent compiler warning + + uint32_t numEffects = 0; + status = mEffectsFactoryHal->queryNumberEffects(&numEffects); + if (status < 0) { + ALOGW("getEffectDescriptor() error %d from FactoryHal queryNumberEffects", status); + return status; + } + + bool found = false; + for (uint32_t i = 0; i < numEffects; i++) { + status = mEffectsFactoryHal->getDescriptor(i, &desc); + if (status < 0) { + ALOGW("getEffectDescriptor() error %d from FactoryHal getDescriptor", status); + continue; + } + if (memcmp(&desc.type, pTypeUuid, sizeof(effect_uuid_t)) == 0) { + // If matching type found save effect descriptor. + found = true; + *descriptor = desc; + + // If there's no preferred flag or this descriptor matches the preferred + // flag, success! If this descriptor doesn't match the preferred + // flag, continue enumeration in case a better matching version of this + // effect type is available. Note that this means if no effect with a + // correct flag is found, the descriptor returned will correspond to the + // last effect that at least had a matching type uuid (if any). + if (preferredTypeFlag == EFFECT_FLAG_TYPE_MASK || + (desc.flags & EFFECT_FLAG_TYPE_MASK) == preferredTypeFlag) { + break; + } + } + } + + if (!found) { + status = NAME_NOT_FOUND; + ALOGW("getEffectDescriptor(): Effect not found by type."); + } + } else { + status = BAD_VALUE; + ALOGE("getEffectDescriptor(): Either uuid or type uuid must be non-null UUIDs."); + } + return status; +} sp AudioFlinger::createEffect( effect_descriptor_t *pDesc, @@ -3012,60 +3070,15 @@ sp AudioFlinger::createEffect( } { - if (!EffectsFactoryHalInterface::isNullUuid(&pDesc->uuid)) { - // if uuid is specified, request effect descriptor - lStatus = mEffectsFactoryHal->getDescriptor(&pDesc->uuid, &desc); - if (lStatus < 0) { - ALOGW("createEffect() error %d from EffectGetDescriptor", lStatus); - goto Exit; - } - } else { - // if uuid is not specified, look for an available implementation - // of the required type in effect factory - if (EffectsFactoryHalInterface::isNullUuid(&pDesc->type)) { - ALOGW("createEffect() no effect type"); - lStatus = BAD_VALUE; - goto Exit; - } - uint32_t numEffects = 0; - effect_descriptor_t d; - d.flags = 0; // prevent compiler warning - bool found = false; - - lStatus = mEffectsFactoryHal->queryNumberEffects(&numEffects); - if (lStatus < 0) { - ALOGW("createEffect() error %d from EffectQueryNumberEffects", lStatus); - goto Exit; - } - for (uint32_t i = 0; i < numEffects; i++) { - lStatus = mEffectsFactoryHal->getDescriptor(i, &desc); - if (lStatus < 0) { - ALOGW("createEffect() error %d from EffectQueryEffect", lStatus); - continue; - } - if (memcmp(&desc.type, &pDesc->type, sizeof(effect_uuid_t)) == 0) { - // If matching type found save effect descriptor. If the session is - // 0 and the effect is not auxiliary, continue enumeration in case - // an auxiliary version of this effect type is available - found = true; - d = desc; - if (sessionId != AUDIO_SESSION_OUTPUT_MIX || - (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { - break; - } - } - } - if (!found) { - lStatus = BAD_VALUE; - ALOGW("createEffect() effect not found"); - goto Exit; - } - // For same effect type, chose auxiliary version over insert version if - // connect to output mix (Compliance to OpenSL ES) - if (sessionId == AUDIO_SESSION_OUTPUT_MIX && - (d.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_AUXILIARY) { - desc = d; - } + // Get the full effect descriptor from the uuid/type. + // If the session is the output mix, prefer an auxiliary effect, + // otherwise no preference. + uint32_t preferredType = (sessionId == AUDIO_SESSION_OUTPUT_MIX ? + EFFECT_FLAG_TYPE_AUXILIARY : EFFECT_FLAG_TYPE_MASK); + lStatus = getEffectDescriptor(&pDesc->uuid, &pDesc->type, preferredType, &desc); + if (lStatus < 0) { + ALOGW("createEffect() error %d from getEffectDescriptor", lStatus); + goto Exit; } // Do not allow auxiliary effects on a session different from 0 (output mix) diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 95b947cbdf..9b9a15dfe2 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -208,6 +208,8 @@ public: virtual status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor) const; virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid, + const effect_uuid_t *pTypeUuid, + uint32_t preferredTypeFlag, effect_descriptor_t *descriptor) const; virtual sp createEffect(