// 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; }
int loadLibrary(cnode *root, const char *name) { cnode *node; void *hdl; audio_effect_library_t *desc; list_elem_t *e; lib_entry_t *l; node = config_find(root, PATH_TAG); if (node == NULL) { return -EINVAL; } hdl = dlopen(node->value, RTLD_NOW); if (hdl == NULL) { ALOGW("loadLibrary() failed to open %s", node->value); goto error; } desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR); if (desc == NULL) { ALOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR); goto error; } if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) { ALOGW("getLibrary() bad tag %08x in lib info struct", desc->tag); goto error; } if (EFFECT_API_VERSION_MAJOR(desc->version) != EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) { ALOGW("loadLibrary() bad lib version %08x", desc->version); goto error; } // add entry for library in gLibraryList l = malloc(sizeof(lib_entry_t)); l->name = strndup(name, PATH_MAX); l->path = strndup(node->value, PATH_MAX); l->handle = hdl; l->desc = desc; l->effects = NULL; pthread_mutex_init(&l->lock, NULL); e = malloc(sizeof(list_elem_t)); e->object = l; pthread_mutex_lock(&gLibLock); e->next = gLibraryList; gLibraryList = e; pthread_mutex_unlock(&gLibLock); ALOGV("getLibrary() linked library %p for path %s", l, node->value); return 0; error: if (hdl != NULL) { dlclose(hdl); } return -EINVAL; }
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; }