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