4e12c13ab2c428b37d818e920ff1fa0d8f56aa43
[GitHub/LineageOS/android_hardware_samsung_slsi_openmax.git] / core / Exynos_OMX_Core.c
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
46 static int gInitialized = 0;
47 static OMX_U32 gComponentNum = 0;
48
49 static EXYNOS_OMX_COMPONENT_REGLIST *gComponentList = NULL;
50 static EXYNOS_OMX_COMPONENT *gLoadComponentList = NULL;
51 static OMX_HANDLETYPE ghLoadComponentListMutex = NULL;
52
53
54 OMX_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
83 EXIT:
84 FunctionOut();
85
86 return ret;
87 }
88
89 OMX_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
108 EXIT:
109 FunctionOut();
110
111 return ret;
112 }
113
114 OMX_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
131 EXIT:
132 FunctionOut();
133
134 return ret;
135 }
136
137 OMX_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
204 EXIT:
205 FunctionOut();
206
207 return ret;
208 }
209
210 OMX_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
251 EXIT:
252 FunctionOut();
253
254 return ret;
255 }
256
257 OMX_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
265 EXIT:
266 return ret;
267 }
268
269 OMX_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
275 EXIT:
276 return ret;
277 }
278
279 OMX_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
311 EXIT:
312 FunctionOut();
313
314 return ret;
315 }
316
317 OMX_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
360 EXIT:
361 FunctionOut();
362
363 return ret;
364 }