// This will find the library and UUID tags of the sub effect pointed by the
// node, gets the effect descriptor and lib_entry_t and adds the subeffect -
// sub_entry_t to the gSubEffectList
int addSubEffect(cnode *root)
{
    ALOGV("addSubEffect");
    cnode *node;
    effect_uuid_t uuid;
    effect_descriptor_t *d;
    lib_entry_t *l;
    list_elem_t *e;
    node = config_find(root, LIBRARY_TAG);
    if (node == NULL) {
        return -EINVAL;
    }
    l = getLibrary(node->value);
    if (l == NULL) {
        ALOGW("addSubEffect() could not get library %s", node->value);
        return -EINVAL;
    }
    node = config_find(root, UUID_TAG);
    if (node == NULL) {
        return -EINVAL;
    }
    if (stringToUuid(node->value, &uuid) != 0) {
        ALOGW("addSubEffect() invalid uuid %s", node->value);
        return -EINVAL;
    }
    d = malloc(sizeof(effect_descriptor_t));
    if (l->desc->get_descriptor(&uuid, d) != 0) {
        char s[40];
        uuidToString(&uuid, s, 40);
        ALOGW("Error querying effect %s on lib %s", s, l->name);
        free(d);
        return -EINVAL;
    }
#if (LOG_NDEBUG==0)
    char s[256];
    dumpEffectDescriptor(d, s, 256);
    ALOGV("addSubEffect() read descriptor %p:%s",d, s);
#endif
    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
        ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
        free(d);
        return -EINVAL;
    }
    sub_effect_entry_t *sub_effect = malloc(sizeof(sub_effect_entry_t));
    sub_effect->object = d;
    // lib_entry_t is stored since the sub effects are not linked to the library
    sub_effect->lib = l;
    e = malloc(sizeof(list_elem_t));
    e->object = sub_effect;
    e->next = gSubEffectList->sub_elem;
    gSubEffectList->sub_elem = e;
    ALOGV("addSubEffect end");
    return 0;
}
示例#2
0
int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor)
{
    int ret = init();
    if (ret < 0) {
        return ret;
    }
    if (pDescriptor == NULL ||
        index >= gNumEffects) {
        return -EINVAL;
    }
    if (gCanQueryEffect == 0) {
        return -ENOSYS;
    }

    pthread_mutex_lock(&gLibLock);
    ret = -ENOENT;
    if (index < gCurEffectIdx) {
        resetEffectEnumeration();
    }
    while (gCurLib) {
        if (gCurEffect) {
            if (index == gCurEffectIdx) {
                memcpy(pDescriptor, gCurEffect->object, sizeof(effect_descriptor_t));
                ret = 0;
                break;
            } else {
                gCurEffect = gCurEffect->next;
                gCurEffectIdx++;
            }
        } else {
            gCurLib = gCurLib->next;
            gCurEffect = ((lib_entry_t *)gCurLib->object)->effects;
        }
    }

#if (LOG_NDEBUG == 0)
    char str[256];
    dumpEffectDescriptor(pDescriptor, str, 256);
    LOGV("EffectQueryEffect() desc:%s", str);
#endif
    pthread_mutex_unlock(&gLibLock);
    return ret;
}
示例#3
0
int loadLibrary(const char *libPath, int *handle)
{
    void *hdl;
    effect_QueryNumberEffects_t queryNumFx;
    effect_QueryEffect_t queryFx;
    effect_CreateEffect_t createFx;
    effect_ReleaseEffect_t releaseFx;
    uint32_t numFx;
    uint32_t fx;
    int ret;
    list_elem_t *e, *descHead = NULL;
    lib_entry_t *l;

    if (handle == NULL) {
        return -EINVAL;
    }

    *handle = 0;

    hdl = dlopen(libPath, RTLD_NOW);
    if (hdl == 0) {
        LOGW("could open lib %s", libPath);
        return -ENODEV;
    }

    // Check functions availability
    queryNumFx = (effect_QueryNumberEffects_t)dlsym(hdl, "EffectQueryNumberEffects");
    if (queryNumFx == NULL) {
        LOGW("could not get EffectQueryNumberEffects from lib %s", libPath);
        ret = -ENODEV;
        goto error;
    }
    queryFx = (effect_QueryEffect_t)dlsym(hdl, "EffectQueryEffect");
    if (queryFx == NULL) {
        LOGW("could not get EffectQueryEffect from lib %s", libPath);
        ret = -ENODEV;
        goto error;
    }
    createFx = (effect_CreateEffect_t)dlsym(hdl, "EffectCreate");
    if (createFx == NULL) {
        LOGW("could not get EffectCreate from lib %s", libPath);
        ret = -ENODEV;
        goto error;
    }
    releaseFx = (effect_ReleaseEffect_t)dlsym(hdl, "EffectRelease");
    if (releaseFx == NULL) {
        LOGW("could not get EffectRelease from lib %s", libPath);
        ret = -ENODEV;
        goto error;
    }

    // load effect descriptors
    ret = queryNumFx(&numFx);
    if (ret) {
        goto error;
    }

    for (fx = 0; fx < numFx; fx++) {
        effect_descriptor_t *d = malloc(sizeof(effect_descriptor_t));
        if (d == NULL) {
            ret = -ENOMEM;
            goto error;
        }
        ret = queryFx(fx, d);
        if (ret == 0) {
#if (LOG_NDEBUG==0)
            char s[256];
            dumpEffectDescriptor(d, s, 256);
            LOGV("loadLibrary() read descriptor %p:%s",d, s);
#endif
            if (d->apiVersion != EFFECT_API_VERSION) {
                LOGW("Bad API version %04x on lib %s", d->apiVersion, libPath);
                free(d);
                continue;
            }
            e = malloc(sizeof(list_elem_t));
            if (e == NULL) {
                free(d);
                ret = -ENOMEM;
                goto error;
            }
            e->object = d;
            e->next = descHead;
            descHead = e;
        } else {
            LOGW("Error querying effect # %d on lib %s", fx, libPath);
        }
    }

    pthread_mutex_lock(&gLibLock);

    // add entry for library in gLibraryList
    l = malloc(sizeof(lib_entry_t));
    l->id = ++gNextLibId;
    l->handle = hdl;
    strncpy(l->path, libPath, PATH_MAX);
    l->createFx = createFx;
    l->releaseFx = releaseFx;
    l->effects = descHead;
    pthread_mutex_init(&l->lock, NULL);

    e = malloc(sizeof(list_elem_t));
    e->next = gLibraryList;
    e->object = l;
    gLibraryList = e;
    pthread_mutex_unlock(&gLibLock);
    LOGV("loadLibrary() linked library %p", l);

    *handle = l->id;

    return 0;

error:
    LOGW("loadLibrary() error: %d on lib: %s", ret, libPath);
    while (descHead) {
        free(descHead->object);
        e = descHead->next;
        free(descHead);
        descHead = e;;
    }
    dlclose(hdl);
    return ret;
}
int loadEffect(cnode *root)
{
    cnode *node;
    effect_uuid_t uuid;
    lib_entry_t *l;
    effect_descriptor_t *d;
    list_elem_t *e;

    node = config_find(root, LIBRARY_TAG);
    if (node == NULL) {
        return -EINVAL;
    }

    l = getLibrary(node->value);
    if (l == NULL) {
        ALOGW("loadEffect() could not get library %s", node->value);
        return -EINVAL;
    }

    node = config_find(root, UUID_TAG);
    if (node == NULL) {
        return -EINVAL;
    }
    if (stringToUuid(node->value, &uuid) != 0) {
        ALOGW("loadEffect() invalid uuid %s", node->value);
        return -EINVAL;
    }
    d = malloc(sizeof(effect_descriptor_t));
    if (!d) {
        ALOGE("failed to allocate effect descriptor");
        return -EINVAL;
    }

    if (l->desc->get_descriptor(&uuid, d) != 0) {
        char s[40];
        uuidToString(&uuid, s, 40);
        ALOGW("Error querying effect %s on lib %s", s, l->name);
        free(d);
        return -EINVAL;
    }
#if (LOG_NDEBUG==0)
    char s[256];
    dumpEffectDescriptor(d, s, 256);
    ALOGV("loadEffect() read descriptor %p:%s",d, s);
#endif
    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
        ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
        free(d);
        return -EINVAL;
    }
    e = malloc(sizeof(list_elem_t));
    if (!e) {
        return -ENOMEM;
    }

    e->object = d;
    e->next = l->effects;
    l->effects = e;

    // After the UUID node in the config_tree, if node->next is valid,
    // that would be sub effect node.
    // Find the sub effects and add them to the gSubEffectList
    node = node->next;
    int count = 2;
    bool hwSubefx = false, swSubefx = false;
    list_sub_elem_t *sube = NULL;
    if (node != NULL) {
        ALOGV("Adding the effect to gEffectSubList as there are sub effects");
        sube = malloc(sizeof(list_sub_elem_t));
        if (!sube) {
            ALOGE("failed to allocate sub element list");
            return -ENOMEM;
        }

        sube->object = d;
        sube->sub_elem = NULL;
        sube->next = gSubEffectList;
        gSubEffectList = sube;
    }
    while (node != NULL && count) {
       if (addSubEffect(node)) {
           ALOGW("loadEffect() could not add subEffect %s", node->value);
           // Change the gSubEffectList to point to older list;
           gSubEffectList = sube->next;
           free(sube->sub_elem);// Free an already added sub effect
           sube->sub_elem = NULL;
           free(sube);
           return -ENOENT;
       }
       sub_effect_entry_t *subEntry = (sub_effect_entry_t*)gSubEffectList->sub_elem->object;
       effect_descriptor_t *subEffectDesc = (effect_descriptor_t*)(subEntry->object);
       // Since we return a dummy descriptor for the proxy during
       // get_descriptor call,we replace it with the correspoding
       // sw effect descriptor, but with Proxy UUID
       // check for Sw desc
        if (!((subEffectDesc->flags & EFFECT_FLAG_HW_ACC_MASK) ==
                                           EFFECT_FLAG_HW_ACC_TUNNEL)) {
             swSubefx = true;
             *d = *subEffectDesc;
             d->uuid = uuid;
             ALOGV("loadEffect() Changed the Proxy desc");
       } else
           hwSubefx = true;
       count--;
       node = node->next;
    }
    // 1 HW and 1 SW sub effect found. Set the offload flag in the Proxy desc
    if (hwSubefx && swSubefx) {
        d->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED;
    }
    return 0;
}