Update getEffectDescriptors() to include type

Allows getting effect descriptors by type or uuid,
not just by uuid.

Bug: 78528249
Test: Builds. Manually tested that an app playing audio with an effect works.
Change-Id: I9d339a7d6d81161065e1adaf427dd2d3430436c2
gugelfrei
Ari Hausman-Cohen 6 years ago
parent 965737edc2
commit 2046ec756e

@ -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<IAudioFlinger>& 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)

@ -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));

@ -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

@ -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<IEffect> createEffect(
effect_descriptor_t *pDesc,

@ -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<IEffect> AudioFlinger::createEffect(
effect_descriptor_t *pDesc,
@ -3012,60 +3070,15 @@ sp<IEffect> 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)

@ -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<IEffect> createEffect(

Loading…
Cancel
Save