Force to use Exynos3250 kernel header, not sc7730
[platform/adaptation/ap_samsung/libomxil-e3250-v4l2.git] / openmax / component / common / Exynos_OMX_Basecomponent.c
1 /*
2  *
3  * Copyright 2012 Samsung Electronics S.LSI Co. LTD
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 /*
19  * @file       Exynos_OMX_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 */
51 OMX_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;
71 EXIT:
72     return ret;
73 }
74
75 OMX_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
126 EXIT:
127     FunctionOut();
128
129     return ret;
130 }
131
132 OMX_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
161 EXIT:
162     FunctionOut();
163
164     return ret;
165 }
166
167 OMX_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             goto EXIT;
195         }
196     }
197     if (((currentState == OMX_StateIdle) && (destState == OMX_StateLoaded))       ||
198         ((currentState == OMX_StateIdle) && (destState == OMX_StateInvalid))      ||
199         ((currentState == OMX_StateExecuting) && (destState == OMX_StateInvalid)) ||
200         ((currentState == OMX_StatePause) && (destState == OMX_StateInvalid))) {
201         Exynos_OMX_Release_Resource(pOMXComponent);
202     }
203
204 #ifndef SLP_PLATFORM
205     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "destState: %d", destState);
206 #else
207     Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "destState: %d", destState);
208 #endif
209     switch (destState) {
210     case OMX_StateInvalid:
211         switch (currentState) {
212         case OMX_StateWaitForResources:
213             Exynos_OMX_Out_WaitForResource(pOMXComponent);
214         case OMX_StateIdle:
215         case OMX_StateExecuting:
216         case OMX_StatePause:
217         case OMX_StateLoaded:
218             pExynosComponent->currentState = OMX_StateInvalid;
219             ret = pExynosComponent->exynos_BufferProcessTerminate(pOMXComponent);
220
221             for (i = 0; i < ALL_PORT_NUM; i++) {
222                 if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
223                     Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
224                     pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL;
225                 } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
226                     Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
227                     pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL;
228                     Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
229                     pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL;
230                 }
231                 Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
232                 pExynosComponent->pExynosPort[i].hPortMutex = NULL;
233             }
234
235             if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
236                 Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent);
237                 pExynosComponent->pauseEvent = NULL;
238             } else {
239                 for (i = 0; i < ALL_PORT_NUM; i++) {
240                     Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
241                     pExynosComponent->pExynosPort[i].pauseEvent = NULL;
242                     if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE) {
243                         Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent);
244                         pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL;
245                     }
246                 }
247             }
248             for (i = 0; i < ALL_PORT_NUM; i++) {
249                 Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID);
250                 pExynosComponent->pExynosPort[i].bufferSemID = NULL;
251             }
252             if (pExynosComponent->exynos_codec_componentTerminate != NULL)
253                 pExynosComponent->exynos_codec_componentTerminate(pOMXComponent);
254
255             ret = OMX_ErrorInvalidState;
256             break;
257         default:
258             ret = OMX_ErrorInvalidState;
259             break;
260         }
261         break;
262     case OMX_StateLoaded:
263         switch (currentState) {
264         case OMX_StateIdle:
265             ret = pExynosComponent->exynos_BufferProcessTerminate(pOMXComponent);
266
267             for (i = 0; i < ALL_PORT_NUM; i++) {
268                 if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
269                     Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
270                     pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL;
271                 } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
272                     Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
273                     pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL;
274                     Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
275                     pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL;
276                 }
277                 Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
278                 pExynosComponent->pExynosPort[i].hPortMutex = NULL;
279             }
280             if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
281                 Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent);
282                 pExynosComponent->pauseEvent = NULL;
283             } else {
284                 for (i = 0; i < ALL_PORT_NUM; i++) {
285                     Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
286                     pExynosComponent->pExynosPort[i].pauseEvent = NULL;
287                     if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE) {
288                         Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent);
289                         pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL;
290                     }
291                 }
292             }
293             for (i = 0; i < ALL_PORT_NUM; i++) {
294                 Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID);
295                 pExynosComponent->pExynosPort[i].bufferSemID = NULL;
296             }
297
298             pExynosComponent->exynos_codec_componentTerminate(pOMXComponent);
299
300             for (i = 0; i < (pExynosComponent->portParam.nPorts); i++) {
301                 pExynosPort = (pExynosComponent->pExynosPort + i);
302                 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
303                     while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
304                         message = (EXYNOS_OMX_MESSAGE*)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
305                         if (message != NULL)
306                             Exynos_OSAL_Free(message);
307                     }
308                     ret = pExynosComponent->exynos_FreeTunnelBuffer(pExynosPort, i);
309                     if (OMX_ErrorNone != ret) {
310                         goto EXIT;
311                     }
312                 } else {
313                     if (CHECK_PORT_ENABLED(pExynosPort)) {
314                         Exynos_OSAL_SemaphoreWait(pExynosPort->unloadedResource);
315                         while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
316                             message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
317                             if (message != NULL)
318                                 Exynos_OSAL_Free(message);
319                         }
320                         pExynosPort->portDefinition.bPopulated = OMX_FALSE;
321                     }
322                 }
323             }
324             pExynosComponent->currentState = OMX_StateLoaded;
325             break;
326         case OMX_StateWaitForResources:
327             ret = Exynos_OMX_Out_WaitForResource(pOMXComponent);
328             pExynosComponent->currentState = OMX_StateLoaded;
329             break;
330         case OMX_StateExecuting:
331         case OMX_StatePause:
332         default:
333             ret = OMX_ErrorIncorrectStateTransition;
334             break;
335         }
336         break;
337     case OMX_StateIdle:
338         switch (currentState) {
339         case OMX_StateLoaded:
340             for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
341                 pExynosPort = (pExynosComponent->pExynosPort + i);
342                 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
343                     if (CHECK_PORT_ENABLED(pExynosPort)) {
344                         ret = pExynosComponent->exynos_AllocateTunnelBuffer(pExynosPort, i);
345                         if (ret!=OMX_ErrorNone)
346                             goto EXIT;
347                     }
348                 } else {
349                     if (CHECK_PORT_ENABLED(pExynosPort)) {
350                         Exynos_OSAL_SemaphoreWait(pExynosComponent->pExynosPort[i].loadedResource);
351                         pExynosPort->portDefinition.bPopulated = OMX_TRUE;
352                     }
353                 }
354             }
355             ret = pExynosComponent->exynos_codec_componentInit(pOMXComponent);
356             if (ret != OMX_ErrorNone) {
357                 /*
358                  * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free
359                  */
360                 goto EXIT;
361             }
362             if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
363                 Exynos_OSAL_SignalCreate(&pExynosComponent->pauseEvent);
364             } else {
365                 for (i = 0; i < ALL_PORT_NUM; i++) {
366                     Exynos_OSAL_SignalCreate(&pExynosComponent->pExynosPort[i].pauseEvent);
367                     if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE)
368                         Exynos_OSAL_SignalCreate(&pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent);
369                 }
370             }
371             for (i = 0; i < ALL_PORT_NUM; i++) {
372                 ret = Exynos_OSAL_SemaphoreCreate(&pExynosComponent->pExynosPort[i].bufferSemID);
373                 if (ret != OMX_ErrorNone) {
374                     ret = OMX_ErrorInsufficientResources;
375                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
376                     goto EXIT;
377                 }
378             }
379             for (i = 0; i < ALL_PORT_NUM; i++) {
380                 if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
381                     ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
382                     if (ret != OMX_ErrorNone) {
383                         ret = OMX_ErrorInsufficientResources;
384                         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
385                         goto EXIT;
386                     }
387                 } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
388                     ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
389                     if (ret != OMX_ErrorNone) {
390                         ret = OMX_ErrorInsufficientResources;
391                         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
392                         goto EXIT;
393                     }
394                     ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
395                     if (ret != OMX_ErrorNone) {
396                         ret = OMX_ErrorInsufficientResources;
397                         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
398                         goto EXIT;
399                     }
400                 }
401                 ret = Exynos_OSAL_MutexCreate(&pExynosComponent->pExynosPort[i].hPortMutex);
402                 if (ret != OMX_ErrorNone) {
403                     ret = OMX_ErrorInsufficientResources;
404                     goto EXIT;
405                 }
406             }
407
408             ret = pExynosComponent->exynos_BufferProcessCreate(pOMXComponent);
409             if (ret != OMX_ErrorNone) {
410                 /*
411                  * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free
412                  */
413                 if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
414                     Exynos_OSAL_SignalTerminate(pExynosComponent->pauseEvent);
415                     pExynosComponent->pauseEvent = NULL;
416                 } else {
417                     for (i = 0; i < ALL_PORT_NUM; i++) {
418                         Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].pauseEvent);
419                         pExynosComponent->pExynosPort[i].pauseEvent = NULL;
420                         if (pExynosComponent->pExynosPort[i].bufferProcessType & BUFFER_SHARE) {
421                             Exynos_OSAL_SignalTerminate(pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent);
422                             pExynosComponent->pExynosPort[i].hAllCodecBufferReturnEvent = NULL;
423                         }
424                     }
425                 }
426                 for (i = 0; i < ALL_PORT_NUM; i++) {
427                     if (pExynosComponent->pExynosPort[i].portWayType == WAY1_PORT) {
428                         Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex);
429                         pExynosComponent->pExynosPort[i].way.port1WayDataBuffer.dataBuffer.bufferMutex = NULL;
430                     } else if (pExynosComponent->pExynosPort[i].portWayType == WAY2_PORT) {
431                         Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex);
432                         pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.inputDataBuffer.bufferMutex = NULL;
433                         Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex);
434                         pExynosComponent->pExynosPort[i].way.port2WayDataBuffer.outputDataBuffer.bufferMutex = NULL;
435                     }
436                     Exynos_OSAL_MutexTerminate(pExynosComponent->pExynosPort[i].hPortMutex);
437                     pExynosComponent->pExynosPort[i].hPortMutex = NULL;
438                 }
439                 for (i = 0; i < ALL_PORT_NUM; i++) {
440                     Exynos_OSAL_SemaphoreTerminate(pExynosComponent->pExynosPort[i].bufferSemID);
441                     pExynosComponent->pExynosPort[i].bufferSemID = NULL;
442                 }
443
444                 ret = OMX_ErrorInsufficientResources;
445                 goto EXIT;
446             }
447             pExynosComponent->currentState = OMX_StateIdle;
448             break;
449         case OMX_StateExecuting:
450         case OMX_StatePause:
451             Exynos_OMX_BufferFlushProcess(pOMXComponent, ALL_PORT_INDEX, OMX_FALSE);
452             pExynosComponent->currentState = OMX_StateIdle;
453             break;
454         case OMX_StateWaitForResources:
455             pExynosComponent->currentState = OMX_StateIdle;
456             break;
457         default:
458             ret = OMX_ErrorIncorrectStateTransition;
459             break;
460         }
461         break;
462     case OMX_StateExecuting:
463         switch (currentState) {
464         case OMX_StateLoaded:
465             ret = OMX_ErrorIncorrectStateTransition;
466             break;
467         case OMX_StateIdle:
468             for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
469                 pExynosPort = &pExynosComponent->pExynosPort[i];
470                 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort) && CHECK_PORT_ENABLED(pExynosPort)) {
471                     for (j = 0; j < pExynosPort->tunnelBufferNum; j++) {
472                         Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID);
473                     }
474                 }
475             }
476
477             pExynosComponent->transientState = EXYNOS_OMX_TransStateMax;
478             pExynosComponent->currentState = OMX_StateExecuting;
479             if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
480                 Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
481             } else {
482                 for (i = 0; i < ALL_PORT_NUM; i++) {
483                     Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[i].pauseEvent);
484                 }
485             }
486             break;
487         case OMX_StatePause:
488             for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
489                 pExynosPort = &pExynosComponent->pExynosPort[i];
490                 if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort) && CHECK_PORT_ENABLED(pExynosPort)) {
491                     OMX_S32 semaValue = 0, cnt = 0;
492                     Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[i].bufferSemID, &semaValue);
493                     if (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > semaValue) {
494                         cnt = Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) - semaValue;
495                         for (k = 0; k < cnt; k++) {
496                             Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[i].bufferSemID);
497                         }
498                     }
499                 }
500             }
501
502             pExynosComponent->currentState = OMX_StateExecuting;
503             if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
504                 Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
505             } else {
506                 for (i = 0; i < ALL_PORT_NUM; i++) {
507                     Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[i].pauseEvent);
508                 }
509             }
510             break;
511         case OMX_StateWaitForResources:
512             ret = OMX_ErrorIncorrectStateTransition;
513             break;
514         default:
515             ret = OMX_ErrorIncorrectStateTransition;
516             break;
517         }
518         break;
519     case OMX_StatePause:
520         switch (currentState) {
521         case OMX_StateLoaded:
522             ret = OMX_ErrorIncorrectStateTransition;
523             break;
524         case OMX_StateIdle:
525             pExynosComponent->currentState = OMX_StatePause;
526             break;
527         case OMX_StateExecuting:
528             pExynosComponent->currentState = OMX_StatePause;
529             break;
530         case OMX_StateWaitForResources:
531             ret = OMX_ErrorIncorrectStateTransition;
532             break;
533         default:
534             ret = OMX_ErrorIncorrectStateTransition;
535             break;
536         }
537         break;
538     case OMX_StateWaitForResources:
539         switch (currentState) {
540         case OMX_StateLoaded:
541             ret = Exynos_OMX_In_WaitForResource(pOMXComponent);
542             pExynosComponent->currentState = OMX_StateWaitForResources;
543             break;
544         case OMX_StateIdle:
545         case OMX_StateExecuting:
546         case OMX_StatePause:
547             ret = OMX_ErrorIncorrectStateTransition;
548             break;
549         default:
550             ret = OMX_ErrorIncorrectStateTransition;
551             break;
552         }
553         break;
554     default:
555         ret = OMX_ErrorIncorrectStateTransition;
556         break;
557     }
558
559 EXIT:
560     if (ret == OMX_ErrorNone) {
561         if (pExynosComponent->pCallbacks != NULL) {
562             pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
563             pExynosComponent->callbackData,
564             OMX_EventCmdComplete, OMX_CommandStateSet,
565             destState, NULL);
566         }
567     } else {
568         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d", __FUNCTION__, __LINE__);
569         if (pExynosComponent->pCallbacks != NULL) {
570             pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
571             pExynosComponent->callbackData,
572             OMX_EventError, ret, 0, NULL);
573         }
574     }
575     FunctionOut();
576
577     return ret;
578 }
579
580 static OMX_ERRORTYPE Exynos_OMX_MessageHandlerThread(OMX_PTR threadData)
581 {
582     OMX_ERRORTYPE             ret = OMX_ErrorNone;
583     OMX_COMPONENTTYPE        *pOMXComponent = NULL;
584     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
585     EXYNOS_OMX_MESSAGE       *message = NULL;
586     OMX_U32                   messageType = 0, portIndex = 0;
587
588     FunctionIn();
589
590     if (threadData == NULL) {
591         ret = OMX_ErrorBadParameter;
592         goto EXIT;
593     }
594
595     pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
596     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
597     if (ret != OMX_ErrorNone) {
598         goto EXIT;
599     }
600
601     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
602
603     while (pExynosComponent->bExitMessageHandlerThread == OMX_FALSE) {
604         Exynos_OSAL_SemaphoreWait(pExynosComponent->msgSemaphoreHandle);
605         message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosComponent->messageQ);
606         if (message != NULL) {
607             messageType = message->messageType;
608             switch (messageType) {
609             case OMX_CommandStateSet:
610                 ret = Exynos_OMX_ComponentStateSet(pOMXComponent, message->messageParam);
611                 break;
612             case OMX_CommandFlush:
613                 ret = Exynos_OMX_BufferFlushProcess(pOMXComponent, message->messageParam, OMX_TRUE);
614                 break;
615             case OMX_CommandPortDisable:
616                 ret = Exynos_OMX_PortDisableProcess(pOMXComponent, message->messageParam);
617                 break;
618             case OMX_CommandPortEnable:
619                 ret = Exynos_OMX_PortEnableProcess(pOMXComponent, message->messageParam);
620                 break;
621             case OMX_CommandMarkBuffer:
622                 portIndex = message->messageParam;
623                 pExynosComponent->pExynosPort[portIndex].markType.hMarkTargetComponent = ((OMX_MARKTYPE *)message->pCmdData)->hMarkTargetComponent;
624                 pExynosComponent->pExynosPort[portIndex].markType.pMarkData            = ((OMX_MARKTYPE *)message->pCmdData)->pMarkData;
625                 break;
626             case (OMX_COMMANDTYPE)EXYNOS_OMX_CommandComponentDeInit:
627                 pExynosComponent->bExitMessageHandlerThread = OMX_TRUE;
628                 break;
629             default:
630                 break;
631             }
632             Exynos_OSAL_Free(message);
633             message = NULL;
634         }
635     }
636
637     Exynos_OSAL_ThreadExit(NULL);
638
639 EXIT:
640     FunctionOut();
641
642     return ret;
643 }
644
645 static OMX_ERRORTYPE Exynos_StateSet(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
646 {
647     OMX_U32 destState = nParam;
648     OMX_U32 i = 0;
649
650     if ((destState == OMX_StateIdle) && (pExynosComponent->currentState == OMX_StateLoaded)) {
651         pExynosComponent->transientState = EXYNOS_OMX_TransStateLoadedToIdle;
652         for(i = 0; i < pExynosComponent->portParam.nPorts; i++) {
653             pExynosComponent->pExynosPort[i].portState = OMX_StateIdle;
654         }
655         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateIdle");
656     } else if ((destState == OMX_StateLoaded) && (pExynosComponent->currentState == OMX_StateIdle)) {
657         pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToLoaded;
658         for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
659             pExynosComponent->pExynosPort[i].portState = OMX_StateLoaded;
660         }
661         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateLoaded");
662     } else if ((destState == OMX_StateIdle) && (pExynosComponent->currentState == OMX_StateExecuting)) {
663         pExynosComponent->transientState = EXYNOS_OMX_TransStateExecutingToIdle;
664         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateIdle");
665     } else if ((destState == OMX_StateExecuting) && (pExynosComponent->currentState == OMX_StateIdle)) {
666         pExynosComponent->transientState = EXYNOS_OMX_TransStateIdleToExecuting;
667         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "to OMX_StateExecuting");
668     } else if (destState == OMX_StateInvalid) {
669         for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
670             pExynosComponent->pExynosPort[i].portState = OMX_StateInvalid;
671         }
672     }
673
674     return OMX_ErrorNone;
675 }
676
677 static OMX_ERRORTYPE Exynos_SetPortFlush(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
678 {
679     OMX_ERRORTYPE        ret = OMX_ErrorNone;
680     EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
681     OMX_S32              portIndex = nParam;
682     OMX_U16              i = 0, cnt = 0, index = 0;
683
684
685     if ((pExynosComponent->currentState == OMX_StateExecuting) ||
686         (pExynosComponent->currentState == OMX_StatePause)) {
687         if ((portIndex != ALL_PORT_INDEX) &&
688            ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
689             ret = OMX_ErrorBadPortIndex;
690             goto EXIT;
691         }
692
693         /*********************
694         *    need flush event set ?????
695         **********************/
696         cnt = (portIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1;
697         for (i = 0; i < cnt; i++) {
698             if (portIndex == ALL_PORT_INDEX)
699                 index = i;
700             else
701                 index = portIndex;
702             pExynosComponent->pExynosPort[index].bIsPortFlushed = OMX_TRUE;
703         }
704     } else {
705         ret = OMX_ErrorIncorrectStateOperation;
706         goto EXIT;
707     }
708     ret = OMX_ErrorNone;
709
710 EXIT:
711     return ret;
712 }
713
714 static OMX_ERRORTYPE Exynos_SetPortEnable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
715 {
716     OMX_ERRORTYPE        ret = OMX_ErrorNone;
717     EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
718     OMX_S32              portIndex = nParam;
719     OMX_U16              i = 0, cnt = 0;
720
721     FunctionIn();
722
723     if ((portIndex != ALL_PORT_INDEX) &&
724         ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
725         ret = OMX_ErrorBadPortIndex;
726         goto EXIT;
727     }
728
729     if (portIndex == ALL_PORT_INDEX) {
730         for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
731             pExynosPort = &pExynosComponent->pExynosPort[i];
732             if (CHECK_PORT_ENABLED(pExynosPort)) {
733                 ret = OMX_ErrorIncorrectStateOperation;
734                 goto EXIT;
735             } else {
736                 pExynosPort->portState = OMX_StateIdle;
737             }
738         }
739     } else {
740         pExynosPort = &pExynosComponent->pExynosPort[portIndex];
741         if (CHECK_PORT_ENABLED(pExynosPort)) {
742             ret = OMX_ErrorIncorrectStateOperation;
743             goto EXIT;
744         } else {
745             pExynosPort->portState = OMX_StateIdle;
746         }
747     }
748     ret = OMX_ErrorNone;
749
750 EXIT:
751     FunctionOut();
752
753     return ret;
754
755 }
756
757 static OMX_ERRORTYPE Exynos_SetPortDisable(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
758 {
759     OMX_ERRORTYPE        ret = OMX_ErrorNone;
760     EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
761     OMX_S32              portIndex = nParam;
762     OMX_U16              i = 0, cnt = 0;
763
764     FunctionIn();
765
766     if ((portIndex != ALL_PORT_INDEX) &&
767         ((OMX_S32)portIndex >= (OMX_S32)pExynosComponent->portParam.nPorts)) {
768         ret = OMX_ErrorBadPortIndex;
769         goto EXIT;
770     }
771
772     if (portIndex == ALL_PORT_INDEX) {
773         for (i = 0; i < pExynosComponent->portParam.nPorts; i++) {
774             pExynosPort = &pExynosComponent->pExynosPort[i];
775             if (!CHECK_PORT_ENABLED(pExynosPort)) {
776                 ret = OMX_ErrorIncorrectStateOperation;
777                 goto EXIT;
778             }
779             pExynosPort->portState = OMX_StateLoaded;
780             pExynosPort->bIsPortDisabled = OMX_TRUE;
781         }
782     } else {
783         pExynosPort = &pExynosComponent->pExynosPort[portIndex];
784         pExynosPort->portState = OMX_StateLoaded;
785         pExynosPort->bIsPortDisabled = OMX_TRUE;
786     }
787     ret = OMX_ErrorNone;
788
789 EXIT:
790     FunctionOut();
791
792     return ret;
793 }
794
795 static OMX_ERRORTYPE Exynos_SetMarkBuffer(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nParam)
796 {
797     OMX_ERRORTYPE        ret = OMX_ErrorNone;
798     EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
799     OMX_U32              portIndex = nParam;
800     OMX_U16              i = 0, cnt = 0;
801
802
803     if (nParam >= pExynosComponent->portParam.nPorts) {
804         ret = OMX_ErrorBadPortIndex;
805         goto EXIT;
806     }
807
808     if ((pExynosComponent->currentState == OMX_StateExecuting) ||
809         (pExynosComponent->currentState == OMX_StatePause)) {
810         ret = OMX_ErrorNone;
811     } else {
812         ret = OMX_ErrorIncorrectStateOperation;
813     }
814
815 EXIT:
816     return ret;
817 }
818
819 static OMX_ERRORTYPE Exynos_OMX_CommandQueue(
820     EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
821     OMX_COMMANDTYPE        Cmd,
822     OMX_U32                nParam,
823     OMX_PTR                pCmdData)
824 {
825     OMX_ERRORTYPE    ret = OMX_ErrorNone;
826     EXYNOS_OMX_MESSAGE *command = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE));
827
828     if (command == NULL) {
829         ret = OMX_ErrorInsufficientResources;
830         goto EXIT;
831     }
832     command->messageType  = (OMX_U32)Cmd;
833     command->messageParam = nParam;
834     command->pCmdData     = pCmdData;
835
836     ret = Exynos_OSAL_Queue(&pExynosComponent->messageQ, (void *)command);
837     if (ret != 0) {
838         ret = OMX_ErrorUndefined;
839         goto EXIT;
840     }
841     ret = Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle);
842
843 EXIT:
844     return ret;
845 }
846
847 OMX_ERRORTYPE Exynos_OMX_SendCommand(
848     OMX_IN OMX_HANDLETYPE  hComponent,
849     OMX_IN OMX_COMMANDTYPE Cmd,
850     OMX_IN OMX_U32         nParam,
851     OMX_IN OMX_PTR         pCmdData)
852 {
853     OMX_ERRORTYPE             ret = OMX_ErrorNone;
854     OMX_COMPONENTTYPE        *pOMXComponent = NULL;
855     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
856     EXYNOS_OMX_MESSAGE       *message = NULL;
857
858     FunctionIn();
859
860     if (hComponent == NULL) {
861         ret = OMX_ErrorBadParameter;
862         goto EXIT;
863     }
864     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
865     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
866     if (ret != OMX_ErrorNone) {
867         goto EXIT;
868     }
869
870     if (pOMXComponent->pComponentPrivate == NULL) {
871         ret = OMX_ErrorBadParameter;
872         goto EXIT;
873     }
874     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
875
876     if (pExynosComponent->currentState == OMX_StateInvalid) {
877         ret = OMX_ErrorInvalidState;
878         goto EXIT;
879     }
880
881     switch (Cmd) {
882     case OMX_CommandStateSet :
883         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandStateSet");
884         Exynos_StateSet(pExynosComponent, nParam);
885         break;
886     case OMX_CommandFlush :
887         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandFlush");
888         ret = Exynos_SetPortFlush(pExynosComponent, nParam);
889         if (ret != OMX_ErrorNone)
890             goto EXIT;
891         break;
892     case OMX_CommandPortDisable :
893         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandPortDisable");
894         ret = Exynos_SetPortDisable(pExynosComponent, nParam);
895         if (ret != OMX_ErrorNone)
896             goto EXIT;
897         break;
898     case OMX_CommandPortEnable :
899         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandPortEnable");
900         ret = Exynos_SetPortEnable(pExynosComponent, nParam);
901         if (ret != OMX_ErrorNone)
902             goto EXIT;
903         break;
904     case OMX_CommandMarkBuffer :
905         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Command: OMX_CommandMarkBuffer");
906         ret = Exynos_SetMarkBuffer(pExynosComponent, nParam);
907         if (ret != OMX_ErrorNone)
908             goto EXIT;
909         break;
910     default:
911         break;
912     }
913
914     ret = Exynos_OMX_CommandQueue(pExynosComponent, Cmd, nParam, pCmdData);
915
916 EXIT:
917     FunctionOut();
918
919     return ret;
920 }
921
922 OMX_ERRORTYPE Exynos_OMX_GetParameter(
923     OMX_IN OMX_HANDLETYPE hComponent,
924     OMX_IN OMX_INDEXTYPE  nParamIndex,
925     OMX_INOUT OMX_PTR     ComponentParameterStructure)
926 {
927     OMX_ERRORTYPE             ret = OMX_ErrorNone;
928     OMX_COMPONENTTYPE        *pOMXComponent = NULL;
929     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
930
931     FunctionIn();
932
933     if (hComponent == NULL) {
934         ret = OMX_ErrorBadParameter;
935         goto EXIT;
936     }
937     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
938     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
939     if (ret != OMX_ErrorNone) {
940         goto EXIT;
941     }
942
943     if (pOMXComponent->pComponentPrivate == NULL) {
944         ret = OMX_ErrorBadParameter;
945         goto EXIT;
946     }
947     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
948
949     if (ComponentParameterStructure == NULL) {
950         ret = OMX_ErrorBadParameter;
951         goto EXIT;
952     }
953     if (pExynosComponent->currentState == OMX_StateInvalid) {
954         ret = OMX_ErrorInvalidState;
955         goto EXIT;
956     }
957
958     switch (nParamIndex) {
959     case OMX_IndexParamAudioInit:
960     case OMX_IndexParamVideoInit:
961     case OMX_IndexParamImageInit:
962     case OMX_IndexParamOtherInit:
963     {
964         OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
965         ret = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE));
966         if (ret != OMX_ErrorNone) {
967             goto EXIT;
968         }
969         portParam->nPorts         = 0;
970         portParam->nStartPortNumber     = 0;
971     }
972         break;
973     case OMX_IndexParamPortDefinition:
974     {
975         OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
976         OMX_U32                       portIndex = portDefinition->nPortIndex;
977         EXYNOS_OMX_BASEPORT          *pExynosPort;
978
979         if (portIndex >= pExynosComponent->portParam.nPorts) {
980             ret = OMX_ErrorBadPortIndex;
981             goto EXIT;
982         }
983         ret = Exynos_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
984         if (ret != OMX_ErrorNone) {
985             goto EXIT;
986         }
987
988         pExynosPort = &pExynosComponent->pExynosPort[portIndex];
989         Exynos_OSAL_Memcpy(portDefinition, &pExynosPort->portDefinition, portDefinition->nSize);
990     }
991         break;
992     case OMX_IndexParamPriorityMgmt:
993     {
994         OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure;
995
996         ret = Exynos_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE));
997         if (ret != OMX_ErrorNone) {
998             goto EXIT;
999         }
1000
1001         compPriority->nGroupID       = pExynosComponent->compPriority.nGroupID;
1002         compPriority->nGroupPriority = pExynosComponent->compPriority.nGroupPriority;
1003     }
1004         break;
1005
1006     case OMX_IndexParamCompBufferSupplier:
1007     {
1008         OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure;
1009         OMX_U32                       portIndex = bufferSupplier->nPortIndex;
1010         EXYNOS_OMX_BASEPORT          *pExynosPort;
1011
1012         if ((pExynosComponent->currentState == OMX_StateLoaded) ||
1013             (pExynosComponent->currentState == OMX_StateWaitForResources)) {
1014             if (portIndex >= pExynosComponent->portParam.nPorts) {
1015                 ret = OMX_ErrorBadPortIndex;
1016                 goto EXIT;
1017             }
1018             ret = Exynos_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
1019             if (ret != OMX_ErrorNone) {
1020                 goto EXIT;
1021             }
1022
1023             pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1024
1025
1026             if (pExynosPort->portDefinition.eDir == OMX_DirInput) {
1027                 if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
1028                     bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput;
1029                 } else if (CHECK_PORT_TUNNELED(pExynosPort)) {
1030                     bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput;
1031                 } else {
1032                     bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified;
1033                 }
1034             } else {
1035                 if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
1036                     bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput;
1037                 } else if (CHECK_PORT_TUNNELED(pExynosPort)) {
1038                     bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput;
1039                 } else {
1040                     bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified;
1041                 }
1042             }
1043         }
1044         else
1045         {
1046             ret = OMX_ErrorIncorrectStateOperation;
1047             goto EXIT;
1048         }
1049     }
1050         break;
1051     default:
1052     {
1053         ret = OMX_ErrorUnsupportedIndex;
1054         goto EXIT;
1055     }
1056         break;
1057     }
1058
1059     ret = OMX_ErrorNone;
1060
1061 EXIT:
1062
1063     FunctionOut();
1064
1065     return ret;
1066 }
1067
1068 OMX_ERRORTYPE Exynos_OMX_SetParameter(
1069     OMX_IN OMX_HANDLETYPE hComponent,
1070     OMX_IN OMX_INDEXTYPE  nIndex,
1071     OMX_IN OMX_PTR        ComponentParameterStructure)
1072 {
1073     OMX_ERRORTYPE             ret = OMX_ErrorNone;
1074     OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1075     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1076
1077     FunctionIn();
1078
1079     if (hComponent == NULL) {
1080         ret = OMX_ErrorBadParameter;
1081         goto EXIT;
1082     }
1083     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1084     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1085     if (ret != OMX_ErrorNone) {
1086         goto EXIT;
1087     }
1088
1089     if (pOMXComponent->pComponentPrivate == NULL) {
1090         ret = OMX_ErrorBadParameter;
1091         goto EXIT;
1092     }
1093     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1094
1095     if (ComponentParameterStructure == NULL) {
1096         ret = OMX_ErrorBadParameter;
1097         goto EXIT;
1098     }
1099     if (pExynosComponent->currentState == OMX_StateInvalid) {
1100         ret = OMX_ErrorInvalidState;
1101         goto EXIT;
1102     }
1103
1104     switch (nIndex) {
1105     case OMX_IndexParamAudioInit:
1106     case OMX_IndexParamVideoInit:
1107     case OMX_IndexParamImageInit:
1108     case OMX_IndexParamOtherInit:
1109     {
1110         OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
1111         ret = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE));
1112         if (ret != OMX_ErrorNone) {
1113             goto EXIT;
1114         }
1115
1116         if ((pExynosComponent->currentState != OMX_StateLoaded) &&
1117             (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1118             ret = OMX_ErrorIncorrectStateOperation;
1119             goto EXIT;
1120         }
1121         ret = OMX_ErrorUndefined;
1122         /* Exynos_OSAL_Memcpy(&pExynosComponent->portParam, portParam, sizeof(OMX_PORT_PARAM_TYPE)); */
1123     }
1124         break;
1125     case OMX_IndexParamPortDefinition:
1126     {
1127         OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
1128         OMX_U32                       portIndex = portDefinition->nPortIndex;
1129         EXYNOS_OMX_BASEPORT          *pExynosPort;
1130         OMX_PARAM_PORTDEFINITIONTYPE  portDefinition_backup;
1131
1132         if (portIndex >= pExynosComponent->portParam.nPorts) {
1133             ret = OMX_ErrorBadPortIndex;
1134             goto EXIT;
1135         }
1136         ret = Exynos_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1137         if (ret != OMX_ErrorNone) {
1138             goto EXIT;
1139         }
1140
1141         pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1142
1143         if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1144             if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
1145                 ret = OMX_ErrorIncorrectStateOperation;
1146                 goto EXIT;
1147             }
1148         }
1149         if (portDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
1150             ret = OMX_ErrorBadParameter;
1151             goto EXIT;
1152         }
1153
1154         Exynos_OSAL_Memcpy(&portDefinition_backup, &pExynosPort->portDefinition, portDefinition->nSize);
1155         Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, portDefinition, portDefinition->nSize);
1156         RESTORE_READONLYPARAMETERS_OMX_PARAM_PORTDEFINITIONTYPE(&pExynosPort->portDefinition,&portDefinition_backup);
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
1262 EXIT:
1263
1264     FunctionOut();
1265
1266     return ret;
1267 }
1268
1269 OMX_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
1311 EXIT:
1312     FunctionOut();
1313
1314     return ret;
1315 }
1316
1317 OMX_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
1359 EXIT:
1360     FunctionOut();
1361
1362     return ret;
1363 }
1364
1365 OMX_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
1403 EXIT:
1404     FunctionOut();
1405
1406     return ret;
1407 }
1408
1409 OMX_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
1454 EXIT:
1455     FunctionOut();
1456
1457     return ret;
1458 }
1459
1460 OMX_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
1470 OMX_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
1507     pExynosComponent->bExitMessageHandlerThread = OMX_FALSE;
1508     Exynos_OSAL_QueueCreate(&pExynosComponent->messageQ, MAX_QUEUE_ELEMENTS);
1509     ret = Exynos_OSAL_ThreadCreate(&pExynosComponent->hMessageHandler, Exynos_OMX_MessageHandlerThread, pOMXComponent);
1510     if (ret != OMX_ErrorNone) {
1511         ret = OMX_ErrorInsufficientResources;
1512         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1513         goto EXIT;
1514     }
1515
1516     pExynosComponent->bMultiThreadProcess = OMX_FALSE;
1517
1518     pOMXComponent->GetComponentVersion = &Exynos_OMX_GetComponentVersion;
1519     pOMXComponent->SendCommand         = &Exynos_OMX_SendCommand;
1520     pOMXComponent->GetState            = &Exynos_OMX_GetState;
1521     pOMXComponent->SetCallbacks        = &Exynos_OMX_SetCallbacks;
1522     pOMXComponent->UseEGLImage         = &Exynos_OMX_UseEGLImage;
1523
1524 EXIT:
1525     FunctionOut();
1526
1527     return ret;
1528 }
1529
1530 OMX_ERRORTYPE Exynos_OMX_BaseComponent_Destructor(
1531     OMX_IN OMX_HANDLETYPE hComponent)
1532 {
1533     OMX_ERRORTYPE             ret = OMX_ErrorNone;
1534     OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1535     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1536     OMX_S32                   semaValue = 0;
1537
1538     FunctionIn();
1539
1540     if (hComponent == NULL) {
1541         ret = OMX_ErrorBadParameter;
1542         goto EXIT;
1543     }
1544     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1545     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1546     if (ret != OMX_ErrorNone) {
1547         goto EXIT;
1548     }
1549
1550     if (pOMXComponent->pComponentPrivate == NULL) {
1551         ret = OMX_ErrorBadParameter;
1552         goto EXIT;
1553     }
1554     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1555
1556     Exynos_OMX_CommandQueue(pExynosComponent, EXYNOS_OMX_CommandComponentDeInit, 0, NULL);
1557     Exynos_OSAL_SleepMillisec(0);
1558     Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->msgSemaphoreHandle, &semaValue);
1559     if (semaValue == 0)
1560         Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle);
1561     Exynos_OSAL_SemaphorePost(pExynosComponent->msgSemaphoreHandle);
1562
1563     Exynos_OSAL_ThreadTerminate(pExynosComponent->hMessageHandler);
1564     pExynosComponent->hMessageHandler = NULL;
1565
1566     Exynos_OSAL_MutexTerminate(pExynosComponent->compMutex);
1567     pExynosComponent->compMutex = NULL;
1568     Exynos_OSAL_SemaphoreTerminate(pExynosComponent->msgSemaphoreHandle);
1569     pExynosComponent->msgSemaphoreHandle = NULL;
1570     Exynos_OSAL_QueueTerminate(&pExynosComponent->messageQ);
1571
1572     Exynos_OSAL_Free(pExynosComponent);
1573     pExynosComponent = NULL;
1574
1575     ret = OMX_ErrorNone;
1576 EXIT:
1577     FunctionOut();
1578
1579     return ret;
1580 }
1581
1582