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