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_Core.c 20 * @brief SEC OpenMAX IL Core 21 * @author SeungBeom Kim (sbcrux.kim (at) samsung.com) 22 * HyeYeon Chung (hyeon.chung (at) samsung.com) 23 * Yunji Kim (yunji.kim (at) samsung.com) 24 * @version 1.0 25 * @history 26 * 2010.7.15 : Create 27 */ 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <pthread.h> // for pthread related functions 33 34 #include "SEC_OMX_Core.h" 35 #include "SEC_OSAL_Mutex.h" // for mutext related functions 36 #include "SEC_OSAL_ETC.h" // for SEC_OSAL_Strcmp, etc 37 #include "SEC_OMX_Component_Register.h" 38 #include "SEC_OSAL_Memory.h" 39 #include "SEC_OMX_Resourcemanager.h" 40 41 #undef SEC_LOG_TAG 42 #define SEC_LOG_TAG "SEC_OMX_CORE" 43 #define SEC_LOG_OFF 44 #include "SEC_OSAL_Log.h" 45 46 47 static int gInitialized = 0; 48 static OMX_U32 gComponentNum = 0; 49 50 static SEC_OMX_COMPONENT_REGLIST *gComponentList = NULL; 51 static SEC_OMX_COMPONENT *gLoadComponentList = NULL; 52 static pthread_mutex_t ghLoadComponentListMutex = PTHREAD_MUTEX_INITIALIZER; 53 54 55 OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Init(void) 56 { 57 OMX_ERRORTYPE ret = OMX_ErrorNone; 58 59 FunctionIn(); 60 61 SEC_OSAL_MutexLock(&ghLoadComponentListMutex); 62 if (gInitialized == 0) { 63 if (SEC_OMX_Component_Register(&gComponentList, &gComponentNum)) { 64 ret = OMX_ErrorInsufficientResources; 65 SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_Init : %s", "OMX_ErrorInsufficientResources"); 66 goto EXIT; 67 } 68 69 SEC_OMX_ResourceManager_Init(); 70 SEC_OSAL_Log(SEC_LOG_TRACE, "SEC_OMX_Init : %s", "OMX_ErrorNone"); 71 } 72 ++gInitialized; 73 74 EXIT: 75 SEC_OSAL_MutexUnlock(&ghLoadComponentListMutex); 76 FunctionOut(); 77 78 return ret; 79 } 80 81 OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Deinit(void) 82 { 83 OMX_ERRORTYPE ret = OMX_ErrorNone; 84 85 FunctionIn(); 86 87 SEC_OSAL_MutexLock(&ghLoadComponentListMutex); 88 if (gInitialized > 0) { 89 --gInitialized; 90 } 91 92 if (gInitialized != 0) { 93 // Some component still uses the core. 94 // Nothing needs to be done 95 goto EXIT; 96 } 97 98 SEC_OMX_ResourceManager_Deinit(); 99 100 if (OMX_ErrorNone != SEC_OMX_Component_Unregister(gComponentList)) { 101 ret = OMX_ErrorUndefined; 102 goto EXIT; 103 } 104 gComponentList = NULL; 105 gComponentNum = 0; 106 107 EXIT: 108 SEC_OSAL_MutexUnlock(&ghLoadComponentListMutex); 109 FunctionOut(); 110 111 return ret; 112 } 113 114 OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_ComponentNameEnum( 115 OMX_OUT OMX_STRING cComponentName, 116 OMX_IN OMX_U32 nNameLength, 117 OMX_IN OMX_U32 nIndex) 118 { 119 OMX_ERRORTYPE ret = OMX_ErrorNone; 120 121 FunctionIn(); 122 123 if (nIndex >= gComponentNum) { 124 ret = OMX_ErrorNoMore; 125 goto EXIT; 126 } 127 128 sprintf(cComponentName, "%s", gComponentList[nIndex].component.componentName); 129 ret = OMX_ErrorNone; 130 131 EXIT: 132 FunctionOut(); 133 134 return ret; 135 } 136 137 OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_GetHandle( 138 OMX_OUT OMX_HANDLETYPE *pHandle, 139 OMX_IN OMX_STRING cComponentName, 140 OMX_IN OMX_PTR pAppData, 141 OMX_IN OMX_CALLBACKTYPE *pCallBacks) 142 { 143 OMX_ERRORTYPE ret = OMX_ErrorNone; 144 SEC_OMX_COMPONENT *loadComponent; 145 SEC_OMX_COMPONENT *currentComponent; 146 147 FunctionIn(); 148 149 if (gInitialized != 1) { 150 ret = OMX_ErrorNotReady; 151 goto EXIT; 152 } 153 154 if ((pHandle == NULL) || (cComponentName == NULL) || (pCallBacks == NULL)) { 155 ret = OMX_ErrorBadParameter; 156 goto EXIT; 157 } 158 SEC_OSAL_Log(SEC_LOG_TRACE, "ComponentName : %s", cComponentName); 159 160 OMX_U32 i = 0; 161 for (i = 0; i < gComponentNum; i++) { 162 if (SEC_OSAL_Strcmp(cComponentName, gComponentList[i].component.componentName) == 0) { 163 loadComponent = SEC_OSAL_Malloc(sizeof(SEC_OMX_COMPONENT)); 164 SEC_OSAL_Memset(loadComponent, 0, sizeof(SEC_OMX_COMPONENT)); 165 166 SEC_OSAL_Strcpy(loadComponent->libName, gComponentList[i].libName); 167 SEC_OSAL_Strcpy(loadComponent->componentName, gComponentList[i].component.componentName); 168 ret = SEC_OMX_ComponentLoad(loadComponent); 169 if (ret != OMX_ErrorNone) { 170 SEC_OSAL_Free(loadComponent); 171 SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); 172 goto EXIT; 173 } 174 175 ret = loadComponent->pOMXComponent->SetCallbacks(loadComponent->pOMXComponent, pCallBacks, pAppData); 176 if (ret != OMX_ErrorNone) { 177 SEC_OMX_ComponentUnload(loadComponent); 178 SEC_OSAL_Free(loadComponent); 179 SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); 180 goto EXIT; 181 } 182 183 SEC_OSAL_MutexLock(&ghLoadComponentListMutex); 184 if (gLoadComponentList == NULL) { 185 gLoadComponentList = loadComponent; 186 } else { 187 currentComponent = gLoadComponentList; 188 while (currentComponent->nextOMXComp != NULL) { 189 currentComponent = currentComponent->nextOMXComp; 190 } 191 currentComponent->nextOMXComp = loadComponent; 192 } 193 SEC_OSAL_MutexUnlock(&ghLoadComponentListMutex); 194 195 *pHandle = loadComponent->pOMXComponent; 196 ret = OMX_ErrorNone; 197 SEC_OSAL_Log(SEC_LOG_TRACE, "SEC_OMX_GetHandle : %s", "OMX_ErrorNone"); 198 goto EXIT; 199 } 200 } 201 202 ret = OMX_ErrorComponentNotFound; 203 204 EXIT: 205 FunctionOut(); 206 207 return ret; 208 } 209 210 OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent) 211 { 212 OMX_ERRORTYPE ret = OMX_ErrorNone; 213 SEC_OMX_COMPONENT *currentComponent; 214 SEC_OMX_COMPONENT *deleteComponent; 215 216 FunctionIn(); 217 218 if (gInitialized != 1) { 219 ret = OMX_ErrorNotReady; 220 goto EXIT; 221 } 222 223 if (!hComponent) { 224 ret = OMX_ErrorBadParameter; 225 goto EXIT; 226 } 227 228 SEC_OSAL_MutexLock(&ghLoadComponentListMutex); 229 currentComponent = gLoadComponentList; 230 if (gLoadComponentList->pOMXComponent == hComponent) { 231 deleteComponent = gLoadComponentList; 232 gLoadComponentList = gLoadComponentList->nextOMXComp; 233 } else { 234 while ((currentComponent != NULL) && (((SEC_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent != hComponent)) 235 currentComponent = currentComponent->nextOMXComp; 236 237 if (((SEC_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent == hComponent) { 238 deleteComponent = currentComponent->nextOMXComp; 239 currentComponent->nextOMXComp = deleteComponent->nextOMXComp; 240 } else if (currentComponent == NULL) { 241 ret = OMX_ErrorComponentNotFound; 242 goto EXIT; 243 } 244 } 245 246 SEC_OMX_ComponentUnload(deleteComponent); 247 SEC_OSAL_Free(deleteComponent); 248 249 EXIT: 250 SEC_OSAL_MutexUnlock(&ghLoadComponentListMutex); 251 FunctionOut(); 252 253 return ret; 254 } 255 256 OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_SetupTunnel( 257 OMX_IN OMX_HANDLETYPE hOutput, 258 OMX_IN OMX_U32 nPortOutput, 259 OMX_IN OMX_HANDLETYPE hInput, 260 OMX_IN OMX_U32 nPortInput) 261 { 262 OMX_ERRORTYPE ret = OMX_ErrorNotImplemented; 263 264 EXIT: 265 return ret; 266 } 267 268 OMX_API OMX_ERRORTYPE SEC_OMX_GetContentPipe( 269 OMX_OUT OMX_HANDLETYPE *hPipe, 270 OMX_IN OMX_STRING szURI) 271 { 272 OMX_ERRORTYPE ret = OMX_ErrorNotImplemented; 273 274 EXIT: 275 return ret; 276 } 277 278 OMX_API OMX_ERRORTYPE SEC_OMX_GetComponentsOfRole ( 279 OMX_IN OMX_STRING role, 280 OMX_INOUT OMX_U32 *pNumComps, 281 OMX_INOUT OMX_U8 **compNames) 282 { 283 OMX_ERRORTYPE ret = OMX_ErrorNone; 284 int max_role_num = 0; 285 OMX_STRING RoleString[MAX_OMX_COMPONENT_ROLE_SIZE]; 286 int i = 0, j = 0; 287 288 FunctionIn(); 289 290 if (gInitialized != 1) { 291 ret = OMX_ErrorNotReady; 292 goto EXIT; 293 } 294 295 *pNumComps = 0; 296 297 for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) { 298 max_role_num = gComponentList[i].component.totalRoleNum; 299 300 for (j = 0; j < max_role_num; j++) { 301 if (SEC_OSAL_Strcmp(gComponentList[i].component.roles[j], role) == 0) { 302 if (compNames != NULL) { 303 SEC_OSAL_Strcpy((OMX_STRING)compNames[*pNumComps], gComponentList[i].component.componentName); 304 } 305 *pNumComps = (*pNumComps + 1); 306 } 307 } 308 } 309 310 EXIT: 311 FunctionOut(); 312 313 return ret; 314 } 315 316 OMX_API OMX_ERRORTYPE SEC_OMX_GetRolesOfComponent ( 317 OMX_IN OMX_STRING compName, 318 OMX_INOUT OMX_U32 *pNumRoles, 319 OMX_OUT OMX_U8 **roles) 320 { 321 OMX_ERRORTYPE ret = OMX_ErrorNone; 322 OMX_BOOL detectComp = OMX_FALSE; 323 int compNum = 0, totalRoleNum = 0; 324 int i = 0; 325 326 FunctionIn(); 327 328 if (gInitialized != 1) { 329 ret = OMX_ErrorNotReady; 330 goto EXIT; 331 } 332 333 for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) { 334 if (gComponentList != NULL) { 335 if (SEC_OSAL_Strcmp(gComponentList[i].component.componentName, compName) == 0) { 336 *pNumRoles = totalRoleNum = gComponentList[i].component.totalRoleNum; 337 compNum = i; 338 detectComp = OMX_TRUE; 339 break; 340 } 341 } else { 342 ret = OMX_ErrorUndefined; 343 goto EXIT; 344 } 345 } 346 347 if (detectComp == OMX_FALSE) { 348 *pNumRoles = 0; 349 ret = OMX_ErrorComponentNotFound; 350 goto EXIT; 351 } 352 353 if (roles != NULL) { 354 for (i = 0; i < totalRoleNum; i++) { 355 SEC_OSAL_Strcpy(roles[i], gComponentList[compNum].component.roles[i]); 356 } 357 } 358 359 EXIT: 360 FunctionOut(); 361 362 return ret; 363 } 364