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_Basecomponent.c
20 * @brief
21 * @author     SeungBeom Kim (sbcrux.kim@samsung.com)
22 *             Yunji Kim (yunji.kim@samsung.com)
23 * @version    2.0.0
24 * @history
25 *    2012.02.20 : Create
26 */
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <unistd.h>
32
33#include "Exynos_OSAL_Event.h"
34#include "Exynos_OSAL_Thread.h"
35#include "Exynos_OSAL_ETC.h"
36#include "Exynos_OSAL_Semaphore.h"
37#include "Exynos_OSAL_Mutex.h"
38#include "Exynos_OMX_Baseport.h"
39#include "Exynos_OMX_Basecomponent.h"
40#include "Exynos_OMX_Resourcemanager.h"
41#include "Exynos_OMX_Macros.h"
42
43#undef  EXYNOS_LOG_TAG
44#define EXYNOS_LOG_TAG    "EXYNOS_BASE_COMP"
45#define EXYNOS_LOG_OFF
46//#define EXYNOS_TRACE_ON
47#include "Exynos_OSAL_Log.h"
48
49
50/* Change CHECK_SIZE_VERSION Macro */
51OMX_ERRORTYPE Exynos_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size)
52{
53    OMX_ERRORTYPE ret = OMX_ErrorNone;
54
55    OMX_VERSIONTYPE* version = NULL;
56    if (header == NULL) {
57        ret = OMX_ErrorBadParameter;
58        goto EXIT;
59    }
60    version = (OMX_VERSIONTYPE*)((char*)header + sizeof(OMX_U32));
61    if (*((OMX_U32*)header) != size) {
62        ret = OMX_ErrorBadParameter;
63        goto EXIT;
64    }
65    if (version->s.nVersionMajor != VERSIONMAJOR_NUMBER ||
66        version->s.nVersionMinor != VERSIONMINOR_NUMBER) {
67        ret = OMX_ErrorVersionMismatch;
68        goto EXIT;
69    }
70    ret = OMX_ErrorNone;
71EXIT:
72    return ret;
73}
74
75OMX_ERRORTYPE Exynos_OMX_GetComponentVersion(
76    OMX_IN  OMX_HANDLETYPE   hComponent,
77    OMX_OUT OMX_STRING       pComponentName,
78    OMX_OUT OMX_VERSIONTYPE *pComponentVersion,
79    OMX_OUT OMX_VERSIONTYPE *pSpecVersion,
80    OMX_OUT OMX_UUIDTYPE    *pComponentUUID)
81{
82    OMX_ERRORTYPE             ret = OMX_ErrorNone;
83    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
84    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
85    OMX_U32                   compUUID[3];
86
87    FunctionIn();
88
89    /* check parameters */
90    if (hComponent     == NULL ||
91        pComponentName == NULL || pComponentVersion == NULL ||
92        pSpecVersion   == NULL || pComponentUUID    == NULL) {
93        ret = OMX_ErrorBadParameter;
94        goto EXIT;
95    }
96    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
97    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
98    if (ret != OMX_ErrorNone) {
99        goto EXIT;
100    }
101
102    if (pOMXComponent->pComponentPrivate == NULL) {
103        ret = OMX_ErrorBadParameter;
104        goto EXIT;
105    }
106    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
107
108    if (pExynosComponent->currentState == OMX_StateInvalid) {
109        ret = OMX_ErrorInvalidState;
110        goto EXIT;
111    }
112
113    Exynos_OSAL_Strcpy(pComponentName, pExynosComponent->componentName);
114    Exynos_OSAL_Memcpy(pComponentVersion, &(pExynosComponent->componentVersion), sizeof(OMX_VERSIONTYPE));
115    Exynos_OSAL_Memcpy(pSpecVersion, &(pExynosComponent->specVersion), sizeof(OMX_VERSIONTYPE));
116
117    /* Fill UUID with handle address, PID and UID.
118     * This should guarantee uiniqness */
119    compUUID[0] = (OMX_U32)pOMXComponent;
120    compUUID[1] = getpid();
121    compUUID[2] = getuid();
122    Exynos_OSAL_Memcpy(*pComponentUUID, compUUID, 3 * sizeof(*compUUID));
123
124    ret = OMX_ErrorNone;
125
126EXIT:
127    FunctionOut();
128
129    return ret;
130}
131
132OMX_ERRORTYPE Exynos_OMX_GetState (
133    OMX_IN OMX_HANDLETYPE  hComponent,
134    OMX_OUT OMX_STATETYPE *pState)
135{
136    OMX_ERRORTYPE             ret = OMX_ErrorNone;
137    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
138    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
139
140    FunctionIn();
141
142    if (hComponent == NULL || pState == NULL) {
143        ret = OMX_ErrorBadParameter;
144        goto EXIT;
145    }
146    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
147    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
148    if (ret != OMX_ErrorNone) {
149        goto EXIT;
150    }
151
152    if (pOMXComponent->pComponentPrivate == NULL) {
153        ret = OMX_ErrorBadParameter;
154        goto EXIT;
155    }
156    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
157
158    *pState = pExynosComponent->currentState;
159    ret = OMX_ErrorNone;
160
161EXIT:
162    FunctionOut();
163
164    return ret;
165}
166
167OMX_ERRORTYPE Exynos_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 messageParam)
168{
169    OMX_ERRORTYPE             ret = OMX_ErrorNone;
170    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
171    EXYNOS_OMX_MESSAGE       *message;
172    OMX_STATETYPE             destState = messageParam;
173    OMX_STATETYPE             currentState = pExynosComponent->currentState;
174    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
175    OMX_S32                   countValue = 0;
176    unsigned int              i = 0, j = 0;
177    int                       k = 0;
178
179    FunctionIn();
180
181    /* check parameters */
182    if (currentState == destState) {
183         ret = OMX_ErrorSameState;
184            goto EXIT;
185    }
186    if (currentState == OMX_StateInvalid) {
187        ret = OMX_ErrorInvalidState;
188        goto EXIT;
189    }
190
191    if ((currentState == OMX_StateLoaded) && (destState == OMX_StateIdle)) {
192        ret = Exynos_OMX_Get_Resource(pOMXComponent);
193        if (ret != OMX_ErrorNone) {
194            Exynos_OSAL_SignalSet(pExynosComponent->abendStateEvent);
195            goto EXIT;
196        }
197    }
198    if (((currentState == OMX_StateIdle) && (destState == OMX_StateLoaded))       ||
199        ((currentState == OMX_StateIdle) && (destState == OMX_StateInvalid))      ||
200        ((currentState == OMX_StateExecuting) && (destState == OMX_StateInvalid)) ||
201        ((currentState == OMX_StatePause) && (destState == OMX_StateInvalid))) {
202        Exynos_OMX_Release_Resource(pOMXComponent);
203    }
204
205    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "destState: %d currentState: %d", destState, currentState);
206    switch (destState) {
207    case OMX_StateInvalid:
208        switch (currentState) {
209        case OMX_StateWaitForResources:
210            Exynos_OMX_Out_WaitForResource(pOMXComponent);
211        case OMX_StateIdle:
212        case OMX_StateExecuting:
213        case OMX_StatePause:
214        case OMX_StateLoaded:
215            pExynosComponent->currentState = OMX_StateInvalid;
216            ret = pExynosComponent->exynos_BufferProcessTerminate(pOMXComponent);
217
218            for (i = 0; i < ALL_PORT_NUM; i++) {
219                if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
220                    Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
221                    pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL;
222                } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
223                    Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
224                    pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL;
225                    Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
226                    pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL;
227                }
228                Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
229                pExynosComponent->pExynosPort[i].hPortMutex = NULL;
230            }
231
232            if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
233                Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent);
234                pExynosComponent->pauseEvent = NULL;
235            } else {
236                for (i = 0; i < ALL_PORT_NUM; i++) {
237                    Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
238                    pExynosComponent->pExynosPort[i].pauseEvent = NULL;
239                    if (pExynosComponent->pExynosPort[i].bufferProcessType == BUFFER_SHARE) {
240                        Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent);
241                        pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL;
242                    }
243                }
244            }
245            for (i = 0; i < ALL_PORT_NUM; i++) {
246                Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID);
247                pExynosComponent->pExynosPort[i].bufferSemID = NULL;
248            }
249            if (pExynosComponent->exynos_codec_componentTerminate != NULL)
250                pExynosComponent->exynos_codec_componentTerminate(pOMXComponent);
251
252            ret = OMX_ErrorInvalidState;
253            break;
254        default:
255            ret = OMX_ErrorInvalidState;
256            break;
257        }
258        break;
259    case OMX_StateLoaded:
260        switch (currentState) {
261        case OMX_StateIdle:
262            ret = pExynosComponent->exynos_BufferProcessTerminate(pOMXComponent);
263
264            for (i = 0; i < ALL_PORT_NUM; i++) {
265                if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
266                    Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
267                    pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL;
268                } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
269                    Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
270                    pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL;
271                    Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
272                    pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL;
273                }
274                Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
275                pExynosComponent->pExynosPort[i].hPortMutex = NULL;
276            }
277            if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
278                Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent);
279                pExynosComponent->pauseEvent = NULL;
280            } else {
281                for (i = 0; i < ALL_PORT_NUM; i++) {
282                    Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
283                    pExynosComponent->pExynosPort[i].pauseEvent = NULL;
284                    if (pExynosComponent->pExynosPort[i].bufferProcessType == BUFFER_SHARE) {
285                        Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent);
286                        pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL;
287                    }
288                }
289            }
290            for (i = 0; i < ALL_PORT_NUM; i++) {
291                Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID);
292                pExynosComponent->pExynosPort[i].bufferSemID = NULL;
293            }
294
295            pExynosComponent->exynos_codec_componentTerminate(pOMXComponent);
296
297            for (i = 0; i < (pExynosComponent->portParam.nPorts); i++) {
298                pExynosPort = (pExynosComponent->pExynosPort + i);
299                if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
300                    while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
301                        message = (EXYNOS_OMX_MESSAGE*)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
302                        if (message != NULL)
303                            Exynos_OSAL_Free(message);
304                    }
305                    ret = pExynosComponent->exynos_FreeTunnelBuffer(pExynosPort, i);
306                    if (OMX_ErrorNone != ret) {
307                        goto EXIT;
308                    }
309                } else {
310                    if (CHECK_PORT_ENABLED(pExynosPort)) {
311                        Exynos_OSAL_SemaphoreWait(pExynosPort->unloadedResource);
312                        pExynosPort->portDefinition.bPopulated = OMX_FALSE;
313                    }
314                }
315            }
316            pExynosComponent->currentState = OMX_StateLoaded;
317            break;
318        case OMX_StateWaitForResources:
319            ret = Exynos_OMX_Out_WaitForResource(pOMXComponent);
320            pExynosComponent->currentState = OMX_StateLoaded;
321            break;
322        case OMX_StateExecuting:
323        case OMX_StatePause:
324        default:
325            ret = OMX_ErrorIncorrectStateTransition;
326            break;
327        }
328        break;
329    case OMX_StateIdle:
330        switch (currentState) {
331        case OMX_StateLoaded:
332            for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
333                pExynosPort = (pExynosComponent->pExynosPort + i);
334                if (pExynosPort == NULL) {
335                    ret = OMX_ErrorBadParameter;
336                    goto EXIT;
337                }
338                if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
339                    if (CHECK_PORT_ENABLED(pExynosPort)) {
340                        ret = pExynosComponent->exynos_AllocateTunnelBuffer(pExynosPort, i);
341                        if (ret!=OMX_ErrorNone)
342                            goto EXIT;
343                    }
344                } else {
345                    if (CHECK_PORT_ENABLED(pExynosPort)) {
346                        Exynos_OSAL_SemaphoreWait(pExynosComponent->pExynosPort[i].loadedResource);
347                        if (pExynosComponent->abendState == OMX_TRUE) {
348                            Exynos_OSAL_SignalSet(pExynosComponent->abendStateEvent);
349                            ret = Exynos_OMX_Release_Resource(pOMXComponent);
350                            goto EXIT;
351                        }
352                        pExynosPort->portDefinition.bPopulated = OMX_TRUE;
353                    }
354                }
355            }
356            ret = pExynosComponent->exynos_codec_componentInit(pOMXComponent);
357            if (ret != OMX_ErrorNone) {
358                /*
359                 * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free
360                 */
361                Exynos_OSAL_SignalSet(pExynosComponent->abendStateEvent);
362                Exynos_OMX_Release_Resource(pOMXComponent);
363                goto EXIT;
364            }
365            if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
366                Exynos_OSAL_SignalCreate(&pExynosComponent->pauseEvent);
367            } else {
368                for (i = 0; i < ALL_PORT_NUM; i++) {
369                    Exynos_OSAL_SignalCreate(&pExynosComponent->pExynosPort[i].pauseEvent);
370                    if (pExynosComponent->pExynosPort[i].bufferProcessType == BUFFER_SHARE)
371                        Exynos_OSAL_SignalCreate(&pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent);
372                }
373            }
374            for (i = 0; i < ALL_PORT_NUM; i++) {
375                ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->pExynosPort[i].bufferSemID);
376                if (ret != OMX_ErrorNone) {
377                    ret = OMX_ErrorInsufficientResources;
378                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
379                    goto EXIT;
380                }
381            }
382            for (i = 0; i < ALL_PORT_NUM; i++) {
383                if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
384                    ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
385                    if (ret != OMX_ErrorNone) {
386                        ret = OMX_ErrorInsufficientResources;
387                        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
388                        goto EXIT;
389                    }
390                } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
391                    ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
392                    if (ret != OMX_ErrorNone) {
393                        ret = OMX_ErrorInsufficientResources;
394                        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
395                        goto EXIT;
396                    }
397                    ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
398                    if (ret != OMX_ErrorNone) {
399                        ret = OMX_ErrorInsufficientResources;
400                        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
401                        goto EXIT;
402                    }
403                }
404                ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].hPortMutex);
405                if (ret != OMX_ErrorNone) {
406                    ret = OMX_ErrorInsufficientResources;
407                    goto EXIT;
408                }
409            }
410
411            ret = pExynosComponent->exynos_BufferProcessCreate(pOMXComponent);
412            if (ret != OMX_ErrorNone) {
413                /*
414                 * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free
415                 */
416                if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
417                    Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent);
418                    pExynosComponent->pauseEvent = NULL;
419                } else {
420                    for (i = 0; i < ALL_PORT_NUM; i++) {
421                        Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
422                        pExynosComponent->pExynosPort[i].pauseEvent = NULL;
423                        if (pExynosComponent->pExynosPort[i].bufferProcessType == BUFFER_SHARE) {
424                            Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent);
425                            pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL;
426                        }
427                    }
428                }
429                for (i = 0; i < ALL_PORT_NUM; i++) {
430                    if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
431                        Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
432                        pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL;
433                    } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
434                        Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
435                        pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL;
436                        Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
437                        pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL;
438                    }
439                    Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
440                    pExynosComponent->pExynosPort[i].hPortMutex = NULL;
441                }
442                for (i = 0; i < ALL_PORT_NUM; i++) {
443                    Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID);
444                    pExynosComponent->pExynosPort[i].bufferSemID = NULL;
445                }
446
447                ret = OMX_ErrorInsufficientResources;
448                goto EXIT;
449            }
450            pExynosComponent->currentState = OMX_StateIdle;
451            break;
452        case OMX_StateExecuting:
453        case OMX_StatePause:
454            Exynos_OMX_BufferFlushProcess(pOMXComponent, ALL_PORT_INDEX, OMX_FALSE);
455            pExynosComponent->currentState = OMX_StateIdle;
456            break;
457        case OMX_StateWaitForResources:
458            pExynosComponent->currentState = OMX_StateIdle;
459            break;
460        default:
461            ret = OMX_ErrorIncorrectStateTransition;
462            break;
463        }
464        break;
465    case OMX_StateExecuting:
466        switch (currentState) {
467        case OMX_StateLoaded:
468            ret = OMX_ErrorIncorrectStateTransition;
469            break;
470        case OMX_StateIdle:
471            for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
472                pExynosPort = &pExynosComponent->pExynosPort[i];
473                if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort) && CHECK_PORT_ENABLED(pExynosPort)) {
474                    for (j = 0; j < pExynosPort->tunnelBufferNum; j++) {
475                        Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID);
476                    }
477                }
478            }
479
480            pExynosComponent->transientState = EXYNOS_OMX_TransStateMax;
481            pExynosComponent->currentState = OMX_StateExecuting;
482            if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
483                Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
484            } else {
485                for (i = 0; i < ALL_PORT_NUM; i++) {
486                    Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[i].pauseEvent);
487                }
488            }
489            break;
490        case OMX_StatePause:
491            for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
492                pExynosPort = &pExynosComponent->pExynosPort[i];
493                if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort) && CHECK_PORT_ENABLED(pExynosPort)) {
494                    OMX_S32 semaValue = 0, cnt = 0;
495                    Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[i].bufferSemID, &semaValue);
496                    if (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > semaValue) {
497                        cnt = Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) - semaValue;
498                        for (k = 0; k < cnt; k++) {
499                            Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID);
500                        }
501                    }
502                }
503            }
504
505            pExynosComponent->currentState = OMX_StateExecuting;
506            if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
507                Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
508            } else {
509                for (i = 0; i < ALL_PORT_NUM; i++) {
510                    Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[i].pauseEvent);
511                }
512            }
513            break;
514        case OMX_StateWaitForResources:
515            ret = OMX_ErrorIncorrectStateTransition;
516            break;
517        default:
518            ret = OMX_ErrorIncorrectStateTransition;
519            break;
520        }
521        break;
522    case OMX_StatePause:
523        switch (currentState) {
524        case OMX_StateLoaded:
525            ret = OMX_ErrorIncorrectStateTransition;
526            break;
527        case OMX_StateIdle:
528            pExynosComponent->currentState = OMX_StatePause;
529            break;
530        case OMX_StateExecuting:
531            pExynosComponent->currentState = OMX_StatePause;
532            break;
533        case OMX_StateWaitForResources:
534            ret = OMX_ErrorIncorrectStateTransition;
535            break;
536        default:
537            ret = OMX_ErrorIncorrectStateTransition;
538            break;
539        }
540        break;
541    case OMX_StateWaitForResources:
542        switch (currentState) {
543        case OMX_StateLoaded:
544            ret = Exynos_OMX_In_WaitForResource(pOMXComponent);
545            pExynosComponent->currentState = OMX_StateWaitForResources;
546            break;
547        case OMX_StateIdle:
548        case OMX_StateExecuting:
549        case OMX_StatePause:
550            ret = OMX_ErrorIncorrectStateTransition;
551            break;
552        default:
553            ret = OMX_ErrorIncorrectStateTransition;
554            break;
555        }
556        break;
557    default:
558        ret = OMX_ErrorIncorrectStateTransition;
559        break;
560    }
561
562EXIT:
563    if (ret == OMX_ErrorNone) {
564        if (pExynosComponent->pCallbacks != NULL) {
565            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
566            pExynosComponent->callbackData,
567            OMX_EventCmdComplete, OMX_CommandStateSet,
568            destState, NULL);
569        }
570    } else {
571        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d", __FUNCTION__, __LINE__);
572        if (pExynosComponent->pCallbacks != NULL) {
573            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
574            pExynosComponent->callbackData,
575            OMX_EventError, ret, 0, NULL);
576        }
577    }
578    FunctionOut();
579
580    return ret;
581}
582
583static OMX_ERRORTYPE Exynos_OMX_MessageHandlerThread(OMX_PTR threadData)
584{
585    OMX_ERRORTYPE             ret = OMX_ErrorNone;
586    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
587    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
588    EXYNOS_OMX_MESSAGE       *message = NULL;
589    OMX_U32                   messageType = 0, portIndex = 0;
590
591    FunctionIn();
592
593    if (threadData == NULL) {
594        ret = OMX_ErrorBadParameter;
595        goto EXIT;
596    }
597
598    pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
599    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
600    if (ret != OMX_ErrorNone) {
601        goto EXIT;
602    }
603
604    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
605
606    while (pExynosComponent->bExitMessageHandlerThread == OMX_FALSE) {
607        Exynos_OSAL_SemaphoreWait(pExynosComponent->msgSemaphoreHandle);
608        message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosComponent->messageQ);
609        if (message != NULL) {
610            messageType = message->messageType;
611            switch (messageType) {
612            case OMX_CommandStateSet:
613                ret = Exynos_OMX_ComponentStateSet(pOMXComponent, message->messageParam);
614                break;
615            case OMX_CommandFlush:
616                ret = Exynos_OMX_BufferFlushProcess(pOMXComponent, message->messageParam, OMX_TRUE);
617                break;
618            case OMX_CommandPortDisable:
619                ret = Exynos_OMX_PortDisableProcess(pOMXComponent, message->messageParam);
620                break;
621            case OMX_CommandPortEnable:
622                ret = Exynos_OMX_PortEnableProcess(pOMXComponent, message->messageParam);
623                break;
624            case OMX_CommandMarkBuffer:
625                portIndex = message->messageParam;
626                pExynosComponent->pExynosPort[portIndex].markType.hMarkTargetComponent = ((OMX_MARKTYPE *)message->pCmdData)->hMarkTargetComponent;
627                pExynosComponent->pExynosPort[portIndex].markType.pMarkData            = ((OMX_MARKTYPE *)message->pCmdData)->pMarkData;
628                break;
629            case (OMX_COMMANDTYPE)EXYNOS_OMX_CommandComponentDeInit:
630                pExynosComponent->bExitMessageHandlerThread = OMX_TRUE;
631                break;
632            default:
633                break;
634            }
635            Exynos_OSAL_Free(message);
636            message = NULL;
637        }
638    }
639
640    Exynos_OSAL_ThreadExit(NULL);
641
642EXIT:
643    FunctionOut();
644
645    return ret;
646}
647
648static OMX_ERRORTYPE Exynos_StateSet(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
649{
650    OMX_U32 destState = nParam;
651    OMX_U32 i = 0;
652
653    if ((destState == OMX_StateIdle) && (pExynosComponent->currentState == OMX_StateLoaded)) {
654        pExynosComponent->transientState = EXYNOS_OMX_TransStateLoadedToIdle;
655        for(i = 0; i < pExynosComponent->portParam.nPorts; i++) {
656            pExynosComponent->pExynosPort[i].portState = OMX_StateIdle;
657        }
658        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateIdle");
659    } else if ((destState == OMX_StateLoaded) && (pExynosComponent->currentState == OMX_StateIdle)) {
660        pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToLoaded;
661        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
662            pExynosComponent->pExynosPort[i].portState = OMX_StateLoaded;
663        }
664        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateLoaded");
665    } else if ((destState == OMX_StateIdle) && (pExynosComponent->currentState == OMX_StateExecuting)) {
666        EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
667
668        pExynosPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]);
669        if ((pExynosPort->portDefinition.bEnabled == OMX_FALSE) &&
670            (pExynosPort->portState == OMX_StateIdle)) {
671            pExynosPort->exceptionFlag = INVALID_STATE;
672            Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
673        }
674
675        pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
676        if ((pExynosPort->portDefinition.bEnabled == OMX_FALSE) &&
677            (pExynosPort->portState == OMX_StateIdle)) {
678            pExynosPort->exceptionFlag = INVALID_STATE;
679            Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
680        }
681
682        pExynosComponent->transientState = EXYNOS_OMX_TransStateExecutingToIdle;
683        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateIdle");
684    } else if ((destState == OMX_StateExecuting) && (pExynosComponent->currentState == OMX_StateIdle)) {
685        pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToExecuting;
686        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateExecuting");
687    } else if (destState == OMX_StateInvalid) {
688        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
689            pExynosComponent->pExynosPort[i].portState = OMX_StateInvalid;
690        }
691    }
692
693    return OMX_ErrorNone;
694}
695
696static OMX_ERRORTYPE Exynos_SetPortFlush(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
697{
698    OMX_ERRORTYPE        ret = OMX_ErrorNone;
699    EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
700    OMX_S32              portIndex = nParam;
701    OMX_U16              i = 0, cnt = 0, index = 0;
702
703
704    if ((pExynosComponent->currentState == OMX_StateExecuting) ||
705        (pExynosComponent->currentState == OMX_StatePause)) {
706        if ((portIndex != ALL_PORT_INDEX) &&
707           ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
708            ret = OMX_ErrorBadPortIndex;
709            goto EXIT;
710        }
711
712        /*********************
713        *    need flush event set ?????
714        **********************/
715        cnt = (portIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1;
716        for (i = 0; i < cnt; i++) {
717            if (portIndex == ALL_PORT_INDEX)
718                index = i;
719            else
720                index = portIndex;
721            pExynosComponent->pExynosPort[index].bIsPortFlushed = OMX_TRUE;
722        }
723    } else {
724        ret = OMX_ErrorIncorrectStateOperation;
725        goto EXIT;
726    }
727    ret = OMX_ErrorNone;
728
729EXIT:
730    return ret;
731}
732
733static OMX_ERRORTYPE Exynos_SetPortEnable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
734{
735    OMX_ERRORTYPE        ret = OMX_ErrorNone;
736    EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
737    OMX_S32              portIndex = nParam;
738    OMX_U16              i = 0, cnt = 0;
739
740    FunctionIn();
741
742    if ((portIndex != ALL_PORT_INDEX) &&
743        ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
744        ret = OMX_ErrorBadPortIndex;
745        goto EXIT;
746    }
747
748    if (portIndex == ALL_PORT_INDEX) {
749        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
750            pExynosPort = &pExynosComponent->pExynosPort[i];
751            if (CHECK_PORT_ENABLED(pExynosPort)) {
752                ret = OMX_ErrorIncorrectStateOperation;
753                goto EXIT;
754            } else {
755                pExynosPort->portState = OMX_StateIdle;
756            }
757        }
758    } else {
759        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
760        if (CHECK_PORT_ENABLED(pExynosPort)) {
761            ret = OMX_ErrorIncorrectStateOperation;
762            goto EXIT;
763        } else {
764            pExynosPort->portState = OMX_StateIdle;
765        }
766    }
767    ret = OMX_ErrorNone;
768
769EXIT:
770    FunctionOut();
771
772    return ret;
773
774}
775
776static OMX_ERRORTYPE Exynos_SetPortDisable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
777{
778    OMX_ERRORTYPE        ret = OMX_ErrorNone;
779    EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
780    OMX_S32              portIndex = nParam;
781    OMX_U16              i = 0, cnt = 0;
782
783    FunctionIn();
784
785    if ((portIndex != ALL_PORT_INDEX) &&
786        ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
787        ret = OMX_ErrorBadPortIndex;
788        goto EXIT;
789    }
790
791    if (portIndex == ALL_PORT_INDEX) {
792        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
793            pExynosPort = &pExynosComponent->pExynosPort[i];
794            if (!CHECK_PORT_ENABLED(pExynosPort)) {
795                ret = OMX_ErrorIncorrectStateOperation;
796                goto EXIT;
797            }
798            pExynosPort->portState = OMX_StateLoaded;
799            pExynosPort->bIsPortDisabled = OMX_TRUE;
800        }
801    } else {
802        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
803        pExynosPort->portState = OMX_StateLoaded;
804        pExynosPort->bIsPortDisabled = OMX_TRUE;
805    }
806    ret = OMX_ErrorNone;
807
808EXIT:
809    FunctionOut();
810
811    return ret;
812}
813
814static OMX_ERRORTYPE Exynos_SetMarkBuffer(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
815{
816    OMX_ERRORTYPE        ret = OMX_ErrorNone;
817    EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
818    OMX_U32              portIndex = nParam;
819    OMX_U16              i = 0, cnt = 0;
820
821
822    if (nParam >= pExynosComponent->portParam.nPorts) {
823        ret = OMX_ErrorBadPortIndex;
824        goto EXIT;
825    }
826
827    if ((pExynosComponent->currentState == OMX_StateExecuting) ||
828        (pExynosComponent->currentState == OMX_StatePause)) {
829        ret = OMX_ErrorNone;
830    } else {
831        ret = OMX_ErrorIncorrectStateOperation;
832    }
833
834EXIT:
835    return ret;
836}
837
838static OMX_ERRORTYPE Exynos_OMX_CommandQueue(
839    EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
840    OMX_COMMANDTYPE        Cmd,
841    OMX_U32                nParam,
842    OMX_PTR                pCmdData)
843{
844    OMX_ERRORTYPE    ret = OMX_ErrorNone;
845    EXYNOS_OMX_MESSAGE *command = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE));
846
847    if (command == NULL) {
848        ret = OMX_ErrorInsufficientResources;
849        goto EXIT;
850    }
851    command->messageType  = (OMX_U32)Cmd;
852    command->messageParam = nParam;
853    command->pCmdData     = pCmdData;
854
855    ret = Exynos_OSAL_Queue(&pExynosComponent->messageQ, (void *)command);
856    if (ret != 0) {
857        ret = OMX_ErrorUndefined;
858        goto EXIT;
859    }
860    ret = Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle);
861
862EXIT:
863    return ret;
864}
865
866OMX_ERRORTYPE Exynos_OMX_SendCommand(
867    OMX_IN OMX_HANDLETYPE  hComponent,
868    OMX_IN OMX_COMMANDTYPE Cmd,
869    OMX_IN OMX_U32         nParam,
870    OMX_IN OMX_PTR         pCmdData)
871{
872    OMX_ERRORTYPE             ret = OMX_ErrorNone;
873    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
874    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
875    EXYNOS_OMX_MESSAGE       *message = NULL;
876
877    FunctionIn();
878
879    if (hComponent == NULL) {
880        ret = OMX_ErrorBadParameter;
881        goto EXIT;
882    }
883    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
884    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
885    if (ret != OMX_ErrorNone) {
886        goto EXIT;
887    }
888
889    if (pOMXComponent->pComponentPrivate == NULL) {
890        ret = OMX_ErrorBadParameter;
891        goto EXIT;
892    }
893    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
894
895    if (pExynosComponent->currentState == OMX_StateInvalid) {
896        ret = OMX_ErrorInvalidState;
897        goto EXIT;
898    }
899
900    switch (Cmd) {
901    case OMX_CommandStateSet :
902        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandStateSet");
903        Exynos_StateSet(pExynosComponent, nParam);
904        break;
905    case OMX_CommandFlush :
906        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandFlush");
907        ret = Exynos_SetPortFlush(pExynosComponent, nParam);
908        if (ret != OMX_ErrorNone)
909            goto EXIT;
910        break;
911    case OMX_CommandPortDisable :
912        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandPortDisable");
913        ret = Exynos_SetPortDisable(pExynosComponent, nParam);
914        if (ret != OMX_ErrorNone)
915            goto EXIT;
916        break;
917    case OMX_CommandPortEnable :
918        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandPortEnable");
919        ret = Exynos_SetPortEnable(pExynosComponent, nParam);
920        if (ret != OMX_ErrorNone)
921            goto EXIT;
922        break;
923    case OMX_CommandMarkBuffer :
924        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandMarkBuffer");
925        ret = Exynos_SetMarkBuffer(pExynosComponent, nParam);
926        if (ret != OMX_ErrorNone)
927            goto EXIT;
928        break;
929    default:
930        break;
931    }
932
933    ret = Exynos_OMX_CommandQueue(pExynosComponent, Cmd, nParam, pCmdData);
934
935EXIT:
936    FunctionOut();
937
938    return ret;
939}
940
941OMX_ERRORTYPE Exynos_OMX_GetParameter(
942    OMX_IN OMX_HANDLETYPE hComponent,
943    OMX_IN OMX_INDEXTYPE  nParamIndex,
944    OMX_INOUT OMX_PTR     ComponentParameterStructure)
945{
946    OMX_ERRORTYPE             ret = OMX_ErrorNone;
947    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
948    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
949
950    FunctionIn();
951
952    if (hComponent == NULL) {
953        ret = OMX_ErrorBadParameter;
954        goto EXIT;
955    }
956    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
957    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
958    if (ret != OMX_ErrorNone) {
959        goto EXIT;
960    }
961
962    if (pOMXComponent->pComponentPrivate == NULL) {
963        ret = OMX_ErrorBadParameter;
964        goto EXIT;
965    }
966    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
967
968    if (ComponentParameterStructure == NULL) {
969        ret = OMX_ErrorBadParameter;
970        goto EXIT;
971    }
972    if (pExynosComponent->currentState == OMX_StateInvalid) {
973        ret = OMX_ErrorInvalidState;
974        goto EXIT;
975    }
976
977    switch (nParamIndex) {
978    case OMX_IndexParamAudioInit:
979    case OMX_IndexParamVideoInit:
980    case OMX_IndexParamImageInit:
981    case OMX_IndexParamOtherInit:
982    {
983        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
984        ret = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE));
985        if (ret != OMX_ErrorNone) {
986            goto EXIT;
987        }
988        portParam->nPorts         = 0;
989        portParam->nStartPortNumber     = 0;
990    }
991        break;
992    case OMX_IndexParamPortDefinition:
993    {
994        OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
995        OMX_U32                       portIndex = portDefinition->nPortIndex;
996        EXYNOS_OMX_BASEPORT          *pExynosPort;
997
998        if (portIndex >= pExynosComponent->portParam.nPorts) {
999            ret = OMX_ErrorBadPortIndex;
1000            goto EXIT;
1001        }
1002        ret = Exynos_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1003        if (ret != OMX_ErrorNone) {
1004            goto EXIT;
1005        }
1006
1007        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1008        Exynos_OSAL_Memcpy(portDefinition, &pExynosPort->portDefinition, portDefinition->nSize);
1009    }
1010        break;
1011    case OMX_IndexParamPriorityMgmt:
1012    {
1013        OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure;
1014
1015        ret = Exynos_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE));
1016        if (ret != OMX_ErrorNone) {
1017            goto EXIT;
1018        }
1019
1020        compPriority->nGroupID       = pExynosComponent->compPriority.nGroupID;
1021        compPriority->nGroupPriority = pExynosComponent->compPriority.nGroupPriority;
1022    }
1023        break;
1024
1025    case OMX_IndexParamCompBufferSupplier:
1026    {
1027        OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure;
1028        OMX_U32                       portIndex = bufferSupplier->nPortIndex;
1029        EXYNOS_OMX_BASEPORT          *pExynosPort;
1030
1031        if ((pExynosComponent->currentState == OMX_StateLoaded) ||
1032            (pExynosComponent->currentState == OMX_StateWaitForResources)) {
1033            if (portIndex >= pExynosComponent->portParam.nPorts) {
1034                ret = OMX_ErrorBadPortIndex;
1035                goto EXIT;
1036            }
1037            ret = Exynos_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
1038            if (ret != OMX_ErrorNone) {
1039                goto EXIT;
1040            }
1041
1042            pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1043
1044
1045            if (pExynosPort->portDefinition.eDir == OMX_DirInput) {
1046                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
1047                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput;
1048                } else if (CHECK_PORT_TUNNELED(pExynosPort)) {
1049                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput;
1050                } else {
1051                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified;
1052                }
1053            } else {
1054                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
1055                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput;
1056                } else if (CHECK_PORT_TUNNELED(pExynosPort)) {
1057                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput;
1058                } else {
1059                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified;
1060                }
1061            }
1062        }
1063        else
1064        {
1065            ret = OMX_ErrorIncorrectStateOperation;
1066            goto EXIT;
1067        }
1068    }
1069        break;
1070    default:
1071    {
1072        ret = OMX_ErrorUnsupportedIndex;
1073        goto EXIT;
1074    }
1075        break;
1076    }
1077
1078    ret = OMX_ErrorNone;
1079
1080EXIT:
1081
1082    FunctionOut();
1083
1084    return ret;
1085}
1086
1087OMX_ERRORTYPE Exynos_OMX_SetParameter(
1088    OMX_IN OMX_HANDLETYPE hComponent,
1089    OMX_IN OMX_INDEXTYPE  nIndex,
1090    OMX_IN OMX_PTR        ComponentParameterStructure)
1091{
1092    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1093    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1094    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1095
1096    FunctionIn();
1097
1098    if (hComponent == NULL) {
1099        ret = OMX_ErrorBadParameter;
1100        goto EXIT;
1101    }
1102    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1103    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1104    if (ret != OMX_ErrorNone) {
1105        goto EXIT;
1106    }
1107
1108    if (pOMXComponent->pComponentPrivate == NULL) {
1109        ret = OMX_ErrorBadParameter;
1110        goto EXIT;
1111    }
1112    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1113
1114    if (ComponentParameterStructure == NULL) {
1115        ret = OMX_ErrorBadParameter;
1116        goto EXIT;
1117    }
1118    if (pExynosComponent->currentState == OMX_StateInvalid) {
1119        ret = OMX_ErrorInvalidState;
1120        goto EXIT;
1121    }
1122
1123    switch (nIndex) {
1124    case OMX_IndexParamAudioInit:
1125    case OMX_IndexParamVideoInit:
1126    case OMX_IndexParamImageInit:
1127    case OMX_IndexParamOtherInit:
1128    {
1129        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
1130        ret = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE));
1131        if (ret != OMX_ErrorNone) {
1132            goto EXIT;
1133        }
1134
1135        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
1136            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1137            ret = OMX_ErrorIncorrectStateOperation;
1138            goto EXIT;
1139        }
1140        ret = OMX_ErrorUndefined;
1141        /* Exynos_OSAL_Memcpy(&pExynosComponent->portParam, portParam, sizeof(OMX_PORT_PARAM_TYPE)); */
1142    }
1143        break;
1144    case OMX_IndexParamPortDefinition:
1145    {
1146        OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
1147        OMX_U32                       portIndex = portDefinition->nPortIndex;
1148        EXYNOS_OMX_BASEPORT          *pExynosPort;
1149
1150        if (portIndex >= pExynosComponent->portParam.nPorts) {
1151            ret = OMX_ErrorBadPortIndex;
1152            goto EXIT;
1153        }
1154        ret = Exynos_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1155        if (ret != OMX_ErrorNone) {
1156            goto EXIT;
1157        }
1158
1159        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1160
1161        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1162            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
1163                ret = OMX_ErrorIncorrectStateOperation;
1164                goto EXIT;
1165            }
1166        }
1167        if (portDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
1168            ret = OMX_ErrorBadParameter;
1169            goto EXIT;
1170        }
1171
1172        Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, portDefinition, portDefinition->nSize);
1173    }
1174        break;
1175    case OMX_IndexParamPriorityMgmt:
1176    {
1177        OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure;
1178
1179        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
1180            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1181            ret = OMX_ErrorIncorrectStateOperation;
1182            goto EXIT;
1183        }
1184
1185        ret = Exynos_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE));
1186        if (ret != OMX_ErrorNone) {
1187            goto EXIT;
1188        }
1189
1190        pExynosComponent->compPriority.nGroupID = compPriority->nGroupID;
1191        pExynosComponent->compPriority.nGroupPriority = compPriority->nGroupPriority;
1192    }
1193        break;
1194    case OMX_IndexParamCompBufferSupplier:
1195    {
1196        OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure;
1197        OMX_U32           portIndex = bufferSupplier->nPortIndex;
1198        EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1199
1200
1201        if (portIndex >= pExynosComponent->portParam.nPorts) {
1202            ret = OMX_ErrorBadPortIndex;
1203            goto EXIT;
1204        }
1205        ret = Exynos_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
1206        if (ret != OMX_ErrorNone) {
1207            goto EXIT;
1208        }
1209
1210        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1211        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1212            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
1213                ret = OMX_ErrorIncorrectStateOperation;
1214                goto EXIT;
1215            }
1216        }
1217
1218        if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyUnspecified) {
1219            ret = OMX_ErrorNone;
1220            goto EXIT;
1221        }
1222        if (CHECK_PORT_TUNNELED(pExynosPort) == 0) {
1223            ret = OMX_ErrorNone; /*OMX_ErrorNone ?????*/
1224            goto EXIT;
1225        }
1226
1227        if (pExynosPort->portDefinition.eDir == OMX_DirInput) {
1228            if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) {
1229                /*
1230                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
1231                    ret = OMX_ErrorNone;
1232                }
1233                */
1234                pExynosPort->tunnelFlags |= EXYNOS_TUNNEL_IS_SUPPLIER;
1235                bufferSupplier->nPortIndex = pExynosPort->tunneledPort;
1236                ret = OMX_SetParameter(pExynosPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier);
1237                goto EXIT;
1238            } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) {
1239                ret = OMX_ErrorNone;
1240                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
1241                    pExynosPort->tunnelFlags &= ~EXYNOS_TUNNEL_IS_SUPPLIER;
1242                    bufferSupplier->nPortIndex = pExynosPort->tunneledPort;
1243                    ret = OMX_SetParameter(pExynosPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier);
1244                }
1245                goto EXIT;
1246            }
1247        } else if (pExynosPort->portDefinition.eDir == OMX_DirOutput) {
1248            if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) {
1249                ret = OMX_ErrorNone;
1250                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
1251                    pExynosPort->tunnelFlags &= ~EXYNOS_TUNNEL_IS_SUPPLIER;
1252                    ret = OMX_ErrorNone;
1253                }
1254                goto EXIT;
1255            } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) {
1256                /*
1257                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
1258                    ret = OMX_ErrorNone;
1259                }
1260                */
1261                pExynosPort->tunnelFlags |= EXYNOS_TUNNEL_IS_SUPPLIER;
1262                ret = OMX_ErrorNone;
1263                goto EXIT;
1264            }
1265        }
1266    }
1267        break;
1268    default:
1269    {
1270        ret = OMX_ErrorUnsupportedIndex;
1271        goto EXIT;
1272    }
1273        break;
1274    }
1275
1276    ret = OMX_ErrorNone;
1277
1278EXIT:
1279
1280    FunctionOut();
1281
1282    return ret;
1283}
1284
1285OMX_ERRORTYPE Exynos_OMX_GetConfig(
1286    OMX_IN OMX_HANDLETYPE hComponent,
1287    OMX_IN OMX_INDEXTYPE  nIndex,
1288    OMX_INOUT OMX_PTR     pComponentConfigStructure)
1289{
1290    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1291    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1292    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1293
1294    FunctionIn();
1295
1296    if (hComponent == NULL) {
1297        ret = OMX_ErrorBadParameter;
1298        goto EXIT;
1299    }
1300    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1301    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1302    if (ret != OMX_ErrorNone) {
1303        goto EXIT;
1304    }
1305
1306    if (pOMXComponent->pComponentPrivate == NULL) {
1307        ret = OMX_ErrorBadParameter;
1308        goto EXIT;
1309    }
1310    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1311
1312    if (pComponentConfigStructure == NULL) {
1313        ret = OMX_ErrorBadParameter;
1314        goto EXIT;
1315    }
1316    if (pExynosComponent->currentState == OMX_StateInvalid) {
1317        ret = OMX_ErrorInvalidState;
1318        goto EXIT;
1319    }
1320
1321    switch (nIndex) {
1322    default:
1323        ret = OMX_ErrorUnsupportedIndex;
1324        break;
1325    }
1326
1327EXIT:
1328    FunctionOut();
1329
1330    return ret;
1331}
1332
1333OMX_ERRORTYPE Exynos_OMX_SetConfig(
1334    OMX_IN OMX_HANDLETYPE hComponent,
1335    OMX_IN OMX_INDEXTYPE  nIndex,
1336    OMX_IN OMX_PTR        pComponentConfigStructure)
1337{
1338    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1339    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1340    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1341
1342    FunctionIn();
1343
1344    if (hComponent == NULL) {
1345        ret = OMX_ErrorBadParameter;
1346        goto EXIT;
1347    }
1348    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1349    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1350    if (ret != OMX_ErrorNone) {
1351        goto EXIT;
1352    }
1353
1354    if (pOMXComponent->pComponentPrivate == NULL) {
1355        ret = OMX_ErrorBadParameter;
1356        goto EXIT;
1357    }
1358    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1359
1360    if (pComponentConfigStructure == NULL) {
1361        ret = OMX_ErrorBadParameter;
1362        goto EXIT;
1363    }
1364    if (pExynosComponent->currentState == OMX_StateInvalid) {
1365        ret = OMX_ErrorInvalidState;
1366        goto EXIT;
1367    }
1368
1369    switch (nIndex) {
1370    default:
1371        ret = OMX_ErrorUnsupportedIndex;
1372        break;
1373    }
1374
1375EXIT:
1376    FunctionOut();
1377
1378    return ret;
1379}
1380
1381OMX_ERRORTYPE Exynos_OMX_GetExtensionIndex(
1382    OMX_IN OMX_HANDLETYPE  hComponent,
1383    OMX_IN OMX_STRING      cParameterName,
1384    OMX_OUT OMX_INDEXTYPE *pIndexType)
1385{
1386    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1387    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1388    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1389
1390    FunctionIn();
1391
1392    if (hComponent == NULL) {
1393        ret = OMX_ErrorBadParameter;
1394        goto EXIT;
1395    }
1396    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1397    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1398    if (ret != OMX_ErrorNone) {
1399        goto EXIT;
1400    }
1401
1402    if (pOMXComponent->pComponentPrivate == NULL) {
1403        ret = OMX_ErrorBadParameter;
1404        goto EXIT;
1405    }
1406    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1407
1408    if ((cParameterName == NULL) || (pIndexType == NULL)) {
1409        ret = OMX_ErrorBadParameter;
1410        goto EXIT;
1411    }
1412    if (pExynosComponent->currentState == OMX_StateInvalid) {
1413        ret = OMX_ErrorInvalidState;
1414        goto EXIT;
1415    }
1416
1417    ret = OMX_ErrorBadParameter;
1418
1419EXIT:
1420    FunctionOut();
1421
1422    return ret;
1423}
1424
1425OMX_ERRORTYPE Exynos_OMX_SetCallbacks (
1426    OMX_IN OMX_HANDLETYPE    hComponent,
1427    OMX_IN OMX_CALLBACKTYPE* pCallbacks,
1428    OMX_IN OMX_PTR           pAppData)
1429{
1430    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1431    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1432    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1433
1434    FunctionIn();
1435
1436    if (hComponent == NULL) {
1437        ret = OMX_ErrorBadParameter;
1438        goto EXIT;
1439    }
1440    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1441    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1442    if (ret != OMX_ErrorNone) {
1443        goto EXIT;
1444    }
1445
1446    if (pOMXComponent->pComponentPrivate == NULL) {
1447        ret = OMX_ErrorBadParameter;
1448        goto EXIT;
1449    }
1450    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1451
1452    if (pCallbacks == NULL) {
1453        ret = OMX_ErrorBadParameter;
1454        goto EXIT;
1455    }
1456    if (pExynosComponent->currentState == OMX_StateInvalid) {
1457        ret = OMX_ErrorInvalidState;
1458        goto EXIT;
1459    }
1460    if (pExynosComponent->currentState != OMX_StateLoaded) {
1461        ret = OMX_ErrorIncorrectStateOperation;
1462        goto EXIT;
1463    }
1464
1465    pExynosComponent->pCallbacks = pCallbacks;
1466    pExynosComponent->callbackData = pAppData;
1467
1468    ret = OMX_ErrorNone;
1469
1470EXIT:
1471    FunctionOut();
1472
1473    return ret;
1474}
1475
1476OMX_ERRORTYPE Exynos_OMX_UseEGLImage(
1477    OMX_IN OMX_HANDLETYPE            hComponent,
1478    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
1479    OMX_IN OMX_U32                   nPortIndex,
1480    OMX_IN OMX_PTR                   pAppPrivate,
1481    OMX_IN void                     *eglImage)
1482{
1483    return OMX_ErrorNotImplemented;
1484}
1485
1486OMX_ERRORTYPE Exynos_OMX_BaseComponent_Constructor(
1487    OMX_IN OMX_HANDLETYPE hComponent)
1488{
1489    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1490    OMX_COMPONENTTYPE        *pOMXComponent;
1491    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1492
1493    FunctionIn();
1494
1495    if (hComponent == NULL) {
1496        ret = OMX_ErrorBadParameter;
1497        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
1498        goto EXIT;
1499    }
1500    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1501    pExynosComponent = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BASECOMPONENT));
1502    if (pExynosComponent == NULL) {
1503        ret = OMX_ErrorInsufficientResources;
1504        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1505        goto EXIT;
1506    }
1507    Exynos_OSAL_Memset(pExynosComponent, 0, sizeof(EXYNOS_OMX_BASECOMPONENT));
1508    pOMXComponent->pComponentPrivate = (OMX_PTR)pExynosComponent;
1509
1510    ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->msgSemaphoreHandle);
1511    if (ret != OMX_ErrorNone) {
1512        ret = OMX_ErrorInsufficientResources;
1513        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1514        goto EXIT;
1515    }
1516    ret = Exynos_OSAL_MutexCreate(&pExynosComponent->compMutex);
1517    if (ret != OMX_ErrorNone) {
1518        ret = OMX_ErrorInsufficientResources;
1519        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1520        goto EXIT;
1521    }
1522    ret = Exynos_OSAL_SignalCreate(&pExynosComponent->abendStateEvent);
1523    if (ret != OMX_ErrorNone) {
1524        ret = OMX_ErrorInsufficientResources;
1525        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1526        goto EXIT;
1527    }
1528
1529    pExynosComponent->bExitMessageHandlerThread = OMX_FALSE;
1530    Exynos_OSAL_QueueCreate(&pExynosComponent->messageQ, MAX_QUEUE_ELEMENTS);
1531    ret = Exynos_OSAL_ThreadCreate(&pExynosComponent->hMessageHandler, Exynos_OMX_MessageHandlerThread, pOMXComponent);
1532    if (ret != OMX_ErrorNone) {
1533        ret = OMX_ErrorInsufficientResources;
1534        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1535        goto EXIT;
1536    }
1537
1538    pExynosComponent->bMultiThreadProcess = OMX_FALSE;
1539
1540    pOMXComponent->GetComponentVersion = &Exynos_OMX_GetComponentVersion;
1541    pOMXComponent->SendCommand         = &Exynos_OMX_SendCommand;
1542    pOMXComponent->GetState            = &Exynos_OMX_GetState;
1543    pOMXComponent->SetCallbacks        = &Exynos_OMX_SetCallbacks;
1544    pOMXComponent->UseEGLImage         = &Exynos_OMX_UseEGLImage;
1545
1546EXIT:
1547    FunctionOut();
1548
1549    return ret;
1550}
1551
1552OMX_ERRORTYPE Exynos_OMX_BaseComponent_Destructor(
1553    OMX_IN OMX_HANDLETYPE hComponent)
1554{
1555    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1556    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1557    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1558    OMX_S32                   semaValue = 0;
1559
1560    FunctionIn();
1561
1562    if (hComponent == NULL) {
1563        ret = OMX_ErrorBadParameter;
1564        goto EXIT;
1565    }
1566    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1567    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1568    if (ret != OMX_ErrorNone) {
1569        goto EXIT;
1570    }
1571
1572    if (pOMXComponent->pComponentPrivate == NULL) {
1573        ret = OMX_ErrorBadParameter;
1574        goto EXIT;
1575    }
1576    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1577
1578    Exynos_OMX_CommandQueue(pExynosComponent, EXYNOS_OMX_CommandComponentDeInit, 0, NULL);
1579    Exynos_OSAL_SleepMillisec(0);
1580    Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->msgSemaphoreHandle, &semaValue);
1581    if (semaValue == 0)
1582        Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle);
1583    Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle);
1584
1585    Exynos_OSAL_ThreadTerminate(pExynosComponent->hMessageHandler);
1586    pExynosComponent->hMessageHandler = NULL;
1587
1588    Exynos_OSAL_SignalTerminate(pExynosComponent->abendStateEvent);
1589    pExynosComponent->abendStateEvent = NULL;
1590    Exynos_OSAL_MutexTerminate(pExynosComponent->compMutex);
1591    pExynosComponent->compMutex = NULL;
1592    Exynos_OSAL_SemaphoreTerminate(pExynosComponent->msgSemaphoreHandle);
1593    pExynosComponent->msgSemaphoreHandle = NULL;
1594    Exynos_OSAL_QueueTerminate(&pExynosComponent->messageQ);
1595
1596    Exynos_OSAL_Free(pExynosComponent);
1597    pExynosComponent = NULL;
1598
1599    ret = OMX_ErrorNone;
1600EXIT:
1601    FunctionOut();
1602
1603    return ret;
1604}
1605
1606
1607