1 /*
2 *
3 * Copyright 2013 Rockchip Electronics 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 Rockchip_OMX_Core.c
20 * @brief Rockchip OpenMAX IL Core
21 * @author csy (csy@rock-chips.com)
22 *
23 * @version 1.0.0
24 * @history
25 * 2013.11.26 : Create
26 */
27 #undef ROCKCHIP_LOG_TAG
28 #define ROCKCHIP_LOG_TAG "omx_core"
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <pthread.h>
34 #include "Rockchip_OMX_Component_Register.h"
35 #include "Rockchip_OSAL_Memory.h"
36 #include "Rockchip_OSAL_Mutex.h"
37 #include "Rockchip_OSAL_ETC.h"
38 #include "Rockchip_OMX_Resourcemanager.h"
39 #include "Rockchip_OSAL_Log.h"
40 #include "Rockchip_OMX_Core.h"
41
42 static int gInitialized = 0;
43 static OMX_U32 gComponentNum = 0;
44 static OMX_U32 gCount = 0;
45 static pthread_mutex_t gMutex = PTHREAD_MUTEX_INITIALIZER;
46 static ROCKCHIP_OMX_COMPONENT_REGLIST *gComponentList = NULL;
47 static ROCKCHIP_OMX_COMPONENT *gLoadComponentList = NULL;
48 static OMX_HANDLETYPE ghLoadComponentListMutex = NULL;
49
50
OMX_Init(void)51 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void)
52 {
53 OMX_ERRORTYPE ret = OMX_ErrorNone;
54
55 FunctionIn();
56 Rockchip_OSAL_MutexLock(&gMutex);
57 gCount++;
58 if (gInitialized == 0) {
59 if (Rockchip_OMX_Component_Register(&gComponentList, &gComponentNum)) {
60 ret = OMX_ErrorInsufficientResources;
61 omx_err("Rockchip_OMX_Init : %s", "OMX_ErrorInsufficientResources");
62 goto EXIT;
63 }
64
65 ret = Rockchip_OMX_ResourceManager_Init();
66 if (OMX_ErrorNone != ret) {
67 omx_err("Rockchip_OMX_Init : Rockchip_OMX_ResourceManager_Init failed");
68 goto EXIT;
69 }
70
71 ret = Rockchip_OSAL_MutexCreate(&ghLoadComponentListMutex);
72 if (OMX_ErrorNone != ret) {
73 omx_err("Rockchip_OMX_Init : Rockchip_OSAL_MutexCreate(&ghLoadComponentListMutex) failed");
74 goto EXIT;
75 }
76
77 gInitialized = 1;
78 omx_trace("Rockchip_OMX_Init : %s", "OMX_ErrorNone");
79 }
80
81 EXIT:
82
83 Rockchip_OSAL_MutexUnlock(&gMutex);
84 FunctionOut();
85
86 return ret;
87 }
88
OMX_Deinit(void)89 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void)
90 {
91 OMX_ERRORTYPE ret = OMX_ErrorNone;
92
93 FunctionIn();
94 Rockchip_OSAL_MutexLock(&gMutex);
95 gCount--;
96 if (gCount == 0) {
97 Rockchip_OSAL_MutexTerminate(ghLoadComponentListMutex);
98 ghLoadComponentListMutex = NULL;
99
100 Rockchip_OMX_ResourceManager_Deinit();
101
102 if (OMX_ErrorNone != Rockchip_OMX_Component_Unregister(gComponentList)) {
103 ret = OMX_ErrorUndefined;
104 goto EXIT;
105 }
106 gComponentList = NULL;
107 gComponentNum = 0;
108 gInitialized = 0;
109 }
110 EXIT:
111 Rockchip_OSAL_MutexUnlock(&gMutex);
112 FunctionOut();
113
114 return ret;
115 }
116
OMX_ComponentNameEnum(OMX_OUT OMX_STRING cComponentName,OMX_IN OMX_U32 nNameLength,OMX_IN OMX_U32 nIndex)117 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum(
118 OMX_OUT OMX_STRING cComponentName,
119 OMX_IN OMX_U32 nNameLength,
120 OMX_IN OMX_U32 nIndex)
121 {
122 OMX_ERRORTYPE ret = OMX_ErrorNone;
123
124 FunctionIn();
125
126 if (nIndex >= gComponentNum) {
127 ret = OMX_ErrorNoMore;
128 goto EXIT;
129 }
130
131 snprintf(cComponentName, nNameLength, "%s", gComponentList[nIndex].component.componentName);
132 ret = OMX_ErrorNone;
133
134 EXIT:
135 FunctionOut();
136
137 return ret;
138 }
139
OMX_GetHandle(OMX_OUT OMX_HANDLETYPE * pHandle,OMX_IN OMX_STRING cComponentName,OMX_IN OMX_PTR pAppData,OMX_IN OMX_CALLBACKTYPE * pCallBacks)140 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
141 OMX_OUT OMX_HANDLETYPE *pHandle,
142 OMX_IN OMX_STRING cComponentName,
143 OMX_IN OMX_PTR pAppData,
144 OMX_IN OMX_CALLBACKTYPE *pCallBacks)
145 {
146 OMX_ERRORTYPE ret = OMX_ErrorNone;
147 ROCKCHIP_OMX_COMPONENT *loadComponent;
148 ROCKCHIP_OMX_COMPONENT *currentComponent;
149 unsigned int i = 0;
150
151 FunctionIn();
152
153 if (gInitialized != 1) {
154 ret = OMX_ErrorNotReady;
155 goto EXIT;
156 }
157
158 if ((pHandle == NULL) || (cComponentName == NULL) || (pCallBacks == NULL)) {
159 ret = OMX_ErrorBadParameter;
160 goto EXIT;
161 }
162 omx_trace("ComponentName : %s", cComponentName);
163
164 for (i = 0; i < gComponentNum; i++) {
165 if (Rockchip_OSAL_Strcmp(cComponentName, gComponentList[i].component.componentName) == 0) {
166 loadComponent = Rockchip_OSAL_Malloc(sizeof(ROCKCHIP_OMX_COMPONENT));
167 Rockchip_OSAL_Memset(loadComponent, 0, sizeof(ROCKCHIP_OMX_COMPONENT));
168
169 Rockchip_OSAL_Strcpy(loadComponent->libName, gComponentList[i].libName);
170 Rockchip_OSAL_Strcpy(loadComponent->componentName, gComponentList[i].component.componentName);
171 ret = Rockchip_OMX_ComponentLoad(loadComponent);
172 if (ret != OMX_ErrorNone) {
173 Rockchip_OSAL_Free(loadComponent);
174 omx_err("OMX_Error, Line:%d", __LINE__);
175 goto EXIT;
176 }
177
178 ret = loadComponent->pOMXComponent->SetCallbacks(loadComponent->pOMXComponent, pCallBacks, pAppData);
179 if (ret != OMX_ErrorNone) {
180 Rockchip_OMX_ComponentUnload(loadComponent);
181 Rockchip_OSAL_Free(loadComponent);
182 omx_err("OMX_Error 0x%x, Line:%d", ret, __LINE__);
183 goto EXIT;
184 }
185
186 ret = Rockchip_OMX_Check_Resource(loadComponent->pOMXComponent);
187 if (ret != OMX_ErrorNone) {
188 Rockchip_OMX_ComponentUnload(loadComponent);
189 Rockchip_OSAL_Free(loadComponent);
190 omx_err("OMX_Error 0x%x, Line:%d", ret, __LINE__);
191
192 goto EXIT;
193 }
194 Rockchip_OSAL_MutexLock(ghLoadComponentListMutex);
195 if (gLoadComponentList == NULL) {
196 gLoadComponentList = loadComponent;
197 } else {
198 currentComponent = gLoadComponentList;
199 while (currentComponent->nextOMXComp != NULL) {
200 currentComponent = currentComponent->nextOMXComp;
201 }
202 currentComponent->nextOMXComp = loadComponent;
203 }
204 Rockchip_OSAL_MutexUnlock(ghLoadComponentListMutex);
205
206 *pHandle = loadComponent->pOMXComponent;
207
208 ret = OMX_ErrorNone;
209 omx_trace("Rockchip_OMX_GetHandle : %s", "OMX_ErrorNone");
210 goto EXIT;
211 }
212 }
213
214 ret = OMX_ErrorComponentNotFound;
215
216 EXIT:
217 FunctionOut();
218
219 return ret;
220 }
221
OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent)222 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent)
223 {
224 OMX_ERRORTYPE ret = OMX_ErrorNone;
225 ROCKCHIP_OMX_COMPONENT *currentComponent = NULL;
226 ROCKCHIP_OMX_COMPONENT *deleteComponent = NULL;
227
228 FunctionIn();
229
230 if (gInitialized != 1) {
231 ret = OMX_ErrorNotReady;
232 goto EXIT;
233 }
234
235 if (!hComponent) {
236 ret = OMX_ErrorBadParameter;
237 goto EXIT;
238 }
239
240 Rockchip_OSAL_MutexLock(ghLoadComponentListMutex);
241 currentComponent = gLoadComponentList;
242
243 if (gLoadComponentList->pOMXComponent == hComponent) {
244 deleteComponent = gLoadComponentList;
245 gLoadComponentList = gLoadComponentList->nextOMXComp;
246 } else {
247 while ((currentComponent != NULL) &&
248 (((ROCKCHIP_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent != hComponent))
249 currentComponent = currentComponent->nextOMXComp;
250
251 if (((ROCKCHIP_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent == hComponent) {
252 deleteComponent = currentComponent->nextOMXComp;
253 currentComponent->nextOMXComp = deleteComponent->nextOMXComp;
254 } else if (currentComponent == NULL) {
255 ret = OMX_ErrorComponentNotFound;
256 Rockchip_OSAL_MutexUnlock(ghLoadComponentListMutex);
257 goto EXIT;
258 }
259 }
260 Rockchip_OSAL_MutexUnlock(ghLoadComponentListMutex);
261
262 Rockchip_OMX_ComponentUnload(deleteComponent);
263 Rockchip_OSAL_Free(deleteComponent);
264 omx_err("OMX_FreeHandle : %s", "OMX_ErrorNone");
265 EXIT:
266 FunctionOut();
267
268 return ret;
269 }
270
OMX_SetupTunnel(OMX_IN OMX_HANDLETYPE hOutput,OMX_IN OMX_U32 nPortOutput,OMX_IN OMX_HANDLETYPE hInput,OMX_IN OMX_U32 nPortInput)271 OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel(
272 OMX_IN OMX_HANDLETYPE hOutput,
273 OMX_IN OMX_U32 nPortOutput,
274 OMX_IN OMX_HANDLETYPE hInput,
275 OMX_IN OMX_U32 nPortInput)
276 {
277 OMX_ERRORTYPE ret = OMX_ErrorNotImplemented;
278 (void)hOutput;
279 (void)nPortOutput;
280 (void)hInput;
281 (void)nPortInput;
282 goto EXIT;
283 EXIT:
284 return ret;
285 }
286
OMX_GetContentPipe(OMX_OUT OMX_HANDLETYPE * hPipe,OMX_IN OMX_STRING szURI)287 OMX_API OMX_ERRORTYPE OMX_GetContentPipe(
288 OMX_OUT OMX_HANDLETYPE *hPipe,
289 OMX_IN OMX_STRING szURI)
290 {
291 OMX_ERRORTYPE ret = OMX_ErrorNotImplemented;
292 (void)hPipe;
293 (void)szURI;
294 goto EXIT;
295 EXIT:
296 return ret;
297 }
298
OMX_GetComponentsOfRole(OMX_IN OMX_STRING role,OMX_INOUT OMX_U32 * pNumComps,OMX_INOUT OMX_U8 ** compNames)299 OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole (
300 OMX_IN OMX_STRING role,
301 OMX_INOUT OMX_U32 *pNumComps,
302 OMX_INOUT OMX_U8 **compNames)
303 {
304 OMX_ERRORTYPE ret = OMX_ErrorNone;
305 int max_role_num = 0;
306 int i = 0, j = 0;
307
308 FunctionIn();
309
310 if (gInitialized != 1) {
311 ret = OMX_ErrorNotReady;
312 goto EXIT;
313 }
314
315 *pNumComps = 0;
316
317 for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) {
318 max_role_num = gComponentList[i].component.totalRoleNum;
319
320 for (j = 0; j < max_role_num; j++) {
321 if (Rockchip_OSAL_Strcmp(gComponentList[i].component.roles[j], role) == 0) {
322 if (compNames != NULL) {
323 Rockchip_OSAL_Strcpy((OMX_STRING)compNames[*pNumComps], gComponentList[i].component.componentName);
324 }
325 *pNumComps = (*pNumComps + 1);
326 }
327 }
328 }
329
330 EXIT:
331 FunctionOut();
332
333 return ret;
334 }
335
OMX_GetRolesOfComponent(OMX_IN OMX_STRING compName,OMX_INOUT OMX_U32 * pNumRoles,OMX_OUT OMX_U8 ** roles)336 OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent (
337 OMX_IN OMX_STRING compName,
338 OMX_INOUT OMX_U32 *pNumRoles,
339 OMX_OUT OMX_U8 **roles)
340 {
341 OMX_ERRORTYPE ret = OMX_ErrorNone;
342 OMX_BOOL detectComp = OMX_FALSE;
343 int compNum = 0, totalRoleNum = 0;
344 int i = 0;
345
346 FunctionIn();
347
348 if (gInitialized != 1) {
349 ret = OMX_ErrorNotReady;
350 goto EXIT;
351 }
352
353 for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) {
354 if (gComponentList != NULL) {
355 if (Rockchip_OSAL_Strcmp(gComponentList[i].component.componentName, compName) == 0) {
356 *pNumRoles = totalRoleNum = gComponentList[i].component.totalRoleNum;
357 compNum = i;
358 detectComp = OMX_TRUE;
359 break;
360 }
361 } else {
362 ret = OMX_ErrorUndefined;
363 goto EXIT;
364 }
365 }
366
367 if (detectComp == OMX_FALSE) {
368 *pNumRoles = 0;
369 ret = OMX_ErrorComponentNotFound;
370 goto EXIT;
371 }
372
373 if (roles != NULL) {
374 for (i = 0; i < totalRoleNum; i++) {
375 Rockchip_OSAL_Strcpy(roles[i], gComponentList[compNum].component.roles[i]);
376 }
377 }
378
379 EXIT:
380 FunctionOut();
381
382 return ret;
383 }
384