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