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