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