fix build warning
[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((int)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 //TIZEN_FEATURE_E3250
255
256     FunctionIn();
257
258     OMX_U32 width = 0, height = 0;
259
260 #ifndef TIZEN_FEATURE_E3250
261     int imageSize = 0;
262     OMX_COLOR_FORMATTYPE colorFormat;
263 #endif
264
265     void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer;
266 #ifndef TIZEN_FEATURE_E3250
267     void *pSrcBuf[MAX_BUFFER_PLANE] = {NULL, };
268     void *pYUVBuf[MAX_BUFFER_PLANE] = {NULL, };
269
270     CSC_ERRORCODE cscRet = CSC_ErrorNone;
271 #endif
272
273     pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo;
274
275     width = pBufferInfo->imageWidth;
276     height = pBufferInfo->imageHeight;
277 #ifndef TIZEN_FEATURE_E3250
278     imageSize = width * height;
279     colorFormat = pBufferInfo->ColorFormat;
280 #endif
281
282 #ifdef TIZEN_FEATURE_E3250
283     pSlpOutBuf = (MMVideoBuffer *)pOutputBuf;
284     pSlpOutBuf->width[0] = width;
285     pSlpOutBuf->width[1] = width;
286     pSlpOutBuf->height[0] = height;
287     pSlpOutBuf->height[1] = height/2;
288     pSlpOutBuf->stride_width[0] = width; /* need to check. stride */
289     pSlpOutBuf->stride_width[1] = width;
290     pSlpOutBuf->stride_height[0] = height; /* need to check. elevation */
291     pSlpOutBuf->stride_height[1] = height/2;
292
293     if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
294         pSlpOutBuf->data[0] = 0;
295         pSlpOutBuf->data[1] = 0;
296     } else {
297         pSlpOutBuf->data[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0];
298         pSlpOutBuf->data[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1];
299     }
300     pSlpOutBuf->data[2] = 0; /* omx do not use this plane */
301
302
303     pSlpOutBuf->handle.dmabuf_fd[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0];
304     pSlpOutBuf->handle.dmabuf_fd[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1];
305     pSlpOutBuf->handle.dmabuf_fd[2] = 0; /* omx do not use this plane */
306
307     pSlpOutBuf->handle.bo[0] = dstOutputData->buffer.multiPlaneBuffer.tbm_bo[0];
308     pSlpOutBuf->handle.bo[1] = dstOutputData->buffer.multiPlaneBuffer.tbm_bo[1];
309     pSlpOutBuf->handle.bo[2] = NULL;
310
311     //pSlpOutBuf->type = MM_VIDEO_BUFFER_TYPE_DMABUF_FD;
312     dstOutputData->dataLen = sizeof(MMVideoBuffer);
313
314     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: using fd instead of csc", __FUNCTION__);
315     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fd (%d, %d, %d) received from MFC", pSlpOutBuf->handle.dmabuf_fd[0], pSlpOutBuf->handle.dmabuf_fd[1],
316                     pSlpOutBuf->handle.dmabuf_fd[2]);
317
318     ret = OMX_TRUE;
319 #else //TIZEN_FEATURE_E3250
320
321     pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0];
322     pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1];
323     pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[2];
324
325     pYUVBuf[0]  = (unsigned char *)pOutputBuf;
326     pYUVBuf[1]  = (unsigned char *)pOutputBuf + imageSize;
327     pYUVBuf[2]  = (unsigned char *)pOutputBuf + imageSize + imageSize / 4;
328
329 #ifdef USE_DMA_BUF
330     CSC_METHOD csc_method = CSC_METHOD_SW;
331     csc_get_method(pVideoDec->csc_handle, &csc_method);
332     if (csc_method == CSC_METHOD_HW) {
333         pSrcBuf[0] = (unsigned char *)(&dstOutputData->buffer.multiPlaneBuffer.fd[0]);
334         pSrcBuf[1] = (unsigned char *)(&dstOutputData->buffer.multiPlaneBuffer.fd[1]);
335         pSrcBuf[2] = (unsigned char *)(&dstOutputData->buffer.multiPlaneBuffer.fd[2]);
336     }
337 #endif //USE_DMA_BUF
338
339 #ifdef USE_PB
340     if (exynosOutputPort->bIsPBEnabled == OMX_TRUE) {
341         ExynosVideoPlane planes[MAX_BUFFER_PLANE];
342         OMX_U32 stride = 0;
343         Exynos_OSAL_LockPB(pOutputBuf, width, height, exynosOutputPort->portDefinition.format.video.eColorFormat, &stride, planes);
344         width = stride;
345         outputUseBuffer->dataLen = sizeof(void *);
346
347         pYUVBuf[0]  = (unsigned char *)planes[0].addr;
348         pYUVBuf[1]  = (unsigned char *)planes[1].addr;
349         pYUVBuf[2]  = (unsigned char *)planes[2].addr;
350 #ifdef USE_DMA_BUF
351         if (csc_method == CSC_METHOD_HW) {
352             pYUVBuf[0]  = (unsigned char *)planes[0].fd;
353             pYUVBuf[1]  = (unsigned char *)planes[1].fd;
354             pYUVBuf[2]  = (unsigned char *)planes[2].fd;
355         }
356 #endif //USE_DMA_BUF
357     }
358 #endif //USE_PB
359 #ifdef USE_DMA_BUF
360     if ((exynosOutputPort->bIsPBEnabled == OMX_FALSE) &&
361         (csc_method == CSC_METHOD_HW)) {
362         pYUVBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, (OMX_PTR)pOutputBuf);
363         pYUVBuf[1] = NULL;
364         pYUVBuf[2] = NULL;
365     }
366 #endif //USE_DMA_BUF
367
368     unsigned int cacheable = 1;
369     if (pVideoDec->csc_set_format == OMX_FALSE) {
370         csc_set_src_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(colorFormat), /* color_format */
379             cacheable);             /* cacheable */
380         csc_set_dst_format(
381             pVideoDec->csc_handle,  /* handle */
382             width,           /* width */
383             height,           /* height */
384             0,                /* crop_left */
385             0,                /* crop_right */
386             width,           /* crop_width */
387             height,           /* crop_height */
388             omx_2_hal_pixel_format(exynosOutputPort->portDefinition.format.video.eColorFormat), /* color_format */
389             cacheable);             /* cacheable */
390         pVideoDec->csc_set_format = OMX_TRUE;
391     }
392     csc_set_src_buffer(
393         pVideoDec->csc_handle,  /* handle */
394         pSrcBuf[0],             /* y addr */
395         pSrcBuf[1],             /* u addr or uv addr */
396         pSrcBuf[2],             /* v addr or none */
397         0);                     /* ion fd */
398     csc_set_dst_buffer(
399         pVideoDec->csc_handle,  /* handle */
400         pYUVBuf[0],             /* y addr */
401         pYUVBuf[1],             /* u addr or uv addr */
402         pYUVBuf[2],             /* v addr or none */
403         0);                     /* ion fd */
404     cscRet = csc_convert(pVideoDec->csc_handle);
405     if (cscRet != CSC_ErrorNone)
406         ret = OMX_FALSE;
407     else
408         ret = OMX_TRUE;
409 #endif //TIZEN_FEATURE_E3250
410 #ifdef USE_PB
411     if (exynosOutputPort->bIsPBEnabled == OMX_TRUE) {
412 #ifdef TIZEN_FEATURE_E3250
413         Exynos_OSAL_UnlockPB(pOutputBuf, dstOutputData, exynosOutputPort, exynosInputPort);
414 #else //TIZEN_FEATURE_E3250
415         Exynos_OSAL_UnlockPB(pOutputBuf, dstOutputData);
416 #endif //TIZEN_FEATURE_E3250
417     }
418 #endif //USE_PB
419
420 //EXIT:
421     FunctionOut();
422
423     return ret;
424 }
425
426 OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData)
427 {
428     OMX_BOOL               ret = OMX_FALSE;
429     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
430     EXYNOS_OMX_BASEPORT      *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
431     EXYNOS_OMX_DATABUFFER    *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
432     OMX_U32                copySize = 0;
433     OMX_BYTE               checkInputStream = NULL;
434     OMX_U32                checkInputStreamLen = 0;
435
436     FunctionIn();
437
438     if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
439         if ((srcInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) ||
440             (srcInputData->pPrivate == NULL)) {
441             ret = OMX_FALSE;
442             goto EXIT;
443         }
444     }
445
446     if (inputUseBuffer->dataValid == OMX_TRUE) {
447         if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
448             Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE);
449
450 #ifndef TIZEN_FEATURE_E3250
451             EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
452             if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
453                 OMX_PTR dataBuffer = NULL;
454
455                 dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory,
456                                                             srcInputData->buffer.singlePlaneBuffer.dataBuffer);
457                 if (dataBuffer == NULL) {
458                     ret = OMX_FALSE;
459                     goto EXIT;
460                 }
461
462                 srcInputData->buffer.singlePlaneBuffer.dataBuffer = dataBuffer;
463             }
464 #endif
465             /* reset dataBuffer */
466             Exynos_ResetDataBuffer(inputUseBuffer);
467         } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
468             checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
469             checkInputStreamLen = inputUseBuffer->remainDataLen;
470
471             pExynosComponent->bUseFlagEOF = OMX_TRUE;
472
473             copySize = checkInputStreamLen;
474             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE");
475
476             if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) {
477                 if (copySize > 0) {
478                     Exynos_OSAL_Memcpy(srcInputData->buffer.singlePlaneBuffer.dataBuffer + srcInputData->dataLen,
479                                        checkInputStream, copySize);
480                 }
481
482                 inputUseBuffer->dataLen -= copySize;
483                 inputUseBuffer->remainDataLen -= copySize;
484                 inputUseBuffer->usedDataLen += copySize;
485
486                 srcInputData->dataLen += copySize;
487                 srcInputData->remainDataLen += copySize;
488
489                 srcInputData->timeStamp = inputUseBuffer->timeStamp;
490                 srcInputData->nFlags = inputUseBuffer->nFlags;
491                 srcInputData->bufferHeader = inputUseBuffer->bufferHeader;
492             } else {
493                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length");
494                 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
495                                                         pExynosComponent->callbackData,
496                                                         OMX_EventError, OMX_ErrorUndefined, 0, NULL);
497                 ret = OMX_FALSE;
498             }
499
500             Exynos_InputBufferReturn(pOMXComponent);
501         }
502
503         if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
504             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE");
505             srcInputData->dataLen = 0;
506             srcInputData->remainDataLen = 0;
507             pExynosComponent->bSaveFlagEOS = OMX_TRUE;
508         }
509
510         if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
511             pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
512             pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp;
513             pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags;
514             pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
515             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)",
516                             srcInputData->timeStamp, srcInputData->timeStamp / 1E6);
517         }
518
519         ret = OMX_TRUE;
520     }
521
522 EXIT:
523
524     FunctionOut();
525
526     return ret;
527 }
528
529 OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
530 {
531     OMX_BOOL                   ret = OMX_FALSE;
532     EXYNOS_OMX_BASECOMPONENT  *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
533     EXYNOS_OMX_BASEPORT       *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
534     EXYNOS_OMX_BASEPORT       *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
535     EXYNOS_OMX_DATABUFFER     *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
536     OMX_U32                    copySize = 0;
537
538     FunctionIn();
539
540     if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
541         if (exynosOutputPort->bIsPBEnabled == OMX_FALSE) {
542             if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer) == OMX_ErrorNone)
543                 outputUseBuffer->dataValid = OMX_TRUE;
544         } else {
545 #ifdef USE_PB
546 #ifdef TIZEN_FEATURE_E3250
547             if (Exynos_Shared_DataToPlatformBuffer(dstOutputData, outputUseBuffer, exynosOutputPort,exynosInputPort) == OMX_ErrorNone) {
548 #else
549             if (Exynos_Shared_DataToPlatformBuffer(dstOutputData, outputUseBuffer, exynosOutputPort) == OMX_ErrorNone) {
550 #endif
551                 outputUseBuffer->dataValid = OMX_TRUE;
552             } else {
553                 ret = OMX_FALSE;
554                 goto EXIT;
555             }
556 #else
557             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s Should not come here", __FUNCTION__);
558             ret = OMX_FALSE;
559             goto EXIT;
560 #endif
561         }
562     }
563
564     if (outputUseBuffer->dataValid == OMX_TRUE) {
565         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out timestamp after seeking %lld us (%.2f secs)",
566             dstOutputData->timeStamp, dstOutputData->timeStamp / 1E6);
567         if ((pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) &&
568             ((dstOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) {
569             if ((pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp) &&
570                 (pExynosComponent->checkTimeStamp.nStartFlags == dstOutputData->nFlags)){
571                 pExynosComponent->checkTimeStamp.startTimeStamp = -19761123;
572                 pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
573                 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
574                 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
575                 pExynosComponent->checkTimeStamp.bImmediateDisplay = OMX_FALSE;
576             } else {
577                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "drop frame after seeking", pExynosComponent);
578                 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE)
579                     Exynos_OMX_FillThisBuffer(pOMXComponent, outputUseBuffer->bufferHeader);
580                 ret = OMX_TRUE;
581                 goto EXIT;
582             }
583         } else if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE)) {
584             ret = OMX_TRUE;
585             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "not set check timestame after seeking");
586             goto EXIT;
587         }
588
589         if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
590             //void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer;
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 TIZEN_FEATURE_E3250
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               bCodecConfigured = OMX_FALSE;
683
684     FunctionIn();
685
686     while (!pVideoDec->bExitBufferProcessThread) {
687         Exynos_OSAL_SleepMillisec(0);
688         Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX);
689
690         while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) &&
691                (!pVideoDec->bExitBufferProcessThread)) {
692             Exynos_OSAL_SleepMillisec(0);
693
694             if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort)) ||
695                 ((exynosOutputPort->exceptionFlag == NEED_PORT_DISABLE) && (ret == (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet)))
696                 break;
697             if (exynosInputPort->portState != OMX_StateIdle)
698                 break;
699
700             Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex);
701             if (ret != (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet) {
702                 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
703                     OMX_PTR codecBuffer;
704
705                     if ((pVideoDec->exynos_process_codecConfigData) && !bCodecConfigured) {
706                         EXYNOS_OMX_DATABUFFER *inputUseBuffer = NULL;
707                         ret = Exynos_InputBufferGetQueue(pExynosComponent);
708
709                         inputUseBuffer = &(exynosInputPort->way.port2WayDataBuffer.inputDataBuffer);
710                         pVideoDec->exynos_process_codecConfigData(pOMXComponent, inputUseBuffer); /* TIZEN_FEATURE_E3250 */
711 //                        pVideoDec->exynos_process_codecConfigData(pOMXComponent, pSrcInputData);
712
713                         bCodecConfigured = OMX_TRUE;
714                     }
715
716                     if ((pSrcInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) || (pSrcInputData->pPrivate == NULL)) {
717                         Exynos_CodecBufferDeQueue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer);
718                         if (codecBuffer != NULL) {
719                             Exynos_Input_CodecBufferToData(pExynosComponent, codecBuffer, pSrcInputData);
720                         }
721                         Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
722                         break;
723                     }
724                 }
725
726                 if (srcInputUseBuffer->dataValid == OMX_TRUE) {
727                     bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData);
728                 } else {
729                     bCheckInputData = OMX_FALSE;
730                 }
731
732                 if ((bCheckInputData == OMX_FALSE) &&
733                     (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
734                     ret = Exynos_InputBufferGetQueue(pExynosComponent);
735                     Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
736                     break;
737                 }
738
739                 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) {
740                     Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
741                     break;
742                 }
743             }
744
745             ret = pVideoDec->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData);
746
747                if (ret == (OMX_ERRORTYPE)OMX_ErrorCorruptedFrame) {
748                 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
749                     OMX_PTR codecBuffer;
750                     codecBuffer = pSrcInputData->pPrivate;
751                     if (codecBuffer != NULL)
752                         Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
753                 }
754
755                 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
756                     Exynos_OMX_InputBufferReturn(pOMXComponent, pSrcInputData->bufferHeader);
757                 }
758             }
759
760             if (ret != (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet) {
761                 Exynos_ResetCodecData(pSrcInputData);
762             }
763             Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
764             if (ret == (OMX_ERRORTYPE)OMX_ErrorCodecInit)
765                 pVideoDec->bExitBufferProcessThread = OMX_TRUE;
766         }
767     }
768
769     FunctionOut();
770
771     return ret;
772 }
773
774 OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent)
775 {
776     OMX_ERRORTYPE          ret = OMX_ErrorNone;
777     OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
778     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
779     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
780     EXYNOS_OMX_BASEPORT      *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
781     EXYNOS_OMX_DATABUFFER    *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer;
782     EXYNOS_OMX_DATA           srcOutputData;
783
784     FunctionIn();
785
786     while (!pVideoDec->bExitBufferProcessThread) {
787         Exynos_OSAL_SleepMillisec(0);
788
789         while (!pVideoDec->bExitBufferProcessThread) {
790             if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
791                 if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE)
792                     break;
793             }
794             Exynos_OSAL_SleepMillisec(0);
795
796             if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
797                 break;
798
799             Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex);
800             ret = pVideoDec->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData);
801
802             if (ret == OMX_ErrorNone) {
803                 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
804                     OMX_PTR codecBuffer;
805                     codecBuffer = srcOutputData.pPrivate;
806                     if (codecBuffer != NULL)
807                         Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
808                 }
809                 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
810                     Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer);
811                     Exynos_InputBufferReturn(pOMXComponent);
812                 }
813                 Exynos_ResetCodecData(&srcOutputData);
814             }
815             Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex);
816         }
817     }
818
819     FunctionOut();
820
821     return ret;
822 }
823
824 OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent)
825 {
826     OMX_ERRORTYPE          ret = OMX_ErrorNone;
827     OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
828     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
829     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
830     EXYNOS_OMX_BASEPORT      *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
831     EXYNOS_OMX_DATABUFFER    *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer;
832     EXYNOS_OMX_DATA           dstInputData;
833
834     FunctionIn();
835
836     while (!pVideoDec->bExitBufferProcessThread) {
837         Exynos_OSAL_SleepMillisec(0);
838
839         while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
840                (!pVideoDec->bExitBufferProcessThread)) {
841             Exynos_OSAL_SleepMillisec(0);
842
843             if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) ||
844                 (!CHECK_PORT_POPULATED(exynosOutputPort)))
845                 break;
846             if (exynosOutputPort->portState != OMX_StateIdle)
847                 break;
848
849             Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex);
850             if (ret != (OMX_ERRORTYPE)OMX_ErrorOutputBufferUseYet) {
851                 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
852                     OMX_PTR codecBuffer;
853                     ret = Exynos_CodecBufferDeQueue(pExynosComponent, OUTPUT_PORT_INDEX, &codecBuffer);
854                     if (ret != OMX_ErrorNone) {
855                         Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
856                         break;
857                     }
858                     Exynos_Output_CodecBufferToData(pExynosComponent, codecBuffer, &dstInputData);
859                 }
860
861                 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
862                     if ((dstInputUseBuffer->dataValid != OMX_TRUE) &&
863                         (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
864                         ret = Exynos_OutputBufferGetQueue(pExynosComponent);
865                         if (ret != OMX_ErrorNone) {
866                             Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
867                             break;
868                         }
869                         if (exynosOutputPort->bIsPBEnabled == OMX_FALSE) {
870                             Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, TWO_PLANE);
871                         } else {
872 #ifdef USE_PB
873                             ret = Exynos_Shared_PlatformBufferToData(dstInputUseBuffer, &dstInputData, exynosOutputPort, TWO_PLANE);
874 #endif
875                             if (ret != OMX_ErrorNone) {
876                                 dstInputUseBuffer->dataValid = OMX_FALSE;
877                                 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
878                                 break;
879                             }
880                         }
881                         Exynos_ResetDataBuffer(dstInputUseBuffer);
882                     }
883                 }
884
885                 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
886                     Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
887                     break;
888                 }
889             }
890
891             ret = pVideoDec->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData);
892             if (ret != (OMX_ERRORTYPE)OMX_ErrorOutputBufferUseYet) {
893                 Exynos_ResetCodecData(&dstInputData);
894             }
895             Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
896         }
897     }
898
899     FunctionOut();
900
901     return ret;
902 }
903
904 OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent)
905 {
906     OMX_ERRORTYPE          ret = OMX_ErrorNone;
907     OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
908     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
909     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
910     EXYNOS_OMX_BASEPORT      *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
911     EXYNOS_OMX_DATABUFFER    *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
912     EXYNOS_OMX_DATA          *pDstOutputData = &exynosOutputPort->processData;
913
914     FunctionIn();
915
916     while (!pVideoDec->bExitBufferProcessThread) {
917         Exynos_OSAL_SleepMillisec(0);
918         Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX);
919
920         while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
921                (!pVideoDec->bExitBufferProcessThread)) {
922             Exynos_OSAL_SleepMillisec(0);
923
924             if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))
925                 break;
926
927             Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex);
928             if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
929                 if ((dstOutputUseBuffer->dataValid != OMX_TRUE) &&
930                     (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
931                     ret = Exynos_OutputBufferGetQueue(pExynosComponent);
932                     if (ret != OMX_ErrorNone) {
933                         Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
934                         break;
935                     }
936                 }
937             }
938
939             if ((dstOutputUseBuffer->dataValid == OMX_TRUE) ||
940                 (exynosOutputPort->bufferProcessType & BUFFER_SHARE))
941                 ret = pVideoDec->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData);
942
943             if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) ||
944                 (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) {
945                 Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData);
946             }
947
948             if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
949                 OMX_PTR codecBuffer;
950                 codecBuffer = pDstOutputData->pPrivate;
951                 if (codecBuffer != NULL) {
952                     Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, codecBuffer);
953                     pDstOutputData->pPrivate = NULL;
954                 }
955             }
956
957             /* reset outputData */
958             Exynos_ResetCodecData(pDstOutputData);
959             Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
960         }
961     }
962
963     FunctionOut();
964
965     return ret;
966 }
967
968 static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData)
969 {
970     OMX_ERRORTYPE          ret = OMX_ErrorNone;
971     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
972
973     FunctionIn();
974
975     if (threadData == NULL) {
976         ret = OMX_ErrorBadParameter;
977         goto EXIT;
978     }
979     pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
980     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
981     if (ret != OMX_ErrorNone) {
982         goto EXIT;
983     }
984     Exynos_OMX_SrcInputBufferProcess(pOMXComponent);
985
986     Exynos_OSAL_ThreadExit(NULL);
987
988 EXIT:
989     FunctionOut();
990
991     return ret;
992 }
993
994 static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData)
995 {
996     OMX_ERRORTYPE          ret = OMX_ErrorNone;
997     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
998
999     FunctionIn();
1000
1001     if (threadData == NULL) {
1002         ret = OMX_ErrorBadParameter;
1003         goto EXIT;
1004     }
1005     pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1006     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1007     if (ret != OMX_ErrorNone) {
1008         goto EXIT;
1009     }
1010     Exynos_OMX_SrcOutputBufferProcess(pOMXComponent);
1011
1012     Exynos_OSAL_ThreadExit(NULL);
1013
1014 EXIT:
1015     FunctionOut();
1016
1017     return ret;
1018 }
1019
1020 static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData)
1021 {
1022     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1023     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1024
1025     FunctionIn();
1026
1027     if (threadData == NULL) {
1028         ret = OMX_ErrorBadParameter;
1029         goto EXIT;
1030     }
1031     pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1032     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1033     if (ret != OMX_ErrorNone) {
1034         goto EXIT;
1035     }
1036     Exynos_OMX_DstInputBufferProcess(pOMXComponent);
1037
1038     Exynos_OSAL_ThreadExit(NULL);
1039
1040 EXIT:
1041     FunctionOut();
1042
1043     return ret;
1044 }
1045
1046 static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData)
1047 {
1048     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1049     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1050
1051     FunctionIn();
1052
1053     if (threadData == NULL) {
1054         ret = OMX_ErrorBadParameter;
1055         goto EXIT;
1056     }
1057     pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1058     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1059     if (ret != OMX_ErrorNone) {
1060         goto EXIT;
1061     }
1062     Exynos_OMX_DstOutputBufferProcess(pOMXComponent);
1063
1064     Exynos_OSAL_ThreadExit(NULL);
1065
1066 EXIT:
1067     FunctionOut();
1068
1069     return ret;
1070 }
1071
1072 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent)
1073 {
1074     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1075     OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1076     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1077     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1078
1079     FunctionIn();
1080
1081     pVideoDec->bExitBufferProcessThread = OMX_FALSE;
1082
1083     ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstOutputThread,
1084                  Exynos_OMX_DstOutputProcessThread,
1085                  pOMXComponent);
1086     if (ret == OMX_ErrorNone)
1087         ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcOutputThread,
1088                      Exynos_OMX_SrcOutputProcessThread,
1089                      pOMXComponent);
1090     if (ret == OMX_ErrorNone)
1091         ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstInputThread,
1092                      Exynos_OMX_DstInputProcessThread,
1093                      pOMXComponent);
1094     if (ret == OMX_ErrorNone)
1095         ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcInputThread,
1096                      Exynos_OMX_SrcInputProcessThread,
1097                      pOMXComponent);
1098
1099     FunctionOut();
1100
1101     return ret;
1102 }
1103
1104 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent)
1105 {
1106     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1107     OMX_COMPONENTTYPE     *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1108     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1109     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1110     OMX_S32                countValue = 0;
1111
1112     FunctionIn();
1113
1114     pVideoDec->bExitBufferProcessThread = OMX_TRUE;
1115
1116     Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue);
1117     if (countValue == 0)
1118         Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID);
1119     Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue);
1120     if (countValue == 0)
1121         Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID);
1122     Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1123     Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcInputThread);
1124     pVideoDec->hSrcInputThread = NULL;
1125
1126     Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue);
1127     if (countValue == 0)
1128         Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID);
1129     Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue);
1130     if (countValue == 0)
1131         Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID);
1132     Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1133     Exynos_OSAL_ThreadTerminate(pVideoDec->hDstInputThread);
1134     pVideoDec->hDstInputThread = NULL;
1135
1136     pVideoDec->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX);
1137     pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1138     Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1139     Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcOutputThread);
1140     pVideoDec->hSrcOutputThread = NULL;
1141
1142     pVideoDec->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX);
1143     pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1144     Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1145     Exynos_OSAL_ThreadTerminate(pVideoDec->hDstOutputThread);
1146     pVideoDec->hDstOutputThread = NULL;
1147
1148     FunctionOut();
1149
1150     return ret;
1151 }
1152
1153 OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent)
1154 {
1155     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1156     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1157     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1158     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
1159     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1160
1161     FunctionIn();
1162
1163     if (hComponent == NULL) {
1164         ret = OMX_ErrorBadParameter;
1165         goto EXIT;
1166     }
1167     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1168     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1169     if (ret != OMX_ErrorNone) {
1170         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1171         goto EXIT;
1172     }
1173
1174     ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
1175     if (ret != OMX_ErrorNone) {
1176         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1177         goto EXIT;
1178     }
1179
1180     ret = Exynos_OMX_Port_Constructor(pOMXComponent);
1181     if (ret != OMX_ErrorNone) {
1182         Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1183         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1184         goto EXIT;
1185     }
1186
1187     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1188
1189     pVideoDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
1190     if (pVideoDec == NULL) {
1191         Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1192         ret = OMX_ErrorInsufficientResources;
1193         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1194         goto EXIT;
1195     }
1196
1197     Exynos_OSAL_Memset(pVideoDec, 0, sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
1198     pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec;
1199
1200     pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1201     pExynosComponent->bMultiThreadProcess = OMX_TRUE;
1202
1203     /* Input port */
1204     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1205     pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
1206     pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM;
1207     pExynosPort->portDefinition.nBufferSize = 0;
1208     pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1209
1210     pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1211     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1212     pExynosPort->portDefinition.format.video.pNativeRender = 0;
1213     pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1214     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1215
1216     pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1217     pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1218     pExynosPort->portDefinition.format.video.nStride = 0;
1219     pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1220     pExynosPort->portDefinition.format.video.nBitrate = 64000;
1221     pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1222     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1223     pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1224
1225     /* Output port */
1226     pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1227     pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
1228     pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
1229     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
1230     pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1231
1232     pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1233     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1234     pExynosPort->portDefinition.format.video.pNativeRender = 0;
1235     pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1236     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1237
1238     pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1239     pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1240     pExynosPort->portDefinition.format.video.nStride = 0;
1241     pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1242     pExynosPort->portDefinition.format.video.nBitrate = 64000;
1243     pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1244     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1245     pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1246
1247     pExynosPort->processData.extInfo = (OMX_PTR)Exynos_OSAL_Malloc(sizeof(DECODE_CODEC_EXTRA_BUFFERINFO));
1248
1249     pOMXComponent->UseBuffer              = &Exynos_OMX_UseBuffer;
1250     pOMXComponent->AllocateBuffer         = &Exynos_OMX_AllocateBuffer;
1251     pOMXComponent->FreeBuffer             = &Exynos_OMX_FreeBuffer;
1252     pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest;
1253
1254     pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer;
1255     pExynosComponent->exynos_FreeTunnelBuffer     = &Exynos_OMX_FreeTunnelBuffer;
1256     pExynosComponent->exynos_BufferProcessCreate    = &Exynos_OMX_BufferProcess_Create;
1257     pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate;
1258     pExynosComponent->exynos_BufferFlush          = &Exynos_OMX_BufferFlush;
1259
1260 EXIT:
1261     FunctionOut();
1262
1263     return ret;
1264 }
1265
1266 OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent)
1267 {
1268     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1269     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1270     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1271     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
1272     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1273     int                    i = 0;
1274
1275     FunctionIn();
1276
1277     if (hComponent == NULL) {
1278         ret = OMX_ErrorBadParameter;
1279         goto EXIT;
1280     }
1281     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1282     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1283     if (ret != OMX_ErrorNone) {
1284         goto EXIT;
1285     }
1286
1287     if (pOMXComponent->pComponentPrivate == NULL) {
1288         ret = OMX_ErrorBadParameter;
1289         goto EXIT;
1290     }
1291     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1292
1293     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1294
1295     Exynos_OSAL_Free(pVideoDec);
1296     pExynosComponent->hComponentHandle = pVideoDec = NULL;
1297
1298     pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1299     if (pExynosPort->processData.extInfo != NULL) {
1300         Exynos_OSAL_Free(pExynosPort->processData.extInfo);
1301         pExynosPort->processData.extInfo = NULL;
1302     }
1303
1304     for(i = 0; i < ALL_PORT_NUM; i++) {
1305         pExynosPort = &pExynosComponent->pExynosPort[i];
1306         Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType);
1307         pExynosPort->portDefinition.format.video.cMIMEType = NULL;
1308     }
1309
1310     ret = Exynos_OMX_Port_Destructor(pOMXComponent);
1311
1312     ret = Exynos_OMX_BaseComponent_Destructor(hComponent);
1313
1314 EXIT:
1315     FunctionOut();
1316
1317     return ret;
1318 }