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