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