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