1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <securec.h>
16 #include <string.h>
17 #include "effect_core.h"
18 #include "effect_host_common.h"
19 #include "v1_0/effect_types_vdi.h"
20 #include "v1_0/effect_factory.h"
21 #include "osal_mem.h"
22 #include "parse_effect_config.h"
23 #include "audio_uhdf_log.h"
24
25 #define AUDIO_EFFECT_PLAFORM_CONFIG HDF_CONFIG_DIR"/audio_effect.json"
26 #define AUDIO_EFFECT_PRODUCT_CONFIG HDF_CHIP_PROD_CONFIG_DIR"/audio_effect.json"
27 #define HDF_LOG_TAG HDF_AUDIO_EFFECT
28 #define AUDIO_EFFECT_NUM_MAX 10
29 struct ConfigDescriptor *g_cfgDescs = NULL;
30 struct AudioEffectLibInfo {
31 char *libName;
32 uint8_t *libHandle;
33 struct EffectFactory *libEffect;
34 struct ControllerManager *ctrlMgr;
35 int32_t effectCnt;
36 };
37 struct AudioEffectLibInfo *g_libInfos[AUDIO_EFFECT_NUM_MAX] = { NULL };
38
GetEffectLibInfoByName(const char * libName)39 static struct AudioEffectLibInfo* GetEffectLibInfoByName(const char *libName)
40 {
41 if (libName == NULL) {
42 HDF_LOGE("%{public}s: invailid input params", __func__);
43 return NULL;
44 }
45 struct AudioEffectLibInfo *libInfo = NULL;
46 for (int i = 0; i <= AUDIO_EFFECT_NUM_MAX; i++) {
47 if (i == AUDIO_EFFECT_NUM_MAX) {
48 HDF_LOGE("%{public}s: can not find %{public}s", __func__, libName);
49 return NULL;
50 }
51 if (g_libInfos[i] == NULL || strcmp(g_libInfos[i]->libName, libName) != 0) {
52 continue;
53 }
54 libInfo = g_libInfos[i];
55 break;
56 }
57 return libInfo;
58 }
59
LoadLibraryByName(const char * libName,uint8_t ** libHandle,struct EffectFactory ** factLib)60 static int32_t LoadLibraryByName(const char *libName, uint8_t **libHandle, struct EffectFactory **factLib)
61 {
62 if (libName == NULL || factLib == NULL || libHandle == NULL) {
63 HDF_LOGE("%{public}s: invailid input params", __func__);
64 return HDF_ERR_INVALID_PARAM;
65 }
66 int32_t ret = 0;
67 struct EffectFactory *(*getFactoryLib)(void);
68 char path[PATH_MAX];
69 char pathBuf[PATH_MAX];
70 #if (defined(__aarch64__) || defined(__x86_64__))
71 ret = snprintf_s(path, PATH_MAX, PATH_MAX, "/vendor/lib64/%s.z.so", libName);
72 #else
73 ret = snprintf_s(path, PATH_MAX, PATH_MAX, "/vendor/lib/%s.z.so", libName);
74 #endif
75 if (ret < 0) {
76 HDF_LOGE("%{public}s: get libPath failed", __func__);
77 return HDF_FAILURE;
78 }
79 if (realpath(path, pathBuf) == NULL) {
80 HDF_LOGE("%{public}s: realpath is null! [%{public}d]", __func__, errno);
81 return HDF_FAILURE;
82 }
83 if (strncmp(HDF_LIBRARY_DIR, pathBuf, strlen(HDF_LIBRARY_DIR)) != 0) {
84 HDF_LOGE("%{public}s: The file path is incorrect", __func__);
85 return HDF_FAILURE;
86 }
87
88 void *handle = dlopen(pathBuf, RTLD_LAZY);
89 if (handle == NULL) {
90 HDF_LOGE("%{public}s: open so failed, reason:%{public}s", __func__, dlerror());
91 return HDF_FAILURE;
92 }
93
94 getFactoryLib = dlsym(handle, "GetEffectoyFactoryLib");
95 if (getFactoryLib == NULL) {
96 HDF_LOGE("%{public}s: dlsym failed %{public}s", __func__, dlerror());
97 dlclose(handle);
98 return HDF_FAILURE;
99 }
100 *factLib = getFactoryLib();
101 if (*factLib == NULL) {
102 HDF_LOGE("%{public}s: get fact lib failed %{public}s", __func__, dlerror());
103 dlclose(handle);
104 return HDF_FAILURE;
105 }
106 *libHandle = handle;
107 return HDF_SUCCESS;
108 }
109
AddEffectLibInfo(const char * libName,uint8_t * libHandle,struct EffectFactory * factLib)110 static struct AudioEffectLibInfo* AddEffectLibInfo(const char *libName, uint8_t *libHandle,
111 struct EffectFactory *factLib)
112 {
113 if (libName == NULL || factLib == NULL || libHandle == NULL) {
114 HDF_LOGE("%{public}s: invailid input params", __func__);
115 return NULL;
116 }
117 struct AudioEffectLibInfo *libInfo = NULL;
118 libInfo = (struct AudioEffectLibInfo *)OsalMemCalloc(sizeof(struct AudioEffectLibInfo));
119 if (libInfo == NULL) {
120 HDF_LOGE("%{public}s: OsalMemCalloc fail", __func__);
121 return NULL;
122 }
123 libInfo->libName = strdup(libName);
124 if (libInfo->libName == NULL) {
125 HDF_LOGE("%{public}s: strdup fail", __func__);
126 OsalMemFree(libInfo);
127 libInfo = NULL;
128 return NULL;
129 }
130 libInfo->libHandle = libHandle;
131 libInfo->libEffect = factLib;
132 libInfo->ctrlMgr = NULL;
133 libInfo->effectCnt = 1;
134 return libInfo;
135 }
136
LoadEffectLibrary(const char * libName,struct EffectFactory ** factLib,struct ControllerManager ** ctrlMgr)137 static int32_t LoadEffectLibrary(const char *libName, struct EffectFactory **factLib,
138 struct ControllerManager** ctrlMgr)
139 {
140 if (libName == NULL || factLib == NULL || ctrlMgr == NULL) {
141 HDF_LOGE("%{public}s: invailid input params", __func__);
142 return HDF_ERR_INVALID_PARAM;
143 }
144 uint8_t *libHandle = NULL;
145 int32_t index = 0;
146 for (int i = 0; i <= AUDIO_EFFECT_NUM_MAX; i++) {
147 if (i == AUDIO_EFFECT_NUM_MAX) {
148 HDF_LOGE("%{public}s: over effect max num", __func__);
149 return HDF_FAILURE;
150 }
151 if (g_libInfos[i] == NULL) {
152 index = i;
153 break;
154 }
155 if (strcmp(g_libInfos[i]->libName, libName) != 0) {
156 continue;
157 }
158 g_libInfos[i]->effectCnt++;
159 *factLib = g_libInfos[i]->libEffect;
160 *ctrlMgr = g_libInfos[i]->ctrlMgr;
161 HDF_LOGI("%{public}s: %{public}s increase, cnt=[%{public}d]", __func__, libName, g_libInfos[i]->effectCnt);
162 return HDF_SUCCESS;
163 }
164 int32_t ret = LoadLibraryByName(libName, &libHandle, factLib);
165 if (ret != HDF_SUCCESS || libHandle == NULL || *factLib == NULL) {
166 HDF_LOGE("%{public}s: load lib fail, libName:[%{public}s]", __func__, libName);
167 return HDF_FAILURE;
168 }
169 g_libInfos[index] = AddEffectLibInfo(libName, libHandle, *factLib);
170 if (g_libInfos[index] == NULL) {
171 HDF_LOGE("%{public}s: AddEffectLibInfo fail", __func__);
172 dlclose((void *)libHandle);
173 return HDF_FAILURE;
174 }
175 HDF_LOGI("%{public}s: %{public}s create, cnt=[%{public}d]", __func__, libName, g_libInfos[index]->effectCnt);
176 return HDF_SUCCESS;
177 }
178
DeleteEffectLibrary(const char * libName)179 static int32_t DeleteEffectLibrary(const char *libName)
180 {
181 if (libName == NULL) {
182 HDF_LOGE("%{public}s: invailid input params", __func__);
183 return HDF_ERR_INVALID_PARAM;
184 }
185 for (int i = 0; i <= AUDIO_EFFECT_NUM_MAX; i++) {
186 if (i == AUDIO_EFFECT_NUM_MAX) {
187 HDF_LOGE("%{public}s: fail to destroy effect, can not find %{public}s", __func__, libName);
188 return HDF_FAILURE;
189 }
190 if (g_libInfos[i] == NULL || strcmp(g_libInfos[i]->libName, libName) != 0) {
191 continue;
192 }
193 if (g_libInfos[i]->effectCnt > 1) {
194 g_libInfos[i]->effectCnt--;
195 HDF_LOGI("%{public}s: %{public}s decrease, cnt=[%{public}d]", __func__, libName, g_libInfos[i]->effectCnt);
196 return HDF_SUCCESS;
197 }
198 dlclose((void*)g_libInfos[i]->libHandle);
199 OsalMemFree(g_libInfos[i]->libName);
200 OsalMemFree(g_libInfos[i]->ctrlMgr);
201 OsalMemFree(g_libInfos[i]);
202 g_libInfos[i] = NULL;
203 break;
204 }
205 HDF_LOGI("%{public}s: %{public}s delete", __func__, libName);
206 return HDF_SUCCESS;
207 }
208
IsSupplyEffect(const char * libName)209 static int32_t IsSupplyEffect(const char *libName)
210 {
211 if (g_cfgDescs == NULL) {
212 HDF_LOGE("%{public}s: point is null!", __func__);
213 return HDF_FAILURE;
214 }
215 for (uint32_t i = 0; i < g_cfgDescs->effectNum; i++) {
216 if (strcmp(g_cfgDescs->effectCfgDescs[i].library, libName) == 0) {
217 return HDF_SUCCESS;
218 }
219 }
220 return HDF_FAILURE;
221 }
222
EffectModelIsSupplyEffectLibs(struct IEffectModel * self,bool * supply)223 static int32_t EffectModelIsSupplyEffectLibs(struct IEffectModel *self, bool *supply)
224 {
225 if (self == NULL || supply == NULL) {
226 HDF_LOGE("%{public}s: invailid input params", __func__);
227 return HDF_ERR_INVALID_PARAM;
228 }
229
230 *supply = IsEffectLibExist();
231 return HDF_SUCCESS;
232 }
233
EffectModelGetAllEffectDescriptors(struct IEffectModel * self,struct EffectControllerDescriptor * descs,uint32_t * descsLen)234 static int32_t EffectModelGetAllEffectDescriptors(struct IEffectModel *self,
235 struct EffectControllerDescriptor *descs, uint32_t *descsLen)
236 {
237 HDF_LOGD("enter to %{public}s", __func__);
238 int32_t ret;
239 uint32_t i;
240 uint32_t descNum = 0;
241 struct EffectFactory *factLib = NULL;
242 struct ControllerManager *ctrlMgr = NULL;
243
244 if (self == NULL || descs == NULL || descsLen == NULL) {
245 HDF_LOGE("%{public}s: invailid input params", __func__);
246 return HDF_ERR_INVALID_PARAM;
247 }
248
249 if (g_cfgDescs == NULL) {
250 HDF_LOGE("%{public}s: point is null!", __func__);
251 return HDF_FAILURE;
252 }
253 struct EffectControllerDescriptorVdi *descsVdi = (struct EffectControllerDescriptorVdi *)descs;
254 for (i = 0; i < g_cfgDescs->effectNum; i++) {
255 ret = LoadEffectLibrary(g_cfgDescs->effectCfgDescs[i].library, &factLib, &ctrlMgr);
256 if (ret != HDF_SUCCESS || factLib == NULL) {
257 HDF_LOGE("%{public}s: GetEffectLibFromList fail!", __func__);
258 continue;
259 }
260 ret = factLib->GetDescriptor(factLib, g_cfgDescs->effectCfgDescs[i].effectId, &descsVdi[descNum]);
261 if (ret != HDF_SUCCESS) {
262 DeleteEffectLibrary(g_cfgDescs->effectCfgDescs[i].library);
263 HDF_LOGE("%{public}s: GetDescriptor fail!", __func__);
264 continue;
265 }
266 DeleteEffectLibrary(g_cfgDescs->effectCfgDescs[i].library);
267 factLib = NULL;
268 descNum++;
269 }
270 *descsLen = descNum;
271 descs = (struct EffectControllerDescriptor *)descsVdi;
272 HDF_LOGD("%{public}s success", __func__);
273 return HDF_SUCCESS;
274 }
275
EffectModelGetEffectDescriptor(struct IEffectModel * self,const char * uuid,struct EffectControllerDescriptor * desc)276 static int32_t EffectModelGetEffectDescriptor(struct IEffectModel *self, const char *uuid,
277 struct EffectControllerDescriptor *desc)
278 {
279 HDF_LOGD("enter to %{public}s", __func__);
280 uint32_t i;
281 struct EffectFactory *factLib = NULL;
282 struct ControllerManager *ctrlMgr = NULL;
283 if (self == NULL || uuid == NULL || desc == NULL) {
284 HDF_LOGE("%{public}s: invailid input params", __func__);
285 return HDF_ERR_INVALID_PARAM;
286 }
287 struct EffectControllerDescriptorVdi *descVdi = (struct EffectControllerDescriptorVdi *)desc;
288 for (i = 0; i < g_cfgDescs->effectNum; i++) {
289 if (strcmp(uuid, g_cfgDescs->effectCfgDescs[i].effectId) != 0) {
290 continue;
291 }
292
293 LoadEffectLibrary(g_cfgDescs->effectCfgDescs[i].library, &factLib, &ctrlMgr);
294 if (factLib == NULL) {
295 HDF_LOGE("%{public}s: GetEffectLibFromList fail!", __func__);
296 return HDF_FAILURE;
297 }
298
299 if (factLib->GetDescriptor(factLib, uuid, descVdi) != HDF_SUCCESS) {
300 DeleteEffectLibrary(g_cfgDescs->effectCfgDescs[i].library);
301 HDF_LOGE("%{public}s: GetDescriptor fail!", __func__);
302 return HDF_FAILURE;
303 }
304 DeleteEffectLibrary(g_cfgDescs->effectCfgDescs[i].library);
305 HDF_LOGD("%{public}s success", __func__);
306 return HDF_SUCCESS;
307 }
308 desc = (struct EffectControllerDescriptor *)descVdi;
309 HDF_LOGE("%{public}s fail!", __func__);
310 return HDF_FAILURE;
311 }
312
CreateEffectController(const struct EffectInfo * info,struct IEffectControl ** contoller,struct ControllerId * contollerId,struct IEffectControlVdi * ctrlOps)313 static int32_t CreateEffectController(const struct EffectInfo *info, struct IEffectControl **contoller,
314 struct ControllerId *contollerId, struct IEffectControlVdi *ctrlOps)
315 {
316 if (info == NULL || contoller == NULL || contollerId == NULL) {
317 HDF_LOGE("%{public}s: invailid input params", __func__);
318 return HDF_ERR_INVALID_PARAM;
319 }
320 struct ControllerManager *ctrlMgr = (struct ControllerManager *)OsalMemCalloc(sizeof(struct ControllerManager));
321 CHECK_NULL_PTR_RETURN_VALUE(ctrlMgr, HDF_FAILURE);
322 struct AudioEffectLibInfo *libInfo = GetEffectLibInfoByName(info->libName);
323 if (libInfo == NULL) {
324 HDF_LOGE("%{public}s: GetEffectLibInfoByName failed", __func__);
325 OsalMemFree(ctrlMgr);
326 return HDF_FAILURE;
327 }
328 libInfo->ctrlMgr = ctrlMgr;
329 ctrlMgr->ctrlOps = ctrlOps;
330 ctrlMgr->libName = strdup(info->libName);
331 if (ctrlMgr->libName == NULL) {
332 HDF_LOGE("%{public}s: strdup failed, info->effectId = %{public}s", __func__, info->effectId);
333 OsalMemFree(ctrlMgr);
334 return HDF_FAILURE;
335 }
336 ctrlMgr->ctrlImpls.EffectProcess = EffectControlEffectProcess;
337 ctrlMgr->ctrlImpls.SendCommand = EffectControlSendCommand;
338 ctrlMgr->ctrlImpls.GetEffectDescriptor = EffectGetOwnDescriptor;
339 ctrlMgr->ctrlImpls.EffectReverse = EffectControlEffectReverse;
340 *contoller = &ctrlMgr->ctrlImpls;
341 // free after send reply
342 contollerId->libName = strdup(info->libName);
343 contollerId->effectId = strdup(info->effectId);
344 if (contollerId->libName == NULL || contollerId->effectId == NULL) {
345 HDF_LOGE("%{public}s: strdup failed, info->libName = %{public}s", __func__, info->libName);
346 OsalMemFree(ctrlMgr->libName);
347 OsalMemFree(ctrlMgr);
348 *contoller = NULL;
349 return HDF_FAILURE;
350 }
351 return HDF_SUCCESS;
352 }
353
EffectModelCreateEffectController(struct IEffectModel * self,const struct EffectInfo * info,struct IEffectControl ** contoller,struct ControllerId * contollerId)354 static int32_t EffectModelCreateEffectController(struct IEffectModel *self, const struct EffectInfo *info,
355 struct IEffectControl **contoller, struct ControllerId *contollerId)
356 {
357 if (self == NULL || info == NULL || contoller == NULL || contollerId == NULL) {
358 HDF_LOGE("%{public}s: invailid input params", __func__);
359 return HDF_ERR_INVALID_PARAM;
360 }
361
362 if (IsSupplyEffect(info->libName) != HDF_SUCCESS) {
363 HDF_LOGE("%{public}s: not support effect [%{public}s]", __func__, info->libName);
364 return HDF_FAILURE;
365 }
366
367 struct EffectFactory *lib = NULL;
368 struct ControllerManager *ctrlMgr = NULL;
369 struct IEffectControlVdi *ctrlOps = NULL;
370
371 int32_t ret = LoadEffectLibrary(info->libName, &lib, &ctrlMgr);
372 if (ret != HDF_SUCCESS) {
373 HDF_LOGE("%{public}s: LoadEffectLibrary fail", __func__);
374 return HDF_FAILURE;
375 }
376 if (ctrlMgr != NULL) {
377 contollerId->libName = strdup(info->libName);
378 contollerId->effectId = strdup(info->effectId);
379 if (contollerId->libName == NULL || contollerId->effectId == NULL) {
380 HDF_LOGE("%{public}s: strdup failed", __func__);
381 return HDF_FAILURE;
382 }
383 *contoller = &ctrlMgr->ctrlImpls;
384 return HDF_SUCCESS;
385 }
386 CHECK_NULL_PTR_RETURN_VALUE(lib, HDF_FAILURE);
387 CHECK_NULL_PTR_RETURN_VALUE(lib->CreateController, HDF_FAILURE);
388
389 struct EffectInfoVdi *infoVdi = (struct EffectInfoVdi *)info;
390 lib->CreateController(lib, infoVdi, &ctrlOps);
391 CHECK_NULL_PTR_RETURN_VALUE(ctrlOps, HDF_FAILURE);
392
393 ret = CreateEffectController(info, contoller, contollerId, ctrlOps);
394 if (ret != HDF_SUCCESS) {
395 DeleteEffectLibrary(info->libName);
396 return HDF_FAILURE;
397 }
398
399 HDF_LOGI("%{public}s: create effect succeed, libName = %{public}s", __func__, info->libName);
400 return HDF_SUCCESS;
401 }
402
EffectModelDestroyEffectController(struct IEffectModel * self,const struct ControllerId * contollerId)403 int32_t EffectModelDestroyEffectController(struct IEffectModel *self, const struct ControllerId *contollerId)
404 {
405 if (self == NULL || contollerId == NULL) {
406 HDF_LOGE("%{public}s: invailid input params", __func__);
407 return HDF_ERR_INVALID_PARAM;
408 }
409
410 struct AudioEffectLibInfo *libInfo = GetEffectLibInfoByName(contollerId->libName);
411 CHECK_NULL_PTR_RETURN_VALUE(libInfo, HDF_FAILURE);
412 if (libInfo->effectCnt > 1) {
413 libInfo->effectCnt--;
414 return HDF_SUCCESS;
415 }
416 struct EffectFactory *lib = libInfo->libEffect;
417 CHECK_NULL_PTR_RETURN_VALUE(lib, HDF_FAILURE);
418 struct ControllerManager *ctrlMgr = libInfo->ctrlMgr;
419 CHECK_NULL_PTR_RETURN_VALUE(ctrlMgr, HDF_FAILURE);
420
421 if (ctrlMgr->libName != NULL) {
422 OsalMemFree(ctrlMgr->libName);
423 ctrlMgr->libName = NULL;
424 }
425
426 if (ctrlMgr->ctrlOps == NULL) {
427 HDF_LOGE("%{public}s: controller has no options", __func__);
428 return HDF_FAILURE;
429 }
430
431 /* call the lib destroy method,then free controller manager */
432 lib->DestroyController(lib, ctrlMgr->ctrlOps);
433 DeleteEffectLibrary(contollerId->libName);
434 HDF_LOGI("%{public}s: destroy effect succeed, libName = %{public}s", __func__, contollerId->libName);
435 return HDF_SUCCESS;
436 }
437
ModelInit(void)438 void ModelInit(void)
439 {
440 FILE *file;
441 struct ConfigDescriptor *cfgDesc = NULL;
442 int32_t ret;
443 file = fopen(AUDIO_EFFECT_PRODUCT_CONFIG, "r");
444 if (file == NULL) {
445 ret = AudioEffectGetConfigDescriptor(AUDIO_EFFECT_PLAFORM_CONFIG, &cfgDesc);
446 HDF_LOGI("%{public}s: %{public}s!", __func__, AUDIO_EFFECT_PLAFORM_CONFIG);
447 } else {
448 ret = AudioEffectGetConfigDescriptor(AUDIO_EFFECT_PRODUCT_CONFIG, &cfgDesc);
449 HDF_LOGI("%{public}s: %{public}s!", __func__, AUDIO_EFFECT_PRODUCT_CONFIG);
450 (void)fclose(file);
451 }
452 if (ret != HDF_SUCCESS) {
453 HDF_LOGE("%{public}s: AudioEffectGetConfigDescriptor fail!", __func__);
454 return;
455 }
456
457 if (cfgDesc == NULL || cfgDesc->effectCfgDescs == NULL || cfgDesc->libCfgDescs == NULL) {
458 HDF_LOGE("cfgDesc is null!");
459 return;
460 }
461 g_cfgDescs = cfgDesc;
462 HDF_LOGD("%{public}s end!", __func__);
463 }
464
EffectModelImplGetInstance(void)465 struct IEffectModel *EffectModelImplGetInstance(void)
466 {
467 struct EffectModelService *service = (struct EffectModelService *)OsalMemCalloc(sizeof(struct EffectModelService));
468 if (service == NULL) {
469 HDF_LOGE("%{public}s: malloc EffectModelService obj failed!", __func__);
470 return NULL;
471 }
472
473 ModelInit();
474 service->interface.IsSupplyEffectLibs = EffectModelIsSupplyEffectLibs;
475 service->interface.GetAllEffectDescriptors = EffectModelGetAllEffectDescriptors;
476 service->interface.CreateEffectController = EffectModelCreateEffectController;
477 service->interface.DestroyEffectController = EffectModelDestroyEffectController;
478 service->interface.GetEffectDescriptor = EffectModelGetEffectDescriptor;
479
480 return &service->interface;
481 }
482
EffectModelImplRelease(struct IEffectModel * instance)483 void EffectModelImplRelease(struct IEffectModel *instance)
484 {
485 if (instance == NULL) {
486 return;
487 }
488
489 AudioEffectReleaseCfgDesc(g_cfgDescs);
490 struct EffectModelService *service = CONTAINER_OF(instance, struct EffectModelService, interface);
491 if (service == NULL) {
492 return;
493 }
494 OsalMemFree(service);
495 service = NULL;
496 }
497