1/* 2 * 3 * Copyright 2012 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 Exynos_OMX_Core.c 20 * @brief Exynos OpenMAX IL Core 21 * @author SeungBeom Kim (sbcrux.kim@samsung.com) 22 * HyeYeon Chung (hyeon.chung@samsung.com) 23 * Yunji Kim (yunji.kim@samsung.com) 24 * @version 2.0.0 25 * @history 26 * 2012.02.20 : Create 27 */ 28 29#include <stdio.h> 30#include <stdlib.h> 31#include <string.h> 32 33#include "Exynos_OMX_Core.h" 34#include "Exynos_OMX_Component_Register.h" 35#include "Exynos_OSAL_Memory.h" 36#include "Exynos_OSAL_Mutex.h" 37#include "Exynos_OSAL_ETC.h" 38#include "Exynos_OMX_Resourcemanager.h" 39 40#undef EXYNOS_LOG_TAG 41#define EXYNOS_LOG_TAG "EXYNOS_OMX_CORE" 42#define EXYNOS_LOG_OFF 43#include "Exynos_OSAL_Log.h" 44 45 46static int gInitialized = 0; 47static OMX_U32 gComponentNum = 0; 48 49static EXYNOS_OMX_COMPONENT_REGLIST *gComponentList = NULL; 50static EXYNOS_OMX_COMPONENT *gLoadComponentList = NULL; 51static OMX_HANDLETYPE ghLoadComponentListMutex = NULL; 52 53 54OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_Init(void) 55{ 56 OMX_ERRORTYPE ret = OMX_ErrorNone; 57 58 FunctionIn(); 59 60 if (gInitialized == 0) { 61 if (Exynos_OMX_Component_Register(&gComponentList, &gComponentNum)) { 62 ret = OMX_ErrorInsufficientResources; 63 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_OMX_Init : %s", "OMX_ErrorInsufficientResources"); 64 goto EXIT; 65 } 66 67 ret = Exynos_OMX_ResourceManager_Init(); 68 if (OMX_ErrorNone != ret) { 69 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_OMX_Init : Exynos_OMX_ResourceManager_Init failed"); 70 goto EXIT; 71 } 72 73 ret = Exynos_OSAL_MutexCreate(&ghLoadComponentListMutex); 74 if (OMX_ErrorNone != ret) { 75 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_OMX_Init : Exynos_OSAL_MutexCreate(&ghLoadComponentListMutex) failed"); 76 goto EXIT; 77 } 78 79 gInitialized = 1; 80 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_OMX_Init : %s", "OMX_ErrorNone"); 81 } 82 83EXIT: 84 FunctionOut(); 85 86 return ret; 87} 88 89OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_Deinit(void) 90{ 91 OMX_ERRORTYPE ret = OMX_ErrorNone; 92 93 FunctionIn(); 94 95 Exynos_OSAL_MutexTerminate(ghLoadComponentListMutex); 96 ghLoadComponentListMutex = NULL; 97 98 Exynos_OMX_ResourceManager_Deinit(); 99 100 if (OMX_ErrorNone != Exynos_OMX_Component_Unregister(gComponentList)) { 101 ret = OMX_ErrorUndefined; 102 goto EXIT; 103 } 104 gComponentList = NULL; 105 gComponentNum = 0; 106 gInitialized = 0; 107 108EXIT: 109 FunctionOut(); 110 111 return ret; 112} 113 114OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_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 snprintf(cComponentName, nNameLength, "%s", gComponentList[nIndex].component.componentName); 129 ret = OMX_ErrorNone; 130 131EXIT: 132 FunctionOut(); 133 134 return ret; 135} 136 137OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_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 EXYNOS_OMX_COMPONENT *loadComponent; 145 EXYNOS_OMX_COMPONENT *currentComponent; 146 unsigned int i = 0; 147 148 FunctionIn(); 149 150 if (gInitialized != 1) { 151 ret = OMX_ErrorNotReady; 152 goto EXIT; 153 } 154 155 if ((pHandle == NULL) || (cComponentName == NULL) || (pCallBacks == NULL)) { 156 ret = OMX_ErrorBadParameter; 157 goto EXIT; 158 } 159 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ComponentName : %s", cComponentName); 160 161 for (i = 0; i < gComponentNum; i++) { 162 if (Exynos_OSAL_Strcmp(cComponentName, gComponentList[i].component.componentName) == 0) { 163 loadComponent = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_COMPONENT)); 164 Exynos_OSAL_Memset(loadComponent, 0, sizeof(EXYNOS_OMX_COMPONENT)); 165 166 Exynos_OSAL_Strcpy(loadComponent->libName, gComponentList[i].libName); 167 Exynos_OSAL_Strcpy(loadComponent->componentName, gComponentList[i].component.componentName); 168 ret = Exynos_OMX_ComponentLoad(loadComponent); 169 if (ret != OMX_ErrorNone) { 170 Exynos_OSAL_Free(loadComponent); 171 Exynos_OSAL_Log(EXYNOS_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 Exynos_OMX_ComponentUnload(loadComponent); 178 Exynos_OSAL_Free(loadComponent); 179 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); 180 goto EXIT; 181 } 182 183 Exynos_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 Exynos_OSAL_MutexUnlock(ghLoadComponentListMutex); 194 195 *pHandle = loadComponent->pOMXComponent; 196 ret = OMX_ErrorNone; 197 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_OMX_GetHandle : %s", "OMX_ErrorNone"); 198 goto EXIT; 199 } 200 } 201 202 ret = OMX_ErrorComponentNotFound; 203 204EXIT: 205 FunctionOut(); 206 207 return ret; 208} 209 210OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent) 211{ 212 OMX_ERRORTYPE ret = OMX_ErrorNone; 213 EXYNOS_OMX_COMPONENT *currentComponent; 214 EXYNOS_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 Exynos_OSAL_MutexLock(ghLoadComponentListMutex); 229 currentComponent = gLoadComponentList; 230 if (gLoadComponentList->pOMXComponent == hComponent) { 231 deleteComponent = gLoadComponentList; 232 gLoadComponentList = gLoadComponentList->nextOMXComp; 233 } else { 234 while ((currentComponent != NULL) && (((EXYNOS_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent != hComponent)) 235 currentComponent = currentComponent->nextOMXComp; 236 237 if (((EXYNOS_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 Exynos_OSAL_MutexUnlock(ghLoadComponentListMutex); 243 goto EXIT; 244 } 245 } 246 Exynos_OSAL_MutexUnlock(ghLoadComponentListMutex); 247 248 Exynos_OMX_ComponentUnload(deleteComponent); 249 Exynos_OSAL_Free(deleteComponent); 250 251EXIT: 252 FunctionOut(); 253 254 return ret; 255} 256 257OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_SetupTunnel( 258 OMX_IN OMX_HANDLETYPE hOutput, 259 OMX_IN OMX_U32 nPortOutput, 260 OMX_IN OMX_HANDLETYPE hInput, 261 OMX_IN OMX_U32 nPortInput) 262{ 263 OMX_ERRORTYPE ret = OMX_ErrorNotImplemented; 264 265EXIT: 266 return ret; 267} 268 269OMX_API OMX_ERRORTYPE Exynos_OMX_GetContentPipe( 270 OMX_OUT OMX_HANDLETYPE *hPipe, 271 OMX_IN OMX_STRING szURI) 272{ 273 OMX_ERRORTYPE ret = OMX_ErrorNotImplemented; 274 275EXIT: 276 return ret; 277} 278 279OMX_API OMX_ERRORTYPE Exynos_OMX_GetComponentsOfRole ( 280 OMX_IN OMX_STRING role, 281 OMX_INOUT OMX_U32 *pNumComps, 282 OMX_INOUT OMX_U8 **compNames) 283{ 284 OMX_ERRORTYPE ret = OMX_ErrorNone; 285 int max_role_num = 0; 286 OMX_STRING RoleString[MAX_OMX_COMPONENT_ROLE_SIZE]; 287 int i = 0, j = 0; 288 289 FunctionIn(); 290 291 if (gInitialized != 1) { 292 ret = OMX_ErrorNotReady; 293 goto EXIT; 294 } 295 296 *pNumComps = 0; 297 298 for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) { 299 max_role_num = gComponentList[i].component.totalRoleNum; 300 301 for (j = 0; j < max_role_num; j++) { 302 if (Exynos_OSAL_Strcmp(gComponentList[i].component.roles[j], role) == 0) { 303 if (compNames != NULL) { 304 Exynos_OSAL_Strcpy((OMX_STRING)compNames[*pNumComps], gComponentList[i].component.componentName); 305 } 306 *pNumComps = (*pNumComps + 1); 307 } 308 } 309 } 310 311EXIT: 312 FunctionOut(); 313 314 return ret; 315} 316 317OMX_API OMX_ERRORTYPE Exynos_OMX_GetRolesOfComponent ( 318 OMX_IN OMX_STRING compName, 319 OMX_INOUT OMX_U32 *pNumRoles, 320 OMX_OUT OMX_U8 **roles) 321{ 322 OMX_ERRORTYPE ret = OMX_ErrorNone; 323 OMX_BOOL detectComp = OMX_FALSE; 324 int compNum = 0, totalRoleNum = 0; 325 int i = 0; 326 327 FunctionIn(); 328 329 if (gInitialized != 1) { 330 ret = OMX_ErrorNotReady; 331 goto EXIT; 332 } 333 334 for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) { 335 if (gComponentList != NULL) { 336 if (Exynos_OSAL_Strcmp(gComponentList[i].component.componentName, compName) == 0) { 337 *pNumRoles = totalRoleNum = gComponentList[i].component.totalRoleNum; 338 compNum = i; 339 detectComp = OMX_TRUE; 340 break; 341 } 342 } else { 343 ret = OMX_ErrorUndefined; 344 goto EXIT; 345 } 346 } 347 348 if (detectComp == OMX_FALSE) { 349 *pNumRoles = 0; 350 ret = OMX_ErrorComponentNotFound; 351 goto EXIT; 352 } 353 354 if (roles != NULL) { 355 for (i = 0; i < totalRoleNum; i++) { 356 Exynos_OSAL_Strcpy(roles[i], gComponentList[compNum].component.roles[i]); 357 } 358 } 359 360EXIT: 361 FunctionOut(); 362 363 return ret; 364} 365