1 /* 2 * 3 * Copyright 2010 Samsung Electronics S.LSI Co. LTD 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /* 19 * @file SEC_OMX_Component_Register.c 20 * @brief SEC OpenMAX IL Component Register 21 * @author SeungBeom Kim (sbcrux.kim (at) samsung.com) 22 * @version 1.0 23 * @history 24 * 2010.7.15 : Create 25 */ 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <dlfcn.h> 30 #include <sys/types.h> 31 #include <dirent.h> 32 #include <errno.h> 33 #include <assert.h> 34 35 #include "OMX_Component.h" 36 #include "SEC_OSAL_Memory.h" 37 #include "SEC_OSAL_ETC.h" 38 #include "SEC_OSAL_Library.h" 39 #include "SEC_OMX_Component_Register.h" 40 #include "SEC_OMX_Macros.h" 41 42 #undef SEC_LOG_TAG 43 #define SEC_LOG_TAG "SEC_COMP_REGS" 44 #define SEC_LOG_OFF 45 #include "SEC_OSAL_Log.h" 46 47 48 #define REGISTRY_FILENAME "secomxregistry" 49 50 51 OMX_ERRORTYPE SEC_OMX_Component_Register(SEC_OMX_COMPONENT_REGLIST **compList, OMX_U32 *compNum) 52 { 53 OMX_ERRORTYPE ret = OMX_ErrorNone; 54 int componentNum = 0, roleNum = 0, totalCompNum = 0; 55 int read; 56 char *omxregistryfile = NULL; 57 char *line = NULL; 58 char *libName; 59 FILE *omxregistryfp; 60 size_t len; 61 OMX_HANDLETYPE soHandle; 62 const char *errorMsg; 63 int (*SEC_OMX_COMPONENT_Library_Register)(SECRegisterComponentType **secComponents); 64 SECRegisterComponentType **secComponentsTemp; 65 SEC_OMX_COMPONENT_REGLIST *componentList; 66 67 FunctionIn(); 68 69 omxregistryfile = SEC_OSAL_Malloc(strlen("/system/etc/") + strlen(REGISTRY_FILENAME) + 2); 70 SEC_OSAL_Strcpy(omxregistryfile, "/system/etc/"); 71 SEC_OSAL_Strcat(omxregistryfile, REGISTRY_FILENAME); 72 73 omxregistryfp = fopen(omxregistryfile, "r"); 74 if (omxregistryfp == NULL) { 75 ret = OMX_ErrorUndefined; 76 goto EXIT; 77 } 78 SEC_OSAL_Free(omxregistryfile); 79 80 fseek(omxregistryfp, 0, 0); 81 componentList = (SEC_OMX_COMPONENT_REGLIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); 82 SEC_OSAL_Memset(componentList, 0, sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); 83 libName = SEC_OSAL_Malloc(MAX_OMX_COMPONENT_LIBNAME_SIZE); 84 85 while ((read = getline(&line, &len, omxregistryfp)) != -1) { 86 if ((*line == 'l') && (*(line + 1) == 'i') && (*(line + 2) == 'b') && 87 (*(line + 3) == 'O') && (*(line + 4) == 'M') && (*(line + 5) == 'X')) { 88 SEC_OSAL_Memset(libName, 0, MAX_OMX_COMPONENT_LIBNAME_SIZE); 89 SEC_OSAL_Strncpy(libName, line, SEC_OSAL_Strlen(line)-1); 90 SEC_OSAL_Log(SEC_LOG_TRACE, "libName : %s", libName); 91 92 if ((soHandle = SEC_OSAL_dlopen(libName, RTLD_NOW)) != NULL) { 93 SEC_OSAL_dlerror(); /* clear error*/ 94 if ((SEC_OMX_COMPONENT_Library_Register = SEC_OSAL_dlsym(soHandle, "SEC_OMX_COMPONENT_Library_Register")) != NULL) { 95 int i = 0, j = 0; 96 97 componentNum = (*SEC_OMX_COMPONENT_Library_Register)(NULL); 98 secComponentsTemp = (SECRegisterComponentType **)SEC_OSAL_Malloc(sizeof(SECRegisterComponentType*) * componentNum); 99 for (i = 0; i < componentNum; i++) { 100 secComponentsTemp[i] = SEC_OSAL_Malloc(sizeof(SECRegisterComponentType)); 101 SEC_OSAL_Memset(secComponentsTemp[i], 0, sizeof(SECRegisterComponentType)); 102 } 103 (*SEC_OMX_COMPONENT_Library_Register)(secComponentsTemp); 104 105 for (i = 0; i < componentNum; i++) { 106 SEC_OSAL_Strcpy(componentList[totalCompNum].component.componentName, secComponentsTemp[i]->componentName); 107 for (j = 0; j < secComponentsTemp[i]->totalRoleNum; j++) 108 SEC_OSAL_Strcpy(componentList[totalCompNum].component.roles[j], secComponentsTemp[i]->roles[j]); 109 componentList[totalCompNum].component.totalRoleNum = secComponentsTemp[i]->totalRoleNum; 110 111 SEC_OSAL_Strcpy(componentList[totalCompNum].libName, libName); 112 113 totalCompNum++; 114 } 115 for (i = 0; i < componentNum; i++) { 116 SEC_OSAL_Free(secComponentsTemp[i]); 117 } 118 119 SEC_OSAL_Free(secComponentsTemp); 120 } else { 121 if ((errorMsg = SEC_OSAL_dlerror()) != NULL) 122 SEC_OSAL_Log(SEC_LOG_WARNING, "dlsym failed: %s", errorMsg); 123 } 124 SEC_OSAL_dlclose(soHandle); 125 } else { 126 SEC_OSAL_Log(SEC_LOG_WARNING, "dlopen failed: %s", SEC_OSAL_dlerror()); 127 } 128 } else { 129 /* not a component name line. skip */ 130 continue; 131 } 132 } 133 134 SEC_OSAL_Free(libName); 135 fclose(omxregistryfp); 136 137 *compList = componentList; 138 *compNum = totalCompNum; 139 140 EXIT: 141 FunctionOut(); 142 143 return ret; 144 } 145 146 OMX_ERRORTYPE SEC_OMX_Component_Unregister(SEC_OMX_COMPONENT_REGLIST *componentList) 147 { 148 OMX_ERRORTYPE ret = OMX_ErrorNone; 149 150 SEC_OSAL_Memset(componentList, 0, sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); 151 SEC_OSAL_Free(componentList); 152 153 EXIT: 154 return ret; 155 } 156 157 OMX_ERRORTYPE SEC_OMX_ComponentAPICheck(OMX_COMPONENTTYPE component) 158 { 159 OMX_ERRORTYPE ret = OMX_ErrorNone; 160 161 if ((NULL == component.GetComponentVersion) || 162 (NULL == component.SendCommand) || 163 (NULL == component.GetParameter) || 164 (NULL == component.SetParameter) || 165 (NULL == component.GetConfig) || 166 (NULL == component.SetConfig) || 167 (NULL == component.GetExtensionIndex) || 168 (NULL == component.GetState) || 169 (NULL == component.ComponentTunnelRequest) || 170 (NULL == component.UseBuffer) || 171 (NULL == component.AllocateBuffer) || 172 (NULL == component.FreeBuffer) || 173 (NULL == component.EmptyThisBuffer) || 174 (NULL == component.FillThisBuffer) || 175 (NULL == component.SetCallbacks) || 176 (NULL == component.ComponentDeInit) || 177 (NULL == component.UseEGLImage) || 178 (NULL == component.ComponentRoleEnum)) 179 ret = OMX_ErrorInvalidComponent; 180 else 181 ret = OMX_ErrorNone; 182 183 return ret; 184 } 185 186 OMX_ERRORTYPE SEC_OMX_ComponentLoad(SEC_OMX_COMPONENT *sec_component) 187 { 188 OMX_ERRORTYPE ret = OMX_ErrorNone; 189 OMX_HANDLETYPE libHandle; 190 OMX_COMPONENTTYPE *pOMXComponent; 191 192 FunctionIn(); 193 194 OMX_ERRORTYPE (*SEC_OMX_ComponentInit)(OMX_HANDLETYPE hComponent, OMX_STRING componentName); 195 196 libHandle = SEC_OSAL_dlopen(sec_component->libName, RTLD_NOW); 197 if (!libHandle) { 198 ret = OMX_ErrorInvalidComponentName; 199 SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponentName, Line:%d", __LINE__); 200 goto EXIT; 201 } 202 203 SEC_OMX_ComponentInit = SEC_OSAL_dlsym(libHandle, "SEC_OMX_ComponentInit"); 204 if (!SEC_OMX_ComponentInit) { 205 SEC_OSAL_dlclose(libHandle); 206 ret = OMX_ErrorInvalidComponent; 207 SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); 208 goto EXIT; 209 } 210 211 pOMXComponent = (OMX_COMPONENTTYPE *)SEC_OSAL_Malloc(sizeof(OMX_COMPONENTTYPE)); 212 INIT_SET_SIZE_VERSION(pOMXComponent, OMX_COMPONENTTYPE); 213 ret = (*SEC_OMX_ComponentInit)((OMX_HANDLETYPE)pOMXComponent, sec_component->componentName); 214 if (ret != OMX_ErrorNone) { 215 SEC_OSAL_Free(pOMXComponent); 216 SEC_OSAL_dlclose(libHandle); 217 ret = OMX_ErrorInvalidComponent; 218 SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); 219 goto EXIT; 220 } else { 221 if (SEC_OMX_ComponentAPICheck(*pOMXComponent) != OMX_ErrorNone) { 222 SEC_OSAL_Free(pOMXComponent); 223 SEC_OSAL_dlclose(libHandle); 224 if (NULL != pOMXComponent->ComponentDeInit) 225 pOMXComponent->ComponentDeInit(pOMXComponent); 226 ret = OMX_ErrorInvalidComponent; 227 SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); 228 goto EXIT; 229 } 230 sec_component->libHandle = libHandle; 231 sec_component->pOMXComponent = pOMXComponent; 232 ret = OMX_ErrorNone; 233 } 234 235 EXIT: 236 FunctionOut(); 237 238 return ret; 239 } 240 241 OMX_ERRORTYPE SEC_OMX_ComponentUnload(SEC_OMX_COMPONENT *sec_component) 242 { 243 OMX_ERRORTYPE ret = OMX_ErrorNone; 244 OMX_COMPONENTTYPE *pOMXComponent = NULL; 245 246 FunctionIn(); 247 248 if (!sec_component) { 249 ret = OMX_ErrorBadParameter; 250 goto EXIT; 251 } 252 253 pOMXComponent = sec_component->pOMXComponent; 254 if (pOMXComponent != NULL) { 255 pOMXComponent->ComponentDeInit(pOMXComponent); 256 SEC_OSAL_Free(pOMXComponent); 257 sec_component->pOMXComponent = NULL; 258 } 259 260 if (sec_component->libHandle != NULL) { 261 SEC_OSAL_dlclose(sec_component->libHandle); 262 sec_component->libHandle = NULL; 263 } 264 265 EXIT: 266 FunctionOut(); 267 268 return ret; 269 } 270