Exynos_OMX_Basecomponent.c revision d866f455acab131be8f058733abd9c1ede2fcfea
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        pExynosComponent->transientState = EXYNOS_OMX_TransStateExecutingToIdle;
667        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateIdle");
668    } else if ((destState == OMX_StateExecuting) && (pExynosComponent->currentState == OMX_StateIdle)) {
669        pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToExecuting;
670        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateExecuting");
671    } else if (destState == OMX_StateInvalid) {
672        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
673            pExynosComponent->pExynosPort[i].portState = OMX_StateInvalid;
674        }
675    }
676
677    return OMX_ErrorNone;
678}
679
680static OMX_ERRORTYPE Exynos_SetPortFlush(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
681{
682    OMX_ERRORTYPE        ret = OMX_ErrorNone;
683    EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
684    OMX_S32              portIndex = nParam;
685    OMX_U16              i = 0, cnt = 0, index = 0;
686
687
688    if ((pExynosComponent->currentState == OMX_StateExecuting) ||
689        (pExynosComponent->currentState == OMX_StatePause)) {
690        if ((portIndex != ALL_PORT_INDEX) &&
691           ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
692            ret = OMX_ErrorBadPortIndex;
693            goto EXIT;
694        }
695
696        /*********************
697        *    need flush event set ?????
698        **********************/
699        cnt = (portIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1;
700        for (i = 0; i < cnt; i++) {
701            if (portIndex == ALL_PORT_INDEX)
702                index = i;
703            else
704                index = portIndex;
705            pExynosComponent->pExynosPort[index].bIsPortFlushed = OMX_TRUE;
706        }
707    } else {
708        ret = OMX_ErrorIncorrectStateOperation;
709        goto EXIT;
710    }
711    ret = OMX_ErrorNone;
712
713EXIT:
714    return ret;
715}
716
717static OMX_ERRORTYPE Exynos_SetPortEnable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
718{
719    OMX_ERRORTYPE        ret = OMX_ErrorNone;
720    EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
721    OMX_S32              portIndex = nParam;
722    OMX_U16              i = 0, cnt = 0;
723
724    FunctionIn();
725
726    if ((portIndex != ALL_PORT_INDEX) &&
727        ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
728        ret = OMX_ErrorBadPortIndex;
729        goto EXIT;
730    }
731
732    if (portIndex == ALL_PORT_INDEX) {
733        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
734            pExynosPort = &pExynosComponent->pExynosPort[i];
735            if (CHECK_PORT_ENABLED(pExynosPort)) {
736                ret = OMX_ErrorIncorrectStateOperation;
737                goto EXIT;
738            } else {
739                pExynosPort->portState = OMX_StateIdle;
740            }
741        }
742    } else {
743        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
744        if (CHECK_PORT_ENABLED(pExynosPort)) {
745            ret = OMX_ErrorIncorrectStateOperation;
746            goto EXIT;
747        } else {
748            pExynosPort->portState = OMX_StateIdle;
749        }
750    }
751    ret = OMX_ErrorNone;
752
753EXIT:
754    FunctionOut();
755
756    return ret;
757
758}
759
760static OMX_ERRORTYPE Exynos_SetPortDisable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
761{
762    OMX_ERRORTYPE        ret = OMX_ErrorNone;
763    EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
764    OMX_S32              portIndex = nParam;
765    OMX_U16              i = 0, cnt = 0;
766
767    FunctionIn();
768
769    if ((portIndex != ALL_PORT_INDEX) &&
770        ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
771        ret = OMX_ErrorBadPortIndex;
772        goto EXIT;
773    }
774
775    if (portIndex == ALL_PORT_INDEX) {
776        for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
777            pExynosPort = &pExynosComponent->pExynosPort[i];
778            if (!CHECK_PORT_ENABLED(pExynosPort)) {
779                ret = OMX_ErrorIncorrectStateOperation;
780                goto EXIT;
781            }
782            pExynosPort->portState = OMX_StateLoaded;
783            pExynosPort->bIsPortDisabled = OMX_TRUE;
784        }
785    } else {
786        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
787        pExynosPort->portState = OMX_StateLoaded;
788        pExynosPort->bIsPortDisabled = OMX_TRUE;
789    }
790    ret = OMX_ErrorNone;
791
792EXIT:
793    FunctionOut();
794
795    return ret;
796}
797
798static OMX_ERRORTYPE Exynos_SetMarkBuffer(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
799{
800    OMX_ERRORTYPE        ret = OMX_ErrorNone;
801    EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
802    OMX_U32              portIndex = nParam;
803    OMX_U16              i = 0, cnt = 0;
804
805
806    if (nParam >= pExynosComponent->portParam.nPorts) {
807        ret = OMX_ErrorBadPortIndex;
808        goto EXIT;
809    }
810
811    if ((pExynosComponent->currentState == OMX_StateExecuting) ||
812        (pExynosComponent->currentState == OMX_StatePause)) {
813        ret = OMX_ErrorNone;
814    } else {
815        ret = OMX_ErrorIncorrectStateOperation;
816    }
817
818EXIT:
819    return ret;
820}
821
822static OMX_ERRORTYPE Exynos_OMX_CommandQueue(
823    EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
824    OMX_COMMANDTYPE        Cmd,
825    OMX_U32                nParam,
826    OMX_PTR                pCmdData)
827{
828    OMX_ERRORTYPE    ret = OMX_ErrorNone;
829    EXYNOS_OMX_MESSAGE *command = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE));
830
831    if (command == NULL) {
832        ret = OMX_ErrorInsufficientResources;
833        goto EXIT;
834    }
835    command->messageType  = (OMX_U32)Cmd;
836    command->messageParam = nParam;
837    command->pCmdData     = pCmdData;
838
839    ret = Exynos_OSAL_Queue(&pExynosComponent->messageQ, (void *)command);
840    if (ret != 0) {
841        ret = OMX_ErrorUndefined;
842        goto EXIT;
843    }
844    ret = Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle);
845
846EXIT:
847    return ret;
848}
849
850OMX_ERRORTYPE Exynos_OMX_SendCommand(
851    OMX_IN OMX_HANDLETYPE  hComponent,
852    OMX_IN OMX_COMMANDTYPE Cmd,
853    OMX_IN OMX_U32         nParam,
854    OMX_IN OMX_PTR         pCmdData)
855{
856    OMX_ERRORTYPE             ret = OMX_ErrorNone;
857    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
858    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
859    EXYNOS_OMX_MESSAGE       *message = NULL;
860
861    FunctionIn();
862
863    if (hComponent == NULL) {
864        ret = OMX_ErrorBadParameter;
865        goto EXIT;
866    }
867    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
868    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
869    if (ret != OMX_ErrorNone) {
870        goto EXIT;
871    }
872
873    if (pOMXComponent->pComponentPrivate == NULL) {
874        ret = OMX_ErrorBadParameter;
875        goto EXIT;
876    }
877    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
878
879    if (pExynosComponent->currentState == OMX_StateInvalid) {
880        ret = OMX_ErrorInvalidState;
881        goto EXIT;
882    }
883
884    switch (Cmd) {
885    case OMX_CommandStateSet :
886        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandStateSet");
887        Exynos_StateSet(pExynosComponent, nParam);
888        break;
889    case OMX_CommandFlush :
890        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandFlush");
891        ret = Exynos_SetPortFlush(pExynosComponent, nParam);
892        if (ret != OMX_ErrorNone)
893            goto EXIT;
894        break;
895    case OMX_CommandPortDisable :
896        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandPortDisable");
897        ret = Exynos_SetPortDisable(pExynosComponent, nParam);
898        if (ret != OMX_ErrorNone)
899            goto EXIT;
900        break;
901    case OMX_CommandPortEnable :
902        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandPortEnable");
903        ret = Exynos_SetPortEnable(pExynosComponent, nParam);
904        if (ret != OMX_ErrorNone)
905            goto EXIT;
906        break;
907    case OMX_CommandMarkBuffer :
908        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandMarkBuffer");
909        ret = Exynos_SetMarkBuffer(pExynosComponent, nParam);
910        if (ret != OMX_ErrorNone)
911            goto EXIT;
912        break;
913    default:
914        break;
915    }
916
917    ret = Exynos_OMX_CommandQueue(pExynosComponent, Cmd, nParam, pCmdData);
918
919EXIT:
920    FunctionOut();
921
922    return ret;
923}
924
925OMX_ERRORTYPE Exynos_OMX_GetParameter(
926    OMX_IN OMX_HANDLETYPE hComponent,
927    OMX_IN OMX_INDEXTYPE  nParamIndex,
928    OMX_INOUT OMX_PTR     ComponentParameterStructure)
929{
930    OMX_ERRORTYPE             ret = OMX_ErrorNone;
931    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
932    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
933
934    FunctionIn();
935
936    if (hComponent == NULL) {
937        ret = OMX_ErrorBadParameter;
938        goto EXIT;
939    }
940    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
941    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
942    if (ret != OMX_ErrorNone) {
943        goto EXIT;
944    }
945
946    if (pOMXComponent->pComponentPrivate == NULL) {
947        ret = OMX_ErrorBadParameter;
948        goto EXIT;
949    }
950    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
951
952    if (ComponentParameterStructure == NULL) {
953        ret = OMX_ErrorBadParameter;
954        goto EXIT;
955    }
956    if (pExynosComponent->currentState == OMX_StateInvalid) {
957        ret = OMX_ErrorInvalidState;
958        goto EXIT;
959    }
960
961    switch (nParamIndex) {
962    case OMX_IndexParamAudioInit:
963    case OMX_IndexParamVideoInit:
964    case OMX_IndexParamImageInit:
965    case OMX_IndexParamOtherInit:
966    {
967        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
968        ret = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE));
969        if (ret != OMX_ErrorNone) {
970            goto EXIT;
971        }
972        portParam->nPorts         = 0;
973        portParam->nStartPortNumber     = 0;
974    }
975        break;
976    case OMX_IndexParamPortDefinition:
977    {
978        OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
979        OMX_U32                       portIndex = portDefinition->nPortIndex;
980        EXYNOS_OMX_BASEPORT          *pExynosPort;
981
982        if (portIndex >= pExynosComponent->portParam.nPorts) {
983            ret = OMX_ErrorBadPortIndex;
984            goto EXIT;
985        }
986        ret = Exynos_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
987        if (ret != OMX_ErrorNone) {
988            goto EXIT;
989        }
990
991        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
992        Exynos_OSAL_Memcpy(portDefinition, &pExynosPort->portDefinition, portDefinition->nSize);
993    }
994        break;
995    case OMX_IndexParamPriorityMgmt:
996    {
997        OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure;
998
999        ret = Exynos_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE));
1000        if (ret != OMX_ErrorNone) {
1001            goto EXIT;
1002        }
1003
1004        compPriority->nGroupID       = pExynosComponent->compPriority.nGroupID;
1005        compPriority->nGroupPriority = pExynosComponent->compPriority.nGroupPriority;
1006    }
1007        break;
1008
1009    case OMX_IndexParamCompBufferSupplier:
1010    {
1011        OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure;
1012        OMX_U32                       portIndex = bufferSupplier->nPortIndex;
1013        EXYNOS_OMX_BASEPORT          *pExynosPort;
1014
1015        if ((pExynosComponent->currentState == OMX_StateLoaded) ||
1016            (pExynosComponent->currentState == OMX_StateWaitForResources)) {
1017            if (portIndex >= pExynosComponent->portParam.nPorts) {
1018                ret = OMX_ErrorBadPortIndex;
1019                goto EXIT;
1020            }
1021            ret = Exynos_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
1022            if (ret != OMX_ErrorNone) {
1023                goto EXIT;
1024            }
1025
1026            pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1027
1028
1029            if (pExynosPort->portDefinition.eDir == OMX_DirInput) {
1030                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
1031                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput;
1032                } else if (CHECK_PORT_TUNNELED(pExynosPort)) {
1033                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput;
1034                } else {
1035                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified;
1036                }
1037            } else {
1038                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
1039                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput;
1040                } else if (CHECK_PORT_TUNNELED(pExynosPort)) {
1041                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput;
1042                } else {
1043                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified;
1044                }
1045            }
1046        }
1047        else
1048        {
1049            ret = OMX_ErrorIncorrectStateOperation;
1050            goto EXIT;
1051        }
1052    }
1053        break;
1054    default:
1055    {
1056        ret = OMX_ErrorUnsupportedIndex;
1057        goto EXIT;
1058    }
1059        break;
1060    }
1061
1062    ret = OMX_ErrorNone;
1063
1064EXIT:
1065
1066    FunctionOut();
1067
1068    return ret;
1069}
1070
1071OMX_ERRORTYPE Exynos_OMX_SetParameter(
1072    OMX_IN OMX_HANDLETYPE hComponent,
1073    OMX_IN OMX_INDEXTYPE  nIndex,
1074    OMX_IN OMX_PTR        ComponentParameterStructure)
1075{
1076    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1077    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1078    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1079
1080    FunctionIn();
1081
1082    if (hComponent == NULL) {
1083        ret = OMX_ErrorBadParameter;
1084        goto EXIT;
1085    }
1086    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1087    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1088    if (ret != OMX_ErrorNone) {
1089        goto EXIT;
1090    }
1091
1092    if (pOMXComponent->pComponentPrivate == NULL) {
1093        ret = OMX_ErrorBadParameter;
1094        goto EXIT;
1095    }
1096    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1097
1098    if (ComponentParameterStructure == NULL) {
1099        ret = OMX_ErrorBadParameter;
1100        goto EXIT;
1101    }
1102    if (pExynosComponent->currentState == OMX_StateInvalid) {
1103        ret = OMX_ErrorInvalidState;
1104        goto EXIT;
1105    }
1106
1107    switch (nIndex) {
1108    case OMX_IndexParamAudioInit:
1109    case OMX_IndexParamVideoInit:
1110    case OMX_IndexParamImageInit:
1111    case OMX_IndexParamOtherInit:
1112    {
1113        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
1114        ret = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE));
1115        if (ret != OMX_ErrorNone) {
1116            goto EXIT;
1117        }
1118
1119        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
1120            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1121            ret = OMX_ErrorIncorrectStateOperation;
1122            goto EXIT;
1123        }
1124        ret = OMX_ErrorUndefined;
1125        /* Exynos_OSAL_Memcpy(&pExynosComponent->portParam, portParam, sizeof(OMX_PORT_PARAM_TYPE)); */
1126    }
1127        break;
1128    case OMX_IndexParamPortDefinition:
1129    {
1130        OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
1131        OMX_U32                       portIndex = portDefinition->nPortIndex;
1132        EXYNOS_OMX_BASEPORT          *pExynosPort;
1133
1134        if (portIndex >= pExynosComponent->portParam.nPorts) {
1135            ret = OMX_ErrorBadPortIndex;
1136            goto EXIT;
1137        }
1138        ret = Exynos_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1139        if (ret != OMX_ErrorNone) {
1140            goto EXIT;
1141        }
1142
1143        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1144
1145        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1146            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
1147                ret = OMX_ErrorIncorrectStateOperation;
1148                goto EXIT;
1149            }
1150        }
1151        if (portDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
1152            ret = OMX_ErrorBadParameter;
1153            goto EXIT;
1154        }
1155
1156        Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, portDefinition, portDefinition->nSize);
1157    }
1158        break;
1159    case OMX_IndexParamPriorityMgmt:
1160    {
1161        OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure;
1162
1163        if ((pExynosComponent->currentState != OMX_StateLoaded) &&
1164            (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1165            ret = OMX_ErrorIncorrectStateOperation;
1166            goto EXIT;
1167        }
1168
1169        ret = Exynos_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE));
1170        if (ret != OMX_ErrorNone) {
1171            goto EXIT;
1172        }
1173
1174        pExynosComponent->compPriority.nGroupID = compPriority->nGroupID;
1175        pExynosComponent->compPriority.nGroupPriority = compPriority->nGroupPriority;
1176    }
1177        break;
1178    case OMX_IndexParamCompBufferSupplier:
1179    {
1180        OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure;
1181        OMX_U32           portIndex = bufferSupplier->nPortIndex;
1182        EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1183
1184
1185        if (portIndex >= pExynosComponent->portParam.nPorts) {
1186            ret = OMX_ErrorBadPortIndex;
1187            goto EXIT;
1188        }
1189        ret = Exynos_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
1190        if (ret != OMX_ErrorNone) {
1191            goto EXIT;
1192        }
1193
1194        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1195        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1196            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
1197                ret = OMX_ErrorIncorrectStateOperation;
1198                goto EXIT;
1199            }
1200        }
1201
1202        if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyUnspecified) {
1203            ret = OMX_ErrorNone;
1204            goto EXIT;
1205        }
1206        if (CHECK_PORT_TUNNELED(pExynosPort) == 0) {
1207            ret = OMX_ErrorNone; /*OMX_ErrorNone ?????*/
1208            goto EXIT;
1209        }
1210
1211        if (pExynosPort->portDefinition.eDir == OMX_DirInput) {
1212            if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) {
1213                /*
1214                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
1215                    ret = OMX_ErrorNone;
1216                }
1217                */
1218                pExynosPort->tunnelFlags |= EXYNOS_TUNNEL_IS_SUPPLIER;
1219                bufferSupplier->nPortIndex = pExynosPort->tunneledPort;
1220                ret = OMX_SetParameter(pExynosPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier);
1221                goto EXIT;
1222            } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) {
1223                ret = OMX_ErrorNone;
1224                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
1225                    pExynosPort->tunnelFlags &= ~EXYNOS_TUNNEL_IS_SUPPLIER;
1226                    bufferSupplier->nPortIndex = pExynosPort->tunneledPort;
1227                    ret = OMX_SetParameter(pExynosPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier);
1228                }
1229                goto EXIT;
1230            }
1231        } else if (pExynosPort->portDefinition.eDir == OMX_DirOutput) {
1232            if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) {
1233                ret = OMX_ErrorNone;
1234                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
1235                    pExynosPort->tunnelFlags &= ~EXYNOS_TUNNEL_IS_SUPPLIER;
1236                    ret = OMX_ErrorNone;
1237                }
1238                goto EXIT;
1239            } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) {
1240                /*
1241                if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
1242                    ret = OMX_ErrorNone;
1243                }
1244                */
1245                pExynosPort->tunnelFlags |= EXYNOS_TUNNEL_IS_SUPPLIER;
1246                ret = OMX_ErrorNone;
1247                goto EXIT;
1248            }
1249        }
1250    }
1251        break;
1252    default:
1253    {
1254        ret = OMX_ErrorUnsupportedIndex;
1255        goto EXIT;
1256    }
1257        break;
1258    }
1259
1260    ret = OMX_ErrorNone;
1261
1262EXIT:
1263
1264    FunctionOut();
1265
1266    return ret;
1267}
1268
1269OMX_ERRORTYPE Exynos_OMX_GetConfig(
1270    OMX_IN OMX_HANDLETYPE hComponent,
1271    OMX_IN OMX_INDEXTYPE  nIndex,
1272    OMX_INOUT OMX_PTR     pComponentConfigStructure)
1273{
1274    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1275    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1276    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1277
1278    FunctionIn();
1279
1280    if (hComponent == NULL) {
1281        ret = OMX_ErrorBadParameter;
1282        goto EXIT;
1283    }
1284    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1285    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1286    if (ret != OMX_ErrorNone) {
1287        goto EXIT;
1288    }
1289
1290    if (pOMXComponent->pComponentPrivate == NULL) {
1291        ret = OMX_ErrorBadParameter;
1292        goto EXIT;
1293    }
1294    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1295
1296    if (pComponentConfigStructure == NULL) {
1297        ret = OMX_ErrorBadParameter;
1298        goto EXIT;
1299    }
1300    if (pExynosComponent->currentState == OMX_StateInvalid) {
1301        ret = OMX_ErrorInvalidState;
1302        goto EXIT;
1303    }
1304
1305    switch (nIndex) {
1306    default:
1307        ret = OMX_ErrorUnsupportedIndex;
1308        break;
1309    }
1310
1311EXIT:
1312    FunctionOut();
1313
1314    return ret;
1315}
1316
1317OMX_ERRORTYPE Exynos_OMX_SetConfig(
1318    OMX_IN OMX_HANDLETYPE hComponent,
1319    OMX_IN OMX_INDEXTYPE  nIndex,
1320    OMX_IN OMX_PTR        pComponentConfigStructure)
1321{
1322    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1323    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1324    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1325
1326    FunctionIn();
1327
1328    if (hComponent == NULL) {
1329        ret = OMX_ErrorBadParameter;
1330        goto EXIT;
1331    }
1332    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1333    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1334    if (ret != OMX_ErrorNone) {
1335        goto EXIT;
1336    }
1337
1338    if (pOMXComponent->pComponentPrivate == NULL) {
1339        ret = OMX_ErrorBadParameter;
1340        goto EXIT;
1341    }
1342    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1343
1344    if (pComponentConfigStructure == NULL) {
1345        ret = OMX_ErrorBadParameter;
1346        goto EXIT;
1347    }
1348    if (pExynosComponent->currentState == OMX_StateInvalid) {
1349        ret = OMX_ErrorInvalidState;
1350        goto EXIT;
1351    }
1352
1353    switch (nIndex) {
1354    default:
1355        ret = OMX_ErrorUnsupportedIndex;
1356        break;
1357    }
1358
1359EXIT:
1360    FunctionOut();
1361
1362    return ret;
1363}
1364
1365OMX_ERRORTYPE Exynos_OMX_GetExtensionIndex(
1366    OMX_IN OMX_HANDLETYPE  hComponent,
1367    OMX_IN OMX_STRING      cParameterName,
1368    OMX_OUT OMX_INDEXTYPE *pIndexType)
1369{
1370    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1371    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1372    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1373
1374    FunctionIn();
1375
1376    if (hComponent == NULL) {
1377        ret = OMX_ErrorBadParameter;
1378        goto EXIT;
1379    }
1380    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1381    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1382    if (ret != OMX_ErrorNone) {
1383        goto EXIT;
1384    }
1385
1386    if (pOMXComponent->pComponentPrivate == NULL) {
1387        ret = OMX_ErrorBadParameter;
1388        goto EXIT;
1389    }
1390    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1391
1392    if ((cParameterName == NULL) || (pIndexType == NULL)) {
1393        ret = OMX_ErrorBadParameter;
1394        goto EXIT;
1395    }
1396    if (pExynosComponent->currentState == OMX_StateInvalid) {
1397        ret = OMX_ErrorInvalidState;
1398        goto EXIT;
1399    }
1400
1401    ret = OMX_ErrorBadParameter;
1402
1403EXIT:
1404    FunctionOut();
1405
1406    return ret;
1407}
1408
1409OMX_ERRORTYPE Exynos_OMX_SetCallbacks (
1410    OMX_IN OMX_HANDLETYPE    hComponent,
1411    OMX_IN OMX_CALLBACKTYPE* pCallbacks,
1412    OMX_IN OMX_PTR           pAppData)
1413{
1414    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1415    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1416    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1417
1418    FunctionIn();
1419
1420    if (hComponent == NULL) {
1421        ret = OMX_ErrorBadParameter;
1422        goto EXIT;
1423    }
1424    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1425    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1426    if (ret != OMX_ErrorNone) {
1427        goto EXIT;
1428    }
1429
1430    if (pOMXComponent->pComponentPrivate == NULL) {
1431        ret = OMX_ErrorBadParameter;
1432        goto EXIT;
1433    }
1434    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1435
1436    if (pCallbacks == NULL) {
1437        ret = OMX_ErrorBadParameter;
1438        goto EXIT;
1439    }
1440    if (pExynosComponent->currentState == OMX_StateInvalid) {
1441        ret = OMX_ErrorInvalidState;
1442        goto EXIT;
1443    }
1444    if (pExynosComponent->currentState != OMX_StateLoaded) {
1445        ret = OMX_ErrorIncorrectStateOperation;
1446        goto EXIT;
1447    }
1448
1449    pExynosComponent->pCallbacks = pCallbacks;
1450    pExynosComponent->callbackData = pAppData;
1451
1452    ret = OMX_ErrorNone;
1453
1454EXIT:
1455    FunctionOut();
1456
1457    return ret;
1458}
1459
1460OMX_ERRORTYPE Exynos_OMX_UseEGLImage(
1461    OMX_IN OMX_HANDLETYPE            hComponent,
1462    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
1463    OMX_IN OMX_U32                   nPortIndex,
1464    OMX_IN OMX_PTR                   pAppPrivate,
1465    OMX_IN void                     *eglImage)
1466{
1467    return OMX_ErrorNotImplemented;
1468}
1469
1470OMX_ERRORTYPE Exynos_OMX_BaseComponent_Constructor(
1471    OMX_IN OMX_HANDLETYPE hComponent)
1472{
1473    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1474    OMX_COMPONENTTYPE        *pOMXComponent;
1475    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1476
1477    FunctionIn();
1478
1479    if (hComponent == NULL) {
1480        ret = OMX_ErrorBadParameter;
1481        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
1482        goto EXIT;
1483    }
1484    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1485    pExynosComponent = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BASECOMPONENT));
1486    if (pExynosComponent == NULL) {
1487        ret = OMX_ErrorInsufficientResources;
1488        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1489        goto EXIT;
1490    }
1491    Exynos_OSAL_Memset(pExynosComponent, 0, sizeof(EXYNOS_OMX_BASECOMPONENT));
1492    pOMXComponent->pComponentPrivate = (OMX_PTR)pExynosComponent;
1493
1494    ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->msgSemaphoreHandle);
1495    if (ret != OMX_ErrorNone) {
1496        ret = OMX_ErrorInsufficientResources;
1497        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1498        goto EXIT;
1499    }
1500    ret = Exynos_OSAL_MutexCreate(&pExynosComponent->compMutex);
1501    if (ret != OMX_ErrorNone) {
1502        ret = OMX_ErrorInsufficientResources;
1503        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1504        goto EXIT;
1505    }
1506    ret = Exynos_OSAL_SignalCreate(&pExynosComponent->abendStateEvent);
1507    if (ret != OMX_ErrorNone) {
1508        ret = OMX_ErrorInsufficientResources;
1509        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1510        goto EXIT;
1511    }
1512
1513    pExynosComponent->bExitMessageHandlerThread = OMX_FALSE;
1514    Exynos_OSAL_QueueCreate(&pExynosComponent->messageQ, MAX_QUEUE_ELEMENTS);
1515    ret = Exynos_OSAL_ThreadCreate(&pExynosComponent->hMessageHandler, Exynos_OMX_MessageHandlerThread, pOMXComponent);
1516    if (ret != OMX_ErrorNone) {
1517        ret = OMX_ErrorInsufficientResources;
1518        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1519        goto EXIT;
1520    }
1521
1522    pExynosComponent->bMultiThreadProcess = OMX_FALSE;
1523
1524    pOMXComponent->GetComponentVersion = &Exynos_OMX_GetComponentVersion;
1525    pOMXComponent->SendCommand         = &Exynos_OMX_SendCommand;
1526    pOMXComponent->GetState            = &Exynos_OMX_GetState;
1527    pOMXComponent->SetCallbacks        = &Exynos_OMX_SetCallbacks;
1528    pOMXComponent->UseEGLImage         = &Exynos_OMX_UseEGLImage;
1529
1530EXIT:
1531    FunctionOut();
1532
1533    return ret;
1534}
1535
1536OMX_ERRORTYPE Exynos_OMX_BaseComponent_Destructor(
1537    OMX_IN OMX_HANDLETYPE hComponent)
1538{
1539    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1540    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1541    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1542    OMX_S32                   semaValue = 0;
1543
1544    FunctionIn();
1545
1546    if (hComponent == NULL) {
1547        ret = OMX_ErrorBadParameter;
1548        goto EXIT;
1549    }
1550    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1551    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1552    if (ret != OMX_ErrorNone) {
1553        goto EXIT;
1554    }
1555
1556    if (pOMXComponent->pComponentPrivate == NULL) {
1557        ret = OMX_ErrorBadParameter;
1558        goto EXIT;
1559    }
1560    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1561
1562    Exynos_OMX_CommandQueue(pExynosComponent, EXYNOS_OMX_CommandComponentDeInit, 0, NULL);
1563    Exynos_OSAL_SleepMillisec(0);
1564    Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->msgSemaphoreHandle, &semaValue);
1565    if (semaValue == 0)
1566        Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle);
1567    Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle);
1568
1569    Exynos_OSAL_ThreadTerminate(pExynosComponent->hMessageHandler);
1570    pExynosComponent->hMessageHandler = NULL;
1571
1572    Exynos_OSAL_SignalTerminate(pExynosComponent->abendStateEvent);
1573    pExynosComponent->abendStateEvent = NULL;
1574    Exynos_OSAL_MutexTerminate(pExynosComponent->compMutex);
1575    pExynosComponent->compMutex = NULL;
1576    Exynos_OSAL_SemaphoreTerminate(pExynosComponent->msgSemaphoreHandle);
1577    pExynosComponent->msgSemaphoreHandle = NULL;
1578    Exynos_OSAL_QueueTerminate(&pExynosComponent->messageQ);
1579
1580    Exynos_OSAL_Free(pExynosComponent);
1581    pExynosComponent = NULL;
1582
1583    ret = OMX_ErrorNone;
1584EXIT:
1585    FunctionOut();
1586
1587    return ret;
1588}
1589
1590
1591