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