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