Initial version of libomxil-e3250-v4l2
[platform/adaptation/ap_samsung/libomxil-e3250-v4l2.git] / openmax / component / video / dec / Exynos_OMX_Vdec.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_Vdec.c
20  * @brief
21  * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
22  *              HyeYeon Chung (hyeon.chung@samsung.com)
23  *              Yunji Kim (yunji.kim@samsung.com)
24  * @version     2.0.0
25  * @history
26  *   2012.02.20 : Create
27  */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include "Exynos_OMX_Macros.h"
33 #include "Exynos_OSAL_Event.h"
34 #include "Exynos_OMX_Vdec.h"
35 #include "Exynos_OMX_VdecControl.h"
36 #include "Exynos_OMX_Basecomponent.h"
37 #include "Exynos_OSAL_Thread.h"
38 #include "Exynos_OSAL_Semaphore.h"
39 #include "Exynos_OSAL_Mutex.h"
40 #include "Exynos_OSAL_ETC.h"
41
42 #ifdef USE_PB
43 #include "Exynos_OSAL_Platform_Specific.h"
44 #endif
45
46 #include "ExynosVideoApi.h"
47 #include "csc.h"
48
49 #undef  EXYNOS_LOG_TAG
50 #define EXYNOS_LOG_TAG    "EXYNOS_VIDEO_DEC"
51 #define EXYNOS_LOG_OFF
52 //#define EXYNOS_TRACE_ON
53 #include "Exynos_OSAL_Log.h"
54
55 int calc_plane(int width, int height)
56 {
57     int mbX, mbY;
58
59     mbX = ALIGN(width, S5P_FIMV_NV12MT_HALIGN);
60     mbY = ALIGN(height, S5P_FIMV_NV12MT_VALIGN);
61
62     return ALIGN(mbX * mbY, S5P_FIMV_DEC_BUF_ALIGN);
63 }
64
65 int calc_yplane(int width, int height)
66 {
67     int mbX, mbY;
68
69     mbX = ALIGN(width + 24, S5P_FIMV_NV12MT_HALIGN);
70     mbY = ALIGN(height + 16, S5P_FIMV_NV12MT_VALIGN);
71
72     return ALIGN(mbX * mbY, S5P_FIMV_DEC_BUF_ALIGN);
73 }
74
75 int calc_uvplane(int width, int height)
76 {
77     int mbX, mbY;
78
79     mbX = ALIGN(width + 16, S5P_FIMV_NV12MT_HALIGN);
80     mbY = ALIGN(height + 4, S5P_FIMV_NV12MT_VALIGN);
81
82     return ALIGN(mbX * mbY, S5P_FIMV_DEC_BUF_ALIGN);
83 }
84
85 inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent)
86 {
87     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
88     EXYNOS_OMX_BASEPORT      *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
89     EXYNOS_OMX_BASEPORT      *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
90
91     if ((exynosOutputPort->portDefinition.format.video.nFrameWidth !=
92             exynosInputPort->portDefinition.format.video.nFrameWidth) ||
93         (exynosOutputPort->portDefinition.format.video.nFrameHeight !=
94             exynosInputPort->portDefinition.format.video.nFrameHeight)) {
95         OMX_U32 width = 0, height = 0;
96
97         exynosOutputPort->portDefinition.format.video.nFrameWidth =
98             exynosInputPort->portDefinition.format.video.nFrameWidth;
99         exynosOutputPort->portDefinition.format.video.nFrameHeight =
100             exynosInputPort->portDefinition.format.video.nFrameHeight;
101         width = exynosOutputPort->portDefinition.format.video.nStride =
102             exynosInputPort->portDefinition.format.video.nStride;
103         height = exynosOutputPort->portDefinition.format.video.nSliceHeight =
104             exynosInputPort->portDefinition.format.video.nSliceHeight;
105
106         switch(exynosOutputPort->portDefinition.format.video.eColorFormat) {
107         case OMX_COLOR_FormatYUV420Planar:
108         case OMX_COLOR_FormatYUV420SemiPlanar:
109             if (width && height)
110                 exynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2;
111             break;
112 #ifdef SLP_PLATFORM /* nv12t fd */
113         case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd:
114             if (width && height)
115                 exynosOutputPort->portDefinition.nBufferSize = sizeof(SCMN_IMGB);
116             break;
117 #endif
118         case OMX_SEC_COLOR_FormatNV12Tiled:
119             width = exynosOutputPort->portDefinition.format.video.nFrameWidth;
120             height = exynosOutputPort->portDefinition.format.video.nFrameHeight;
121             if (width && height) {
122                 int YBufferSize = calc_plane(width, height);
123                 int CBufferSize = calc_plane(width, height >> 1);
124                 exynosOutputPort->portDefinition.nBufferSize = YBufferSize + CBufferSize;
125             }
126             break;
127         default:
128             if (width && height)
129                 exynosOutputPort->portDefinition.nBufferSize = width * height * 2;
130             break;
131         }
132     }
133
134     return;
135 }
136
137 OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
138 {
139     OMX_BOOL ret = OMX_FALSE;
140 #ifdef SLP_PLATFORM /* check state */
141     if (pExynosComponent->currentState != OMX_StateExecuting)
142         Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "not OMX_StateExecuting");
143
144     if (pExynosComponent->pExynosPort[nPortIndex].portState != OMX_StateIdle)
145         Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "not OMX_StateIdle");
146
147     if (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)
148         Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "EXYNOS_OMX_TransStateExecutingToIdle");
149
150     if (pExynosComponent->transientState == EXYNOS_OMX_TransStateIdleToExecuting)
151         Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "EXYNOS_OMX_TransStateIdleToExecuting");
152
153     if ((pExynosComponent->currentState == OMX_StateExecuting) &&
154         (pExynosComponent->pExynosPort[nPortIndex].portState == OMX_StateIdle) &&
155         (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
156         (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) {
157         ret = OMX_TRUE;
158 #else
159     if ((pExynosComponent->currentState == OMX_StateExecuting) &&
160         (pExynosComponent->pExynosPort[nPortIndex].portState == OMX_StateIdle) &&
161         (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
162         (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) {
163         ret = OMX_TRUE;
164 #endif
165     } else {
166         ret = OMX_FALSE;
167     }
168
169     return ret;
170 }
171
172 OMX_ERRORTYPE Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData)
173 {
174     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
175     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
176     CODEC_DEC_BUFFER *pInputCodecBuffer = (CODEC_DEC_BUFFER *)codecBuffer;
177
178     pData->buffer.singlePlaneBuffer.dataBuffer = pInputCodecBuffer->pVirAddr[0];
179     pData->buffer.singlePlaneBuffer.fd = pInputCodecBuffer->fd[0];
180     pData->allocSize     = pInputCodecBuffer->bufferSize[0];
181     pData->dataLen       = pInputCodecBuffer->dataSize;
182     pData->usedDataLen   = 0;
183     pData->remainDataLen = pInputCodecBuffer->dataSize;
184
185     pData->nFlags        = 0;
186     pData->timeStamp     = 0;
187     pData->pPrivate      = codecBuffer;
188     pData->bufferHeader  = NULL;
189
190     return ret;
191 }
192
193 OMX_ERRORTYPE Exynos_Output_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData)
194 {
195     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
196     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
197     OMX_PTR pSrcBuf[MAX_BUFFER_PLANE];
198     OMX_U32 allocSize[MAX_BUFFER_PLANE];
199
200     pVideoDec->exynos_codec_getCodecOutputPrivateData(codecBuffer, pSrcBuf, allocSize);
201     pData->buffer.multiPlaneBuffer.dataBuffer[0] = pSrcBuf[0];
202     pData->buffer.multiPlaneBuffer.dataBuffer[1] = pSrcBuf[1];
203     pData->buffer.multiPlaneBuffer.dataBuffer[2] = pSrcBuf[2];
204     pData->allocSize     = allocSize[0] + allocSize[1] + allocSize[2];
205     pData->dataLen       = 0;
206     pData->usedDataLen   = 0;
207     pData->remainDataLen = 0;
208
209     pData->nFlags        = 0;
210     pData->timeStamp     = 0;
211     pData->pPrivate      = codecBuffer;
212     pData->bufferHeader  = NULL;
213
214     return ret;
215 }
216
217 void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
218 {
219     EXYNOS_OMX_BASEPORT *exynosOMXInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
220     EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
221     EXYNOS_OMX_BASEPORT *exynosOMXPort = NULL;
222
223     FunctionIn();
224
225     exynosOMXPort = &pExynosComponent->pExynosPort[nPortIndex];
226
227     if (((pExynosComponent->currentState == OMX_StatePause) ||
228         (pExynosComponent->currentState == OMX_StateIdle) ||
229         (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) ||
230         (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)) &&
231         (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded) &&
232         (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort))) {
233         Exynos_OSAL_SignalWait(pExynosComponent->pExynosPort[nPortIndex].pauseEvent, DEF_MAX_WAIT_TIME);
234         Exynos_OSAL_SignalReset(pExynosComponent->pExynosPort[nPortIndex].pauseEvent);
235     }
236
237     FunctionOut();
238
239     return;
240 }
241
242 OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
243 {
244     OMX_BOOL                       ret              = OMX_FALSE;
245     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
246     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
247     EXYNOS_OMX_BASEPORT           *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
248     EXYNOS_OMX_BASEPORT           *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
249
250     EXYNOS_OMX_DATABUFFER         *outputUseBuffer  = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
251     OMX_U32                        copySize         = 0;
252     DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo      = NULL;
253 #ifdef SLP_PLATFORM
254     SCMN_IMGB *pSlpOutBuf = NULL;
255 #endif
256
257     FunctionIn();
258
259     OMX_U32 width = 0, height = 0;
260     int imageSize = 0;
261     OMX_COLOR_FORMATTYPE colorFormat;
262
263     void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer;
264     void *pSrcBuf[MAX_BUFFER_PLANE] = {NULL, };
265     void *pYUVBuf[MAX_BUFFER_PLANE] = {NULL, };
266
267     CSC_ERRORCODE cscRet = CSC_ErrorNone;
268     CSC_METHOD csc_method = CSC_METHOD_SW;
269     unsigned int cacheable = 1;
270
271     pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo;
272
273     width = pBufferInfo->imageWidth;
274     height = pBufferInfo->imageHeight;
275     imageSize = width * height;
276     colorFormat = pBufferInfo->ColorFormat;
277
278 #ifdef SLP_PLATFORM
279     pSlpOutBuf = (SCMN_IMGB *)pOutputBuf;
280     pSlpOutBuf->w[0] = width;
281     pSlpOutBuf->w[1] = width;
282     pSlpOutBuf->h[0] = height;
283     pSlpOutBuf->h[1] = height/2;
284     pSlpOutBuf->s[0] = width; /* need to check. stride */
285     pSlpOutBuf->s[1] = width;
286     pSlpOutBuf->e[0] = height; /* need to check. elevation */
287     pSlpOutBuf->e[1] = height/2;
288
289     if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
290         pSlpOutBuf->a[0] = 0;
291         pSlpOutBuf->a[1] = 0;
292     } else {
293         pSlpOutBuf->a[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0];
294         pSlpOutBuf->a[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1];
295     }
296     pSlpOutBuf->a[2] = 0; /* omx do not use this plane */
297
298
299     pSlpOutBuf->fd[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0];
300     pSlpOutBuf->fd[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1];
301     pSlpOutBuf->fd[2] = dstOutputData->buffer.multiPlaneBuffer.fd[2];
302
303     pSlpOutBuf->buf_share_method = MEMORY_DMABUF;
304     dstOutputData->dataLen = sizeof(SCMN_IMGB);
305
306     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: using fd instead of csc", __FUNCTION__);
307     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fd (%d, %d, %d) received from MFC", pSlpOutBuf->fd[0], pSlpOutBuf->fd[1], pSlpOutBuf->fd[2]);
308
309     ret = OMX_TRUE;
310     goto EXIT;
311 #endif
312
313     pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0];
314     pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1];
315     pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[2];
316
317     pYUVBuf[0]  = (unsigned char *)pOutputBuf;
318     pYUVBuf[1]  = (unsigned char *)pOutputBuf + imageSize;
319     pYUVBuf[2]  = (unsigned char *)pOutputBuf + imageSize + imageSize / 4;
320
321     csc_get_method(pVideoDec->csc_handle, &csc_method);
322 #ifdef USE_DMA_BUF
323     if (csc_method == CSC_METHOD_HW) {
324         pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0];
325         pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1];
326         pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.fd[2];
327     }
328 #endif
329
330 #ifdef USE_PB
331     if (exynosOutputPort->bIsPBEnabled == OMX_TRUE) {
332         ExynosVideoPlane planes[MAX_BUFFER_PLANE];
333         OMX_U32 stride;
334         Exynos_OSAL_LockPB(pOutputBuf, width, height, exynosOutputPort->portDefinition.format.video.eColorFormat, &stride, planes);
335         width = stride;
336         outputUseBuffer->dataLen = sizeof(void *);
337
338         pYUVBuf[0]  = (unsigned char *)planes[0].addr;
339         pYUVBuf[1]  = (unsigned char *)planes[1].addr;
340         pYUVBuf[2]  = (unsigned char *)planes[2].addr;
341 #ifdef USE_DMA_BUF
342         if (csc_method == CSC_METHOD_HW) {
343             pYUVBuf[0]  = (unsigned char *)planes[0].fd;
344             pYUVBuf[1]  = (unsigned char *)planes[1].fd;
345             pYUVBuf[2]  = (unsigned char *)planes[2].fd;
346         }
347 #endif
348     }
349 #endif
350 #ifdef USE_DMA_BUF
351     if ((exynosOutputPort->bIsPBEnabled == OMX_FALSE) &&
352         (csc_method == CSC_METHOD_HW)) {
353         pYUVBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf);
354         pYUVBuf[1] = NULL;
355         pYUVBuf[2] = NULL;
356     }
357 #endif
358
359     if (pVideoDec->csc_set_format == OMX_FALSE) {
360         csc_set_src_format(
361             pVideoDec->csc_handle,  /* handle */
362             width,            /* width */
363             height,           /* height */
364             0,                /* crop_left */
365             0,                /* crop_right */
366             width,            /* crop_width */
367             height,           /* crop_height */
368             omx_2_hal_pixel_format(colorFormat), /* color_format */
369             cacheable);             /* cacheable */
370         csc_set_dst_format(
371             pVideoDec->csc_handle,  /* handle */
372             width,           /* width */
373             height,           /* height */
374             0,                /* crop_left */
375             0,                /* crop_right */
376             width,           /* crop_width */
377             height,           /* crop_height */
378             omx_2_hal_pixel_format(exynosOutputPort->portDefinition.format.video.eColorFormat), /* color_format */
379             cacheable);             /* cacheable */
380         pVideoDec->csc_set_format = OMX_TRUE;
381     }
382     csc_set_src_buffer(
383         pVideoDec->csc_handle,  /* handle */
384         pSrcBuf[0],             /* y addr */
385         pSrcBuf[1],             /* u addr or uv addr */
386         pSrcBuf[2],             /* v addr or none */
387         0);                     /* ion fd */
388     csc_set_dst_buffer(
389         pVideoDec->csc_handle,  /* handle */
390         pYUVBuf[0],             /* y addr */
391         pYUVBuf[1],             /* u addr or uv addr */
392         pYUVBuf[2],             /* v addr or none */
393         0);                     /* ion fd */
394     cscRet = csc_convert(pVideoDec->csc_handle);
395     if (cscRet != CSC_ErrorNone)
396         ret = OMX_FALSE;
397     else
398         ret = OMX_TRUE;
399
400 #ifdef USE_PB
401     if (exynosOutputPort->bIsPBEnabled == OMX_TRUE) {
402 #ifdef SLP_PLATFORM
403         Exynos_OSAL_UnlockPB(pOutputBuf, dstOutputData, exynosOutputPort, exynosInputPort);
404 #else
405         Exynos_OSAL_UnlockPB(pOutputBuf, dstOutputData);
406 #endif
407     }
408 #endif
409
410 EXIT:
411     FunctionOut();
412
413     return ret;
414 }
415
416 OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData)
417 {
418     OMX_BOOL               ret = OMX_FALSE;
419     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
420     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
421     EXYNOS_OMX_BASEPORT      *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
422     EXYNOS_OMX_DATABUFFER    *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
423     OMX_U32                copySize = 0;
424     OMX_BYTE               checkInputStream = NULL;
425     OMX_U32                checkInputStreamLen = 0;
426
427     FunctionIn();
428
429     if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
430         if ((srcInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) ||
431             (srcInputData->pPrivate == NULL)) {
432             ret = OMX_FALSE;
433             goto EXIT;
434         }
435     }
436
437     if (inputUseBuffer->dataValid == OMX_TRUE) {
438         if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
439             Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE);
440
441 #ifndef SLP_PLATFORM
442             if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
443                 OMX_PTR dataBuffer = NULL;
444
445                 dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory,
446                                                             srcInputData->buffer.singlePlaneBuffer.dataBuffer);
447                 if (dataBuffer == NULL) {
448                     ret = OMX_FALSE;
449                     goto EXIT;
450                 }
451
452                 srcInputData->buffer.singlePlaneBuffer.dataBuffer = dataBuffer;
453             }
454 #endif
455             /* reset dataBuffer */
456             Exynos_ResetDataBuffer(inputUseBuffer);
457         } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
458             checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
459             checkInputStreamLen = inputUseBuffer->remainDataLen;
460
461             pExynosComponent->bUseFlagEOF = OMX_TRUE;
462
463             copySize = checkInputStreamLen;
464             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE");
465
466             if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) {
467                 if (copySize > 0) {
468                     Exynos_OSAL_Memcpy(srcInputData->buffer.singlePlaneBuffer.dataBuffer + srcInputData->dataLen,
469                                        checkInputStream, copySize);
470                 }
471
472                 inputUseBuffer->dataLen -= copySize;
473                 inputUseBuffer->remainDataLen -= copySize;
474                 inputUseBuffer->usedDataLen += copySize;
475
476                 srcInputData->dataLen += copySize;
477                 srcInputData->remainDataLen += copySize;
478
479                 srcInputData->timeStamp = inputUseBuffer->timeStamp;
480                 srcInputData->nFlags = inputUseBuffer->nFlags;
481                 srcInputData->bufferHeader = inputUseBuffer->bufferHeader;
482             } else {
483                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length");
484                 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
485                                                         pExynosComponent->callbackData,
486                                                         OMX_EventError, OMX_ErrorUndefined, 0, NULL);
487                 ret = OMX_FALSE;
488             }
489
490             Exynos_InputBufferReturn(pOMXComponent);
491         }
492
493         if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
494             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE");
495             srcInputData->dataLen = 0;
496             srcInputData->remainDataLen = 0;
497             pExynosComponent->bSaveFlagEOS = OMX_TRUE;
498         }
499
500         if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
501             pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
502             pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp;
503             pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags;
504             pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
505             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)",
506                             srcInputData->timeStamp, srcInputData->timeStamp / 1E6);
507         }
508
509         ret = OMX_TRUE;
510     }
511
512 EXIT:
513
514     FunctionOut();
515
516     return ret;
517 }
518
519 OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
520 {
521     OMX_BOOL                   ret = OMX_FALSE;
522     EXYNOS_OMX_BASECOMPONENT  *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
523     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
524     EXYNOS_OMX_BASEPORT       *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
525     EXYNOS_OMX_BASEPORT       *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 
526     EXYNOS_OMX_DATABUFFER     *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
527     OMX_U32                    copySize = 0;
528     DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
529
530     FunctionIn();
531
532     if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
533         if (exynosOutputPort->bIsPBEnabled == OMX_FALSE) {
534             if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer) == OMX_ErrorNone)
535                 outputUseBuffer->dataValid = OMX_TRUE;
536         } else {
537 #ifdef USE_PB
538 #ifdef SLP_PLATFORM
539             if (Exynos_Shared_DataToPlatformBuffer(dstOutputData, outputUseBuffer, exynosOutputPort,exynosInputPort) == OMX_ErrorNone) {
540 #else
541             if (Exynos_Shared_DataToPlatformBuffer(dstOutputData, outputUseBuffer, exynosOutputPort) == OMX_ErrorNone) {
542 #endif
543                 outputUseBuffer->dataValid = OMX_TRUE;
544             } else {
545                 ret = OMX_FALSE;
546                 goto EXIT;
547             }
548 #else
549             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s Should not come here", __FUNCTION__);
550             ret = OMX_FALSE;
551             goto EXIT;
552 #endif
553         }
554     }
555
556     if (outputUseBuffer->dataValid == OMX_TRUE) {
557         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out timestamp after seeking %lld us (%.2f secs)",
558             dstOutputData->timeStamp, dstOutputData->timeStamp / 1E6);
559         if ((pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) &&
560             ((dstOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) {
561             if ((pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp) &&
562                 (pExynosComponent->checkTimeStamp.nStartFlags == dstOutputData->nFlags)){
563                 pExynosComponent->checkTimeStamp.startTimeStamp = -19761123;
564                 pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
565                 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
566                 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
567                 pExynosComponent->checkTimeStamp.bImmediateDisplay = OMX_FALSE; 
568             } else {
569                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "drop frame after seeking", pExynosComponent);
570                 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE)
571                     Exynos_OMX_FillThisBuffer(pOMXComponent, outputUseBuffer->bufferHeader);
572                 ret = OMX_TRUE;
573                 goto EXIT;
574             }
575         } else if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE)) {
576             ret = OMX_TRUE;
577             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "not set check timestame after seeking");
578             goto EXIT;
579         }
580
581         if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
582             OMX_U32 width = 0, height = 0;
583             int imageSize = 0;
584             void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer;
585
586             pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo;
587
588             width = pBufferInfo->imageWidth;
589             height = pBufferInfo->imageHeight;
590             imageSize = width * height;
591
592             if ((dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) &&
593                 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
594                 copySize = dstOutputData->remainDataLen;
595                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"copySize: %d", copySize);
596
597                 outputUseBuffer->dataLen += copySize;
598                 outputUseBuffer->remainDataLen += copySize;
599                 outputUseBuffer->nFlags = dstOutputData->nFlags;
600                 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
601
602                 if (outputUseBuffer->remainDataLen > 0) {
603                     ret = Exynos_CSC_OutputData(pOMXComponent, dstOutputData);
604                 } else {
605                     ret = OMX_TRUE;
606                 }
607
608                 if (ret == OMX_TRUE) {
609                     if ((outputUseBuffer->remainDataLen > 0) ||
610                         ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
611                         (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
612                         Exynos_OutputBufferReturn(pOMXComponent);
613                     }
614                 } else {
615                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "csc_convert Error");
616                     pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
617                                                             pExynosComponent->callbackData,
618                                                             OMX_EventError, OMX_ErrorUndefined, 0, NULL);
619                     ret = OMX_FALSE;
620                 }
621             } else if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
622                 outputUseBuffer->dataLen = 0;
623                 outputUseBuffer->remainDataLen = 0;
624                 outputUseBuffer->nFlags = dstOutputData->nFlags;
625                 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
626                 Exynos_OutputBufferReturn(pOMXComponent);
627             } else {
628 #ifdef SLP_PLATFORM
629                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is SCMN_IMGB type.");
630                 copySize = outputUseBuffer->allocSize - outputUseBuffer->dataLen;
631
632                 outputUseBuffer->dataLen += copySize;
633                 outputUseBuffer->remainDataLen += copySize;
634                 outputUseBuffer->nFlags = 0; /* need to check */
635                 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
636
637                 if (outputUseBuffer->remainDataLen > 0) {
638                     ret = Exynos_CSC_OutputData(pOMXComponent, dstOutputData);
639                 } else {
640                     ret = OMX_TRUE;
641                 }
642
643                 dstOutputData->remainDataLen -= copySize; /* need to check */
644                 dstOutputData->usedDataLen += copySize;
645
646                 Exynos_OutputBufferReturn(pOMXComponent);
647 #else
648                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than decoded data size Out Length");
649                 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
650                                                         pExynosComponent->callbackData,
651                                                         OMX_EventError, OMX_ErrorUndefined, 0, NULL);
652                 ret = OMX_FALSE;
653 #endif
654             }
655         } else if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
656             if ((outputUseBuffer->remainDataLen > 0) ||
657                 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
658                 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)))
659                 Exynos_OutputBufferReturn(pOMXComponent);
660         }
661     } else {
662         ret = OMX_FALSE;
663     }
664
665 EXIT:
666     FunctionOut();
667
668     return ret;
669 }
670
671 OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent)
672 {
673     OMX_ERRORTYPE          ret = OMX_ErrorNone;
674     OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
675     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
676     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
677     EXYNOS_OMX_BASEPORT      *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
678     EXYNOS_OMX_BASEPORT      *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
679     EXYNOS_OMX_DATABUFFER    *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
680     EXYNOS_OMX_DATA          *pSrcInputData = &exynosInputPort->processData;
681     OMX_BOOL               bCheckInputData = OMX_FALSE;
682     OMX_BOOL               bValidCodecData = OMX_FALSE;
683     OMX_BOOL               bCodecConfigured = OMX_FALSE;
684
685     FunctionIn();
686
687     while (!pVideoDec->bExitBufferProcessThread) {
688         Exynos_OSAL_SleepMillisec(0);
689         Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX);
690
691         while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) &&
692                (!pVideoDec->bExitBufferProcessThread)) {
693             Exynos_OSAL_SleepMillisec(0);
694
695             if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort)) ||
696                 ((exynosOutputPort->exceptionFlag == NEED_PORT_DISABLE) && (ret == OMX_ErrorInputDataDecodeYet)))
697                 break;
698             if (exynosInputPort->portState != OMX_StateIdle)
699                 break;
700
701             Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex);
702             if (ret != OMX_ErrorInputDataDecodeYet) {
703                 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
704                     OMX_PTR codecBuffer;
705
706                     if ((pVideoDec->exynos_process_codecConfigData) && !bCodecConfigured) {
707                         EXYNOS_OMX_DATABUFFER *inputUseBuffer = NULL;
708                         ret = Exynos_InputBufferGetQueue(pExynosComponent);
709
710                         inputUseBuffer = &(exynosInputPort->way.port2WayDataBuffer.inputDataBuffer);
711                         pVideoDec->exynos_process_codecConfigData(pOMXComponent, inputUseBuffer); /* SLP_PLATFORM */
712 //                        pVideoDec->exynos_process_codecConfigData(pOMXComponent, pSrcInputData);
713
714                         bCodecConfigured = OMX_TRUE;
715                     }
716
717                     if ((pSrcInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) || (pSrcInputData->pPrivate == NULL)) {
718                         Exynos_CodecBufferDeQueue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer);
719                         if (codecBuffer != NULL) {
720                             Exynos_Input_CodecBufferToData(pExynosComponent, codecBuffer, pSrcInputData);
721                         }
722                         Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
723                         break;
724                     }
725                 }
726
727                 if (srcInputUseBuffer->dataValid == OMX_TRUE) {
728                     bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData);
729                 } else {
730                     bCheckInputData = OMX_FALSE;
731                 }
732
733                 if ((bCheckInputData == OMX_FALSE) &&
734                     (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
735                     ret = Exynos_InputBufferGetQueue(pExynosComponent);
736                     Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
737                     break;
738                 }
739
740                 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) {
741                     Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
742                     break;
743                 }
744             }
745
746             ret = pVideoDec->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData);
747
748                if (ret == OMX_ErrorCorruptedFrame) {
749                 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
750                     OMX_PTR codecBuffer;
751                     codecBuffer = pSrcInputData->pPrivate;
752                     if (codecBuffer != NULL)
753                         Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
754                 }
755
756                 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
757                     Exynos_OMX_InputBufferReturn(pOMXComponent, pSrcInputData->bufferHeader);
758                 }
759             }
760
761             if (ret != OMX_ErrorInputDataDecodeYet) {
762                 Exynos_ResetCodecData(pSrcInputData);
763             }
764             Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
765             if (ret == OMX_ErrorCodecInit)
766                 pVideoDec->bExitBufferProcessThread = OMX_TRUE;
767         }
768     }
769
770 EXIT:
771
772     FunctionOut();
773
774     return ret;
775 }
776
777 OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent)
778 {
779     OMX_ERRORTYPE          ret = OMX_ErrorNone;
780     OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
781     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
782     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
783     EXYNOS_OMX_BASEPORT      *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
784     EXYNOS_OMX_DATABUFFER    *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer;
785     EXYNOS_OMX_DATA           srcOutputData;
786
787     FunctionIn();
788
789     while (!pVideoDec->bExitBufferProcessThread) {
790         Exynos_OSAL_SleepMillisec(0);
791
792         while (!pVideoDec->bExitBufferProcessThread) {
793             if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
794                 if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE)
795                     break;
796             }
797             Exynos_OSAL_SleepMillisec(0);
798
799             if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
800                 break;
801
802             Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex);
803             ret = pVideoDec->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData);
804
805             if (ret == OMX_ErrorNone) {
806                 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
807                     OMX_PTR codecBuffer;
808                     codecBuffer = srcOutputData.pPrivate;
809                     if (codecBuffer != NULL)
810                         Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
811                 }
812                 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
813                     Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer);
814                     Exynos_InputBufferReturn(pOMXComponent);
815                 }
816                 Exynos_ResetCodecData(&srcOutputData);
817             }
818             Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex);
819         }
820     }
821
822 EXIT:
823
824     FunctionOut();
825
826     return ret;
827 }
828
829 OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent)
830 {
831     OMX_ERRORTYPE          ret = OMX_ErrorNone;
832     OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
833     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
834     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
835     EXYNOS_OMX_BASEPORT      *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
836     EXYNOS_OMX_DATABUFFER    *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer;
837     EXYNOS_OMX_DATA           dstInputData;
838
839     FunctionIn();
840
841     while (!pVideoDec->bExitBufferProcessThread) {
842         Exynos_OSAL_SleepMillisec(0);
843
844         while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
845                (!pVideoDec->bExitBufferProcessThread)) {
846             Exynos_OSAL_SleepMillisec(0);
847
848             if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) ||
849                 (!CHECK_PORT_POPULATED(exynosOutputPort)))
850                 break;
851             if (exynosOutputPort->portState != OMX_StateIdle)
852                 break;
853
854             Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex);
855             if (ret != OMX_ErrorOutputBufferUseYet) {
856                 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
857                     OMX_PTR codecBuffer;
858                     ret = Exynos_CodecBufferDeQueue(pExynosComponent, OUTPUT_PORT_INDEX, &codecBuffer);
859                     if (ret != OMX_ErrorNone) {
860                         Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
861                         break;
862                     }
863                     Exynos_Output_CodecBufferToData(pExynosComponent, codecBuffer, &dstInputData);
864                 }
865
866                 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
867                     if ((dstInputUseBuffer->dataValid != OMX_TRUE) &&
868                         (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
869                         ret = Exynos_OutputBufferGetQueue(pExynosComponent);
870                         if (ret != OMX_ErrorNone) {
871                             Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
872                             break;
873                         }
874                         if (exynosOutputPort->bIsPBEnabled == OMX_FALSE) {
875                             Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, TWO_PLANE);
876                         } else {
877 #ifdef USE_PB
878                             ret = Exynos_Shared_PlatformBufferToData(dstInputUseBuffer, &dstInputData, exynosOutputPort, TWO_PLANE);
879 #endif
880                             if (ret != OMX_ErrorNone) {
881                                 dstInputUseBuffer->dataValid = OMX_FALSE;
882                                 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
883                                 break;
884                             }
885                         }
886                         Exynos_ResetDataBuffer(dstInputUseBuffer);
887                     }
888                 }
889
890                 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
891                     Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
892                     break;
893                 }
894             }
895
896             ret = pVideoDec->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData);
897             if (ret != OMX_ErrorOutputBufferUseYet) {
898                 Exynos_ResetCodecData(&dstInputData);
899             }
900             Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
901         }
902     }
903
904 EXIT:
905
906     FunctionOut();
907
908     return ret;
909 }
910
911 OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent)
912 {
913     OMX_ERRORTYPE          ret = OMX_ErrorNone;
914     OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
915     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
916     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
917     EXYNOS_OMX_BASEPORT      *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
918     EXYNOS_OMX_DATABUFFER    *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
919     EXYNOS_OMX_DATA          *pDstOutputData = &exynosOutputPort->processData;
920
921     FunctionIn();
922
923     while (!pVideoDec->bExitBufferProcessThread) {
924         Exynos_OSAL_SleepMillisec(0);
925         Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX);
926
927         while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
928                (!pVideoDec->bExitBufferProcessThread)) {
929             Exynos_OSAL_SleepMillisec(0);
930
931             if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))
932                 break;
933
934             Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex);
935             if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
936                 if ((dstOutputUseBuffer->dataValid != OMX_TRUE) &&
937                     (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
938                     ret = Exynos_OutputBufferGetQueue(pExynosComponent);
939                     if (ret != OMX_ErrorNone) {
940                         Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
941                         break;
942                     }
943                 }
944             }
945
946             if ((dstOutputUseBuffer->dataValid == OMX_TRUE) ||
947                 (exynosOutputPort->bufferProcessType & BUFFER_SHARE))
948                 ret = pVideoDec->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData);
949
950             if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) ||
951                 (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) {
952                 Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData);
953             }
954
955             if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
956                 OMX_PTR codecBuffer;
957                 codecBuffer = pDstOutputData->pPrivate;
958                 if (codecBuffer != NULL) {
959                     Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, codecBuffer);
960                     pDstOutputData->pPrivate = NULL;
961                 }
962             }
963
964             /* reset outputData */
965             Exynos_ResetCodecData(pDstOutputData);
966             Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
967         }
968     }
969
970 EXIT:
971
972     FunctionOut();
973
974     return ret;
975 }
976
977 static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData)
978 {
979     OMX_ERRORTYPE          ret = OMX_ErrorNone;
980     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
981     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
982     EXYNOS_OMX_MESSAGE       *message = NULL;
983
984     FunctionIn();
985
986     if (threadData == NULL) {
987         ret = OMX_ErrorBadParameter;
988         goto EXIT;
989     }
990     pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
991     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
992     if (ret != OMX_ErrorNone) {
993         goto EXIT;
994     }
995     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
996     Exynos_OMX_SrcInputBufferProcess(pOMXComponent);
997
998     Exynos_OSAL_ThreadExit(NULL);
999
1000 EXIT:
1001     FunctionOut();
1002
1003     return ret;
1004 }
1005
1006 static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData)
1007 {
1008     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1009     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1010     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1011     EXYNOS_OMX_MESSAGE       *message = NULL;
1012
1013     FunctionIn();
1014
1015     if (threadData == NULL) {
1016         ret = OMX_ErrorBadParameter;
1017         goto EXIT;
1018     }
1019     pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1020     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1021     if (ret != OMX_ErrorNone) {
1022         goto EXIT;
1023     }
1024     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1025     Exynos_OMX_SrcOutputBufferProcess(pOMXComponent);
1026
1027     Exynos_OSAL_ThreadExit(NULL);
1028
1029 EXIT:
1030     FunctionOut();
1031
1032     return ret;
1033 }
1034
1035 static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData)
1036 {
1037     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1038     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1039     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1040     EXYNOS_OMX_MESSAGE       *message = NULL;
1041
1042     FunctionIn();
1043
1044     if (threadData == NULL) {
1045         ret = OMX_ErrorBadParameter;
1046         goto EXIT;
1047     }
1048     pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1049     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1050     if (ret != OMX_ErrorNone) {
1051         goto EXIT;
1052     }
1053     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1054     Exynos_OMX_DstInputBufferProcess(pOMXComponent);
1055
1056     Exynos_OSAL_ThreadExit(NULL);
1057
1058 EXIT:
1059     FunctionOut();
1060
1061     return ret;
1062 }
1063
1064 static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData)
1065 {
1066     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1067     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1068     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1069     EXYNOS_OMX_MESSAGE       *message = NULL;
1070
1071     FunctionIn();
1072
1073     if (threadData == NULL) {
1074         ret = OMX_ErrorBadParameter;
1075         goto EXIT;
1076     }
1077     pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1078     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1079     if (ret != OMX_ErrorNone) {
1080         goto EXIT;
1081     }
1082     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1083     Exynos_OMX_DstOutputBufferProcess(pOMXComponent);
1084
1085     Exynos_OSAL_ThreadExit(NULL);
1086
1087 EXIT:
1088     FunctionOut();
1089
1090     return ret;
1091 }
1092
1093 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent)
1094 {
1095     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1096     OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1097     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1098     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1099
1100     FunctionIn();
1101
1102     pVideoDec->bExitBufferProcessThread = OMX_FALSE;
1103
1104     ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstOutputThread,
1105                  Exynos_OMX_DstOutputProcessThread,
1106                  pOMXComponent);
1107     if (ret == OMX_ErrorNone)
1108         ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcOutputThread,
1109                      Exynos_OMX_SrcOutputProcessThread,
1110                      pOMXComponent);
1111     if (ret == OMX_ErrorNone)
1112         ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstInputThread,
1113                      Exynos_OMX_DstInputProcessThread,
1114                      pOMXComponent);
1115     if (ret == OMX_ErrorNone)
1116         ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcInputThread,
1117                      Exynos_OMX_SrcInputProcessThread,
1118                      pOMXComponent);
1119
1120 EXIT:
1121     FunctionOut();
1122
1123     return ret;
1124 }
1125
1126 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent)
1127 {
1128     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1129     OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1130     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1131     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1132     OMX_S32                countValue = 0;
1133     unsigned int           i = 0;
1134
1135     FunctionIn();
1136
1137     pVideoDec->bExitBufferProcessThread = OMX_TRUE;
1138
1139     Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue);
1140     if (countValue == 0)
1141         Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID);
1142     Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue);
1143     if (countValue == 0)
1144         Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID);
1145     Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1146     Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcInputThread);
1147     pVideoDec->hSrcInputThread = NULL;
1148
1149     Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue);
1150     if (countValue == 0)
1151         Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID);
1152     Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue);
1153     if (countValue == 0)
1154         Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID);
1155     Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1156     Exynos_OSAL_ThreadTerminate(pVideoDec->hDstInputThread);
1157     pVideoDec->hDstInputThread = NULL;
1158
1159     pVideoDec->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX);
1160     pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1161     Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1162     Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcOutputThread);
1163     pVideoDec->hSrcOutputThread = NULL;
1164
1165     pVideoDec->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX);
1166     pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1167     Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1168     Exynos_OSAL_ThreadTerminate(pVideoDec->hDstOutputThread);
1169     pVideoDec->hDstOutputThread = NULL;
1170
1171 EXIT:
1172     FunctionOut();
1173
1174     return ret;
1175 }
1176
1177 OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent)
1178 {
1179     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1180     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1181     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1182     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
1183     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1184
1185     FunctionIn();
1186
1187     if (hComponent == NULL) {
1188         ret = OMX_ErrorBadParameter;
1189         goto EXIT;
1190     }
1191     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1192     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1193     if (ret != OMX_ErrorNone) {
1194         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1195         goto EXIT;
1196     }
1197
1198     ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
1199     if (ret != OMX_ErrorNone) {
1200         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1201         goto EXIT;
1202     }
1203
1204     ret = Exynos_OMX_Port_Constructor(pOMXComponent);
1205     if (ret != OMX_ErrorNone) {
1206         Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1207         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1208         goto EXIT;
1209     }
1210
1211     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1212
1213     pVideoDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
1214     if (pVideoDec == NULL) {
1215         Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1216         ret = OMX_ErrorInsufficientResources;
1217         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1218         goto EXIT;
1219     }
1220
1221     Exynos_OSAL_Memset(pVideoDec, 0, sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
1222     pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec;
1223
1224     pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1225     pExynosComponent->bMultiThreadProcess = OMX_TRUE;
1226
1227     /* Input port */
1228     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1229     pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
1230     pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM;
1231     pExynosPort->portDefinition.nBufferSize = 0;
1232     pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1233
1234     pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1235     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1236     pExynosPort->portDefinition.format.video.pNativeRender = 0;
1237     pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1238     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1239
1240     pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1241     pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1242     pExynosPort->portDefinition.format.video.nStride = 0;
1243     pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1244     pExynosPort->portDefinition.format.video.nBitrate = 64000;
1245     pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1246     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1247     pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1248
1249     /* Output port */
1250     pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1251     pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
1252     pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
1253     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
1254     pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1255
1256     pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1257     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1258     pExynosPort->portDefinition.format.video.pNativeRender = 0;
1259     pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1260     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1261
1262     pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1263     pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1264     pExynosPort->portDefinition.format.video.nStride = 0;
1265     pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1266     pExynosPort->portDefinition.format.video.nBitrate = 64000;
1267     pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1268     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1269     pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1270
1271     pExynosPort->processData.extInfo = (OMX_PTR)Exynos_OSAL_Malloc(sizeof(DECODE_CODEC_EXTRA_BUFFERINFO));
1272
1273     pOMXComponent->UseBuffer              = &Exynos_OMX_UseBuffer;
1274     pOMXComponent->AllocateBuffer         = &Exynos_OMX_AllocateBuffer;
1275     pOMXComponent->FreeBuffer             = &Exynos_OMX_FreeBuffer;
1276     pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest;
1277
1278     pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer;
1279     pExynosComponent->exynos_FreeTunnelBuffer     = &Exynos_OMX_FreeTunnelBuffer;
1280     pExynosComponent->exynos_BufferProcessCreate    = &Exynos_OMX_BufferProcess_Create;
1281     pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate;
1282     pExynosComponent->exynos_BufferFlush          = &Exynos_OMX_BufferFlush;
1283
1284 EXIT:
1285     FunctionOut();
1286
1287     return ret;
1288 }
1289
1290 OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent)
1291 {
1292     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1293     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1294     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1295     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
1296     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1297     int                    i = 0;
1298
1299     FunctionIn();
1300
1301     if (hComponent == NULL) {
1302         ret = OMX_ErrorBadParameter;
1303         goto EXIT;
1304     }
1305     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1306     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1307     if (ret != OMX_ErrorNone) {
1308         goto EXIT;
1309     }
1310
1311     if (pOMXComponent->pComponentPrivate == NULL) {
1312         ret = OMX_ErrorBadParameter;
1313         goto EXIT;
1314     }
1315     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1316
1317     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1318
1319     Exynos_OSAL_Free(pVideoDec);
1320     pExynosComponent->hComponentHandle = pVideoDec = NULL;
1321
1322     pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1323     if (pExynosPort->processData.extInfo != NULL) {
1324         Exynos_OSAL_Free(pExynosPort->processData.extInfo);
1325         pExynosPort->processData.extInfo = NULL;
1326     }
1327
1328     for(i = 0; i < ALL_PORT_NUM; i++) {
1329         pExynosPort = &pExynosComponent->pExynosPort[i];
1330         Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType);
1331         pExynosPort->portDefinition.format.video.cMIMEType = NULL;
1332     }
1333
1334     ret = Exynos_OMX_Port_Destructor(pOMXComponent);
1335
1336     ret = Exynos_OMX_BaseComponent_Destructor(hComponent);
1337
1338 EXIT:
1339     FunctionOut();
1340
1341     return ret;
1342 }