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