EffectProxy.cpp revision 5baf2af52cd186633b7173196c1e4a4cd3435f22
1bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang/* 2bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang * Copyright (C) 2013 The Android Open Source Project 3bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang * 4bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang * you may not use this file except in compliance with the License. 6bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang * You may obtain a copy of the License at 7bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang * 8bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang * http://www.apache.org/licenses/LICENSE-2.0 9bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang * 10bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang * Unless required by applicable law or agreed to in writing, software 11bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang * distributed under the License is distributed on an "AS IS" BASIS, 12bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang * See the License for the specific language governing permissions and 14bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang * limitations under the License. 15bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang */ 16bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 17bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang#define LOG_TAG "EffectProxy" 18bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang//#define LOG_NDEBUG 0 19bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 20bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang#include <cutils/log.h> 21bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang#include <assert.h> 22bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang#include <stdlib.h> 23bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang#include <string.h> 24bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang#include <new> 25bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang#include <EffectProxy.h> 26bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang#include <utils/threads.h> 27bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang#include <media/EffectsFactoryApi.h> 28bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 29bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wangnamespace android { 30bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang// This is a dummy proxy descriptor just to return to Factory during the initial 31bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang// GetDescriptor call. Later in the factory, it is replaced with the 32bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang// SW sub effect descriptor 33bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wangconst effect_descriptor_t gProxyDescriptor = { 34bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang EFFECT_UUID_INITIALIZER, // type 35bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang EFFECT_UUID_INITIALIZER, // uuid 36bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang EFFECT_CONTROL_API_VERSION, //version of effect control API 37bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | 38bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang EFFECT_FLAG_VOLUME_CTRL), // effect capability flags 39bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 0, // CPU load 40bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 1, // Data memory 41bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang "Proxy", //effect name 42bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang "AOSP", //implementor name 43bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang}; 44bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 45bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 46bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wangstatic const effect_descriptor_t *const gDescriptors[] = 47bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang{ 48bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang &gProxyDescriptor, 49bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang}; 50bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 51bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wangstatic inline bool isGetterCmd(uint32_t cmdCode) 52bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang{ 53bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang switch (cmdCode) { 54bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang case EFFECT_CMD_GET_PARAM: 55bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang case EFFECT_CMD_GET_CONFIG: 56bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang case EFFECT_CMD_GET_CONFIG_REVERSE: 57bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang case EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: 58bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang case EFFECT_CMD_GET_FEATURE_CONFIG: 59bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return true; 60bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang default: 61bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return false; 62bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 63bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang} 64bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 65bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 66bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wangint EffectProxyCreate(const effect_uuid_t *uuid, 67bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang int32_t sessionId, 68bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang int32_t ioId, 69bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang effect_handle_t *pHandle) { 70bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 71bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang effect_descriptor_t* desc; 72bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang EffectContext* pContext; 73bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (pHandle == NULL || uuid == NULL) { 74bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGE("EffectProxyCreate() called with NULL pointer"); 75bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return -EINVAL; 76bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 77bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("EffectProxyCreate start.."); 78bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext = new EffectContext; 79bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->sessionId = sessionId; 80bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->ioId = ioId; 81bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->uuid = *uuid; 82bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->common_itfe = &gEffectInterface; 83bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // The sub effects will be created in effect_command when the first command 84bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // for the effect is received 85bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->eHandle[SUB_FX_HOST] = pContext->eHandle[SUB_FX_OFFLOAD] = NULL; 86bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 87bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // Get the HW and SW sub effect descriptors from the effects factory 88bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang desc = new effect_descriptor_t[SUB_FX_COUNT]; 89bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->desc = new effect_descriptor_t[SUB_FX_COUNT]; 90bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang int retValue = EffectGetSubEffects(uuid, desc, 91bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang sizeof(effect_descriptor_t) * SUB_FX_COUNT); 92bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // EffectGetSubEffects returns the number of sub-effects copied. 93bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (retValue != SUB_FX_COUNT) { 94bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGE("EffectCreate() could not get the sub effects"); 95bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang delete desc; 96bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang delete pContext->desc; 97bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return -EINVAL; 98bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 99bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // Check which is the HW descriptor and copy the descriptors 100bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // to the Context desc array 101bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // Also check if there is only one HW and one SW descriptor. 102bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // HW descriptor alone has the HW_TUNNEL flag. 103bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if ((desc[0].flags & EFFECT_FLAG_HW_ACC_TUNNEL) && 104bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang !(desc[1].flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { 105bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->desc[SUB_FX_OFFLOAD] = desc[0]; 106bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->desc[SUB_FX_HOST] = desc[1]; 107bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 108bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang else if ((desc[1].flags & EFFECT_FLAG_HW_ACC_TUNNEL) && 109bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang !(desc[0].flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { 110bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->desc[SUB_FX_HOST] = desc[0]; 111bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->desc[SUB_FX_OFFLOAD] = desc[1]; 112bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 113bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang delete desc; 114bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang#if (LOG_NDEBUG == 0) 115bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang effect_uuid_t uuid_print = pContext->desc[SUB_FX_HOST].uuid; 116bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("EffectCreate() UUID of HOST: %08X-%04X-%04X-%04X-%02X%02X%02X%02X" 117bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang "%02X%02X\n",uuid_print.timeLow, uuid_print.timeMid, 118bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang uuid_print.timeHiAndVersion, uuid_print.clockSeq, uuid_print.node[0], 119bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang uuid_print.node[1], uuid_print.node[2], uuid_print.node[3], 120bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang uuid_print.node[4], uuid_print.node[5]); 121bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("EffectCreate() UUID of OFFLOAD: %08X-%04X-%04X-%04X-%02X%02X%02X%02X" 122bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang "%02X%02X\n", uuid_print.timeLow, uuid_print.timeMid, 123bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang uuid_print.timeHiAndVersion, uuid_print.clockSeq, uuid_print.node[0], 124bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang uuid_print.node[1], uuid_print.node[2], uuid_print.node[3], 125bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang uuid_print.node[4], uuid_print.node[5]); 126bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang#endif 127bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang *pHandle = (effect_handle_t)pContext; 128bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("EffectCreate end"); 129bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return 0; 130bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang} //end EffectProxyCreate 131bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 132bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wangint EffectProxyRelease(effect_handle_t handle) { 133bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang EffectContext * pContext = (EffectContext *)handle; 134bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (pContext == NULL) { 135bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("ERROR : EffectRelease called with NULL pointer"); 136bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return -EINVAL; 137bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 138bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("EffectRelease"); 139bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang delete pContext->desc; 140bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (pContext->eHandle[SUB_FX_HOST]) 141bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang EffectRelease(pContext->eHandle[SUB_FX_HOST]); 142bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (pContext->eHandle[SUB_FX_OFFLOAD]) 143bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang EffectRelease(pContext->eHandle[SUB_FX_OFFLOAD]); 144bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang delete pContext; 145bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext = NULL; 146bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return 0; 147bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang} /*end EffectProxyRelease */ 148bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 149bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wangint EffectProxyGetDescriptor(const effect_uuid_t *uuid, 150bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang effect_descriptor_t *pDescriptor) { 151bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang const effect_descriptor_t *desc = NULL; 152bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 153bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (pDescriptor == NULL || uuid == NULL) { 154bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("EffectGetDescriptor() called with NULL pointer"); 155bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return -EINVAL; 156bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 157bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang desc = &gProxyDescriptor; 158bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang *pDescriptor = *desc; 159bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return 0; 160bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang} /* end EffectProxyGetDescriptor */ 161bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 162bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang/* Effect Control Interface Implementation: Process */ 163bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wangint Effect_process(effect_handle_t self, 164bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang audio_buffer_t *inBuffer, 165bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang audio_buffer_t *outBuffer) { 166bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 167bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang EffectContext *pContext = (EffectContext *) self; 168bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang int ret = 0; 169bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (pContext != NULL) { 170bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang int index = pContext->index; 171bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // if the index refers to HW , do not do anything. Just return. 172bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (index == SUB_FX_HOST) { 173bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ret = (*pContext->eHandle[index])->process(pContext->eHandle[index], 174bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang inBuffer, outBuffer); 175bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 176bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 177bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return ret; 178bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang} /* end Effect_process */ 179bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 180bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang/* Effect Control Interface Implementation: Command */ 181bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wangint Effect_command(effect_handle_t self, 182bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang uint32_t cmdCode, 183bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang uint32_t cmdSize, 184bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang void *pCmdData, 185bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang uint32_t *replySize, 186bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang void *pReplyData) { 187bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 188bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang EffectContext *pContext = (EffectContext *) self; 189bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang int status = 0; 190bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (pContext == NULL) { 191bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("Effect_command() Proxy context is NULL"); 192bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return -EINVAL; 193bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 194bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (pContext->eHandle[SUB_FX_HOST] == NULL) { 195bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("Effect_command() Calling HOST EffectCreate"); 196bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang status = EffectCreate(&pContext->desc[SUB_FX_HOST].uuid, 197bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->sessionId, pContext->ioId, 198bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang &(pContext->eHandle[SUB_FX_HOST])); 199bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (status != NO_ERROR || (pContext->eHandle[SUB_FX_HOST] == NULL)) { 200bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("Effect_command() Error creating SW sub effect"); 201bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return status; 202bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 203bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 204bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (pContext->eHandle[SUB_FX_OFFLOAD] == NULL) { 205bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("Effect_command() Calling OFFLOAD EffectCreate"); 206bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang status = EffectCreate(&pContext->desc[SUB_FX_OFFLOAD].uuid, 207bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->sessionId, pContext->ioId, 208bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang &(pContext->eHandle[SUB_FX_OFFLOAD])); 209bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (status != NO_ERROR || (pContext->eHandle[SUB_FX_OFFLOAD] == NULL)) { 210bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("Effect_command() Error creating HW effect"); 211bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // Do not return error here as SW effect is created 212bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // Return error if the CMD_OFFLOAD sends the index as OFFLOAD 213bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 214bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->index = SUB_FX_HOST; 215bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 216bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // EFFECT_CMD_OFFLOAD used to (1) send whether the thread is offload or not 217bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // (2) Send the ioHandle of the effectThread when the effect 218bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // is moved from one type of thread to another. 219bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // pCmdData points to a memory holding effect_offload_param_t structure 220bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (cmdCode == EFFECT_CMD_OFFLOAD) { 221bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("Effect_command() cmdCode = EFFECT_CMD_OFFLOAD"); 222bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (cmdSize == 0 || pCmdData == NULL) { 223bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("effectsOffload: Effect_command: CMD_OFFLOAD has no data"); 224bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang *(int*)pReplyData = FAILED_TRANSACTION; 225bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return FAILED_TRANSACTION; 226bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 227bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang effect_offload_param_t* offloadParam = (effect_offload_param_t*)pCmdData; 228bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // Assign the effect context index based on isOffload field of the structure 229bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->index = offloadParam->isOffload ? SUB_FX_OFFLOAD : SUB_FX_HOST; 230bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // if the index is HW and the HW effect is unavailable, return error 231bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // and reset the index to SW 232bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (pContext->eHandle[pContext->index] == NULL) { 233bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("Effect_command()CMD_OFFLOAD sub effect unavailable"); 234bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang *(int*)pReplyData = FAILED_TRANSACTION; 235bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return FAILED_TRANSACTION; 236bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 237bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->ioId = offloadParam->ioHandle; 238bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("Effect_command()CMD_OFFLOAD index:%d io %d", pContext->index, pContext->ioId); 239bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // Update the DSP wrapper with the new ioHandle. 240bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // Pass the OFFLOAD command to the wrapper. 241bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // The DSP wrapper needs to handle this CMD 242bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (pContext->eHandle[SUB_FX_OFFLOAD]) 243bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang status = (*pContext->eHandle[SUB_FX_OFFLOAD])->command( 244bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pContext->eHandle[SUB_FX_OFFLOAD], cmdCode, cmdSize, 245bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang pCmdData, replySize, pReplyData); 246bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return status; 247bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 248bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 249bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang int index = pContext->index; 250bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang if (index != SUB_FX_HOST && index != SUB_FX_OFFLOAD) { 251bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang ALOGV("Effect_command: effect index is neither offload nor host"); 252bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang return -EINVAL; 253bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang } 254bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang 255bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang // Getter commands are only sent to the active sub effect. 256bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang uint32_t hostReplySize = replySize != NULL ? *replySize : 0; 257bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang bool hostReplied = false; 258bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang int hostStatus = 0; 259bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang uint32_t offloadReplySize = replySize != NULL ? *replySize : 0; 260bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang bool offloadReplied = false; 261bfb39754e89488e7a605b4f1c3d0554528da9c0fCindy Wang int offloadStatus = 0; 262 263 if (pContext->eHandle[SUB_FX_HOST] && (!isGetterCmd(cmdCode) || index == SUB_FX_HOST)) { 264 hostStatus = (*pContext->eHandle[SUB_FX_HOST])->command( 265 pContext->eHandle[SUB_FX_HOST], cmdCode, cmdSize, 266 pCmdData, replySize != NULL ? &hostReplySize : NULL, pReplyData); 267 hostReplied = true; 268 } 269 if (pContext->eHandle[SUB_FX_OFFLOAD] && (!isGetterCmd(cmdCode) || index == SUB_FX_OFFLOAD)) { 270 // In case of SET CMD, when the offload stream is unavailable, 271 // we will store the effect param values in the DSP effect wrapper. 272 // When the offload effects get enabled, we send these values to the 273 // DSP during Effect_config. 274 // So,we send the params to DSP wrapper also 275 offloadStatus = (*pContext->eHandle[SUB_FX_OFFLOAD])->command( 276 pContext->eHandle[SUB_FX_OFFLOAD], cmdCode, cmdSize, 277 pCmdData, replySize != NULL ? &offloadReplySize : NULL, pReplyData); 278 offloadReplied = true; 279 } 280 // By convention the offloaded implementation reply is returned if command is processed by both 281 // host and offloaded sub effects 282 if (offloadReplied){ 283 status = offloadStatus; 284 if (replySize) { 285 *replySize = offloadReplySize; 286 } 287 } else if (hostReplied) { 288 status = hostStatus; 289 if (replySize) { 290 *replySize = hostReplySize; 291 } 292 } 293 return status; 294} /* end Effect_command */ 295 296 297/* Effect Control Interface Implementation: get_descriptor */ 298int Effect_getDescriptor(effect_handle_t self, 299 effect_descriptor_t *pDescriptor) { 300 301 EffectContext * pContext = (EffectContext *) self; 302 const effect_descriptor_t *desc; 303 304 ALOGV("Effect_getDescriptor"); 305 if (pContext == NULL || pDescriptor == NULL) { 306 ALOGV("Effect_getDescriptor() invalid param"); 307 return -EINVAL; 308 } 309 if (pContext->desc == NULL) { 310 ALOGV("Effect_getDescriptor() could not get descriptor"); 311 return -EINVAL; 312 } 313 desc = &pContext->desc[SUB_FX_HOST]; 314 *pDescriptor = *desc; 315 pDescriptor->uuid = pContext->uuid; // Replace the uuid with the Proxy UUID 316 // Also set/clear the EFFECT_FLAG_OFFLOAD_SUPPORTED flag based on the sub effects availability 317 if (pContext->eHandle[SUB_FX_OFFLOAD] != NULL) 318 pDescriptor->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED; 319 else 320 pDescriptor->flags &= ~EFFECT_FLAG_OFFLOAD_SUPPORTED; 321 return 0; 322} /* end Effect_getDescriptor */ 323 324} // namespace android 325 326__attribute__ ((visibility ("default"))) 327audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { 328 tag : AUDIO_EFFECT_LIBRARY_TAG, 329 version : EFFECT_LIBRARY_API_VERSION, 330 name : "Effect Proxy", 331 implementor : "AOSP", 332 create_effect : android::EffectProxyCreate, 333 release_effect : android::EffectProxyRelease, 334 get_descriptor : android::EffectProxyGetDescriptor, 335}; 336