| /* |
| * |
| * Copyright 2010 Samsung Electronics S.LSI Co. LTD |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* |
| * @file SEC_OMX_Component_Register.c |
| * @brief SEC OpenMAX IL Component Register |
| * @author SeungBeom Kim (sbcrux.kim@samsung.com) |
| * @version 1.0 |
| * @history |
| * 2010.7.15 : Create |
| */ |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <dlfcn.h> |
| #include <sys/types.h> |
| #include <dirent.h> |
| #include <errno.h> |
| #include <assert.h> |
| |
| #include "OMX_Component.h" |
| #include "SEC_OSAL_Memory.h" |
| #include "SEC_OSAL_ETC.h" |
| #include "SEC_OSAL_Library.h" |
| #include "SEC_OMX_Component_Register.h" |
| #include "SEC_OMX_Macros.h" |
| |
| #undef SEC_LOG_TAG |
| #define SEC_LOG_TAG "SEC_COMP_REGS" |
| #define SEC_LOG_OFF |
| #include "SEC_OSAL_Log.h" |
| |
| |
| #define REGISTRY_FILENAME "secomxregistry" |
| |
| |
| OMX_ERRORTYPE SEC_OMX_Component_Register(SEC_OMX_COMPONENT_REGLIST **compList, OMX_U32 *compNum) |
| { |
| OMX_ERRORTYPE ret = OMX_ErrorNone; |
| int componentNum = 0, roleNum = 0, totalCompNum = 0; |
| int read; |
| char *omxregistryfile = NULL; |
| char *line = NULL; |
| char *libName; |
| FILE *omxregistryfp; |
| size_t len; |
| OMX_HANDLETYPE soHandle; |
| const char *errorMsg; |
| int (*SEC_OMX_COMPONENT_Library_Register)(SECRegisterComponentType **secComponents); |
| SECRegisterComponentType **secComponentsTemp; |
| SEC_OMX_COMPONENT_REGLIST *componentList; |
| |
| FunctionIn(); |
| |
| omxregistryfile = SEC_OSAL_Malloc(strlen("/system/etc/") + strlen(REGISTRY_FILENAME) + 2); |
| SEC_OSAL_Strcpy(omxregistryfile, "/system/etc/"); |
| SEC_OSAL_Strcat(omxregistryfile, REGISTRY_FILENAME); |
| |
| omxregistryfp = fopen(omxregistryfile, "r"); |
| if (omxregistryfp == NULL) { |
| ret = OMX_ErrorUndefined; |
| goto EXIT; |
| } |
| SEC_OSAL_Free(omxregistryfile); |
| |
| fseek(omxregistryfp, 0, 0); |
| componentList = (SEC_OMX_COMPONENT_REGLIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); |
| SEC_OSAL_Memset(componentList, 0, sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); |
| libName = SEC_OSAL_Malloc(MAX_OMX_COMPONENT_LIBNAME_SIZE); |
| |
| while ((read = getline(&line, &len, omxregistryfp)) != -1) { |
| if ((*line == 'l') && (*(line + 1) == 'i') && (*(line + 2) == 'b') && |
| (*(line + 3) == 'O') && (*(line + 4) == 'M') && (*(line + 5) == 'X')) { |
| SEC_OSAL_Memset(libName, 0, MAX_OMX_COMPONENT_LIBNAME_SIZE); |
| SEC_OSAL_Strncpy(libName, line, SEC_OSAL_Strlen(line)-1); |
| SEC_OSAL_Log(SEC_LOG_TRACE, "libName : %s", libName); |
| |
| if ((soHandle = SEC_OSAL_dlopen(libName, RTLD_NOW)) != NULL) { |
| SEC_OSAL_dlerror(); /* clear error*/ |
| if ((SEC_OMX_COMPONENT_Library_Register = SEC_OSAL_dlsym(soHandle, "SEC_OMX_COMPONENT_Library_Register")) != NULL) { |
| int i = 0, j = 0; |
| |
| componentNum = (*SEC_OMX_COMPONENT_Library_Register)(NULL); |
| secComponentsTemp = (SECRegisterComponentType **)SEC_OSAL_Malloc(sizeof(SECRegisterComponentType*) * componentNum); |
| for (i = 0; i < componentNum; i++) { |
| secComponentsTemp[i] = SEC_OSAL_Malloc(sizeof(SECRegisterComponentType)); |
| SEC_OSAL_Memset(secComponentsTemp[i], 0, sizeof(SECRegisterComponentType)); |
| } |
| (*SEC_OMX_COMPONENT_Library_Register)(secComponentsTemp); |
| |
| for (i = 0; i < componentNum; i++) { |
| SEC_OSAL_Strcpy(componentList[totalCompNum].component.componentName, secComponentsTemp[i]->componentName); |
| for (j = 0; j < secComponentsTemp[i]->totalRoleNum; j++) |
| SEC_OSAL_Strcpy(componentList[totalCompNum].component.roles[j], secComponentsTemp[i]->roles[j]); |
| componentList[totalCompNum].component.totalRoleNum = secComponentsTemp[i]->totalRoleNum; |
| |
| SEC_OSAL_Strcpy(componentList[totalCompNum].libName, libName); |
| |
| totalCompNum++; |
| } |
| for (i = 0; i < componentNum; i++) { |
| SEC_OSAL_Free(secComponentsTemp[i]); |
| } |
| |
| SEC_OSAL_Free(secComponentsTemp); |
| } else { |
| if ((errorMsg = SEC_OSAL_dlerror()) != NULL) |
| SEC_OSAL_Log(SEC_LOG_WARNING, "dlsym failed: %s", errorMsg); |
| } |
| SEC_OSAL_dlclose(soHandle); |
| } else { |
| SEC_OSAL_Log(SEC_LOG_WARNING, "dlopen failed: %s", SEC_OSAL_dlerror()); |
| } |
| } else { |
| /* not a component name line. skip */ |
| continue; |
| } |
| } |
| |
| SEC_OSAL_Free(libName); |
| fclose(omxregistryfp); |
| |
| *compList = componentList; |
| *compNum = totalCompNum; |
| |
| EXIT: |
| FunctionOut(); |
| |
| return ret; |
| } |
| |
| OMX_ERRORTYPE SEC_OMX_Component_Unregister(SEC_OMX_COMPONENT_REGLIST *componentList) |
| { |
| OMX_ERRORTYPE ret = OMX_ErrorNone; |
| |
| SEC_OSAL_Memset(componentList, 0, sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); |
| SEC_OSAL_Free(componentList); |
| |
| EXIT: |
| return ret; |
| } |
| |
| OMX_ERRORTYPE SEC_OMX_ComponentAPICheck(OMX_COMPONENTTYPE component) |
| { |
| OMX_ERRORTYPE ret = OMX_ErrorNone; |
| |
| if ((NULL == component.GetComponentVersion) || |
| (NULL == component.SendCommand) || |
| (NULL == component.GetParameter) || |
| (NULL == component.SetParameter) || |
| (NULL == component.GetConfig) || |
| (NULL == component.SetConfig) || |
| (NULL == component.GetExtensionIndex) || |
| (NULL == component.GetState) || |
| (NULL == component.ComponentTunnelRequest) || |
| (NULL == component.UseBuffer) || |
| (NULL == component.AllocateBuffer) || |
| (NULL == component.FreeBuffer) || |
| (NULL == component.EmptyThisBuffer) || |
| (NULL == component.FillThisBuffer) || |
| (NULL == component.SetCallbacks) || |
| (NULL == component.ComponentDeInit) || |
| (NULL == component.UseEGLImage) || |
| (NULL == component.ComponentRoleEnum)) |
| ret = OMX_ErrorInvalidComponent; |
| else |
| ret = OMX_ErrorNone; |
| |
| return ret; |
| } |
| |
| OMX_ERRORTYPE SEC_OMX_ComponentLoad(SEC_OMX_COMPONENT *sec_component) |
| { |
| OMX_ERRORTYPE ret = OMX_ErrorNone; |
| OMX_HANDLETYPE libHandle; |
| OMX_COMPONENTTYPE *pOMXComponent; |
| |
| FunctionIn(); |
| |
| OMX_ERRORTYPE (*SEC_OMX_ComponentInit)(OMX_HANDLETYPE hComponent, OMX_STRING componentName); |
| |
| libHandle = SEC_OSAL_dlopen(sec_component->libName, RTLD_NOW); |
| if (!libHandle) { |
| ret = OMX_ErrorInvalidComponentName; |
| SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponentName, Line:%d", __LINE__); |
| goto EXIT; |
| } |
| |
| SEC_OMX_ComponentInit = SEC_OSAL_dlsym(libHandle, "SEC_OMX_ComponentInit"); |
| if (!SEC_OMX_ComponentInit) { |
| SEC_OSAL_dlclose(libHandle); |
| ret = OMX_ErrorInvalidComponent; |
| SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); |
| goto EXIT; |
| } |
| |
| pOMXComponent = (OMX_COMPONENTTYPE *)SEC_OSAL_Malloc(sizeof(OMX_COMPONENTTYPE)); |
| INIT_SET_SIZE_VERSION(pOMXComponent, OMX_COMPONENTTYPE); |
| ret = (*SEC_OMX_ComponentInit)((OMX_HANDLETYPE)pOMXComponent, sec_component->componentName); |
| if (ret != OMX_ErrorNone) { |
| SEC_OSAL_Free(pOMXComponent); |
| SEC_OSAL_dlclose(libHandle); |
| ret = OMX_ErrorInvalidComponent; |
| SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); |
| goto EXIT; |
| } else { |
| if (SEC_OMX_ComponentAPICheck(*pOMXComponent) != OMX_ErrorNone) { |
| SEC_OSAL_Free(pOMXComponent); |
| SEC_OSAL_dlclose(libHandle); |
| if (NULL != pOMXComponent->ComponentDeInit) |
| pOMXComponent->ComponentDeInit(pOMXComponent); |
| ret = OMX_ErrorInvalidComponent; |
| SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); |
| goto EXIT; |
| } |
| sec_component->libHandle = libHandle; |
| sec_component->pOMXComponent = pOMXComponent; |
| ret = OMX_ErrorNone; |
| } |
| |
| EXIT: |
| FunctionOut(); |
| |
| return ret; |
| } |
| |
| OMX_ERRORTYPE SEC_OMX_ComponentUnload(SEC_OMX_COMPONENT *sec_component) |
| { |
| OMX_ERRORTYPE ret = OMX_ErrorNone; |
| OMX_COMPONENTTYPE *pOMXComponent = NULL; |
| |
| FunctionIn(); |
| |
| if (!sec_component) { |
| ret = OMX_ErrorBadParameter; |
| goto EXIT; |
| } |
| |
| pOMXComponent = sec_component->pOMXComponent; |
| if (pOMXComponent != NULL) { |
| pOMXComponent->ComponentDeInit(pOMXComponent); |
| SEC_OSAL_Free(pOMXComponent); |
| sec_component->pOMXComponent = NULL; |
| } |
| |
| if (sec_component->libHandle != NULL) { |
| SEC_OSAL_dlclose(sec_component->libHandle); |
| sec_component->libHandle = NULL; |
| } |
| |
| EXIT: |
| FunctionOut(); |
| |
| return ret; |
| } |