exynos_omx: multi_thread: Modified Video Encode Scheme.
authorSeungBeom Kim <sbcrux.kim@samsung.com>
Wed, 4 Jul 2012 05:13:28 +0000 (14:13 +0900)
committerDima Zavin <dima@android.com>
Tue, 24 Jul 2012 22:12:42 +0000 (15:12 -0700)
- Encode component setup scheme change.
- Add Encode component output port share.

Change-Id: Iaf145e41dd0f706cfb17fcc0fa34b1f8bf9113b7
Signed-off-by: SeungBeom Kim <sbcrux.kim@samsung.com>
exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_Venc.c
exynos_omx/openmax/exynos_omx/component/video/enc/Exynos_OMX_Venc.h
exynos_omx/openmax/exynos_omx/component/video/enc/h264/Exynos_OMX_H264enc.c
exynos_omx/openmax/exynos_omx/component/video/enc/mpeg4/Exynos_OMX_Mpeg4enc.c

index ecfb788e36a49346915dda0f3c929bb68bfd9e77..265281158aeffb4f2e1cf5e66d98a1e91c5ef7e6 100644 (file)
@@ -175,10 +175,7 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_
     OMX_U32                copySize = 0;
     OMX_BYTE               checkInputStream = NULL;
     OMX_U32                checkInputStreamLen = 0;
-    OMX_U32                checkedSize = 0;
     OMX_BOOL               flagEOS = OMX_FALSE;
-    OMX_BOOL               flagEOF = OMX_FALSE;
-    OMX_BOOL               previousFrameEOF = OMX_FALSE;
 
     FunctionIn();
 
@@ -206,94 +203,59 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_
 #endif
             /* reset dataBuffer */
             Exynos_ResetDataBuffer(inputUseBuffer);
-            flagEOF = OMX_TRUE;
         } else if ((exynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
             checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
             checkInputStreamLen = inputUseBuffer->remainDataLen;
 
-            if (srcInputData->dataLen == 0) {
-                previousFrameEOF = OMX_TRUE;
-            } else {
-                previousFrameEOF = OMX_FALSE;
-            }
-
-            if (pExynosComponent->bUseFlagEOF == OMX_TRUE) {
-                flagEOF = OMX_TRUE;
-                checkedSize = checkInputStreamLen;
-                if (checkedSize == 0) {
-                    inputUseBuffer->remainDataLen = 0;    //inputUseBuffer->dataLen = (nFrameWidth * height * 3) / 2;
-                    checkedSize = checkInputStreamLen = inputUseBuffer->remainDataLen;
-                    inputUseBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
-                }
-                if (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) {
-                    flagEOS = OMX_TRUE;
-                }
-            } else {
-                unsigned int oneFrameSize = 0;
-
-                switch (eColorFormat) {
-                case OMX_COLOR_FormatYUV420Planar:
-                case OMX_COLOR_FormatYUV420SemiPlanar:
-                case OMX_SEC_COLOR_FormatNV12Tiled:
-                case OMX_SEC_COLOR_FormatNV21Linear:
-                    oneFrameSize = (nFrameWidth * nFrameHeight * 3) / 2;
-                    break;
-                default:
-                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_Preprocessor_InputData: eColorFormat is wrong");
-                    break;
-                }
+            pExynosComponent->bUseFlagEOF = OMX_TRUE;
 
-                if (previousFrameEOF == OMX_TRUE) {
-                    if (checkInputStreamLen >= oneFrameSize) {
-                        checkedSize = oneFrameSize;
-                        flagEOF = OMX_TRUE;
-                    } else {
-                        flagEOF = OMX_FALSE;
-                    }
-                } else {
-                    if (checkInputStreamLen >= (oneFrameSize - srcInputData->dataLen)) {
-                        checkedSize = oneFrameSize - srcInputData->dataLen;
-                        flagEOF = OMX_TRUE;
-                    } else {
-                        flagEOF = OMX_FALSE;
-                    }
-                }
-
-                if ((flagEOF == OMX_FALSE) && (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) {
-                    flagEOF = OMX_TRUE;
-                    flagEOS = OMX_TRUE;
-                }
+            if (checkInputStreamLen == 0) {
+                inputUseBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
+                flagEOS = OMX_TRUE;
             }
 
-            if (flagEOF == OMX_TRUE) {
-                copySize = checkedSize;
-                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE");
-            } else {
-                copySize = checkInputStreamLen;
-                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_FALSE");
-            }
+            copySize = checkInputStreamLen;
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE");
 
             if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) {
                 CODEC_ENC_INPUT_BUFFER *codecInputBuffer = (CODEC_ENC_INPUT_BUFFER *)srcInputData->pPrivate;
-
                 codecInputBuffer->YDataSize = nFrameWidth * nFrameHeight;
                 codecInputBuffer->CDataSize = nFrameWidth * nFrameHeight / 2;
 
-                if (flagEOF == OMX_TRUE) {
-                    unsigned int csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar);
-                    unsigned int csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar);
-                    unsigned int cacheable = 1;
-                    unsigned char *pSrcBuf[3] = {NULL, };
-                    unsigned char *pDstBuf[3] = {NULL, };
-                    OMX_PTR ppBuf[3];
+                unsigned int csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar);
+                unsigned int csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar);
+                unsigned int cacheable = 1;
+
+                unsigned char *pSrcBuf[3] = {NULL, };
+                unsigned char *pDstBuf[3] = {NULL, };
+
+                pDstBuf[0] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[0];
+                pDstBuf[1] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[1];
+                pDstBuf[2] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[2];
+
+#ifdef USE_METADATABUFFERTYPE
+                OMX_PTR ppBuf[3];
+
+                if (exynosInputPort->bStoreMetaData == OMX_TRUE) {
+                    OMX_PTR pRGBRealDataBuffer;
 
-                    pDstBuf[0] = (unsigned char *)srcInputData->buffer.multiPlaneBuffer.dataBuffer[0];
-                    pDstBuf[1] = (unsigned char *)srcInputData->buffer.multiPlaneBuffer.dataBuffer[1];
+                    /* ARGB8888 converted to YUV420SemiPlanar */
+                    csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_Format32bitARGB8888);
+                    csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar);
 
-                    if (exynosInputPort->bStoreMetaData == OMX_FALSE) {
-                        pSrcBuf[0]  = checkInputStream;
-                        pSrcBuf[1]  = checkInputStream + (nFrameWidth * nFrameHeight);
-                        pSrcBuf[2]  = checkInputStream + (((nFrameWidth * nFrameHeight) * 5) / 4);
+                    Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf);
+                    if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
+                        Exynos_OSAL_LockANBHandle((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatAndroidOpaque, &pRGBRealDataBuffer);
+                        pSrcBuf[0]  = (unsigned char *)pRGBRealDataBuffer;
+                        pSrcBuf[1]  = NULL;
+                        pSrcBuf[2]  = NULL;
+                    }
+                } else
+#endif
+                {
+                    pSrcBuf[0]  = checkInputStream;
+                    pSrcBuf[1]  = checkInputStream + (nFrameWidth * nFrameHeight);
+                    pSrcBuf[2]  = checkInputStream + (((nFrameWidth * nFrameHeight) * 5) / 4);
 
                     switch (eColorFormat) {
                     case OMX_COLOR_FormatYUV420Planar:
@@ -312,63 +274,46 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_
                         break;
                     }
                 }
+
+                csc_set_src_format(
+                    pVideoEnc->csc_handle,  /* handle */
+                    nFrameWidth,                  /* width */
+                    nFrameHeight,                 /* height */
+                    0,                      /* crop_left */
+                    0,                      /* crop_right */
+                    nFrameWidth,                  /* crop_width */
+                    nFrameHeight,                 /* crop_height */
+                    csc_src_color_format,   /* color_format */
+                    cacheable);             /* cacheable */
+                csc_set_dst_format(
+                    pVideoEnc->csc_handle,  /* handle */
+                    nFrameWidth,                  /* width */
+                    nFrameHeight,                 /* height */
+                    0,                      /* crop_left */
+                    0,                      /* crop_right */
+                    nFrameWidth,                  /* crop_width */
+                    nFrameHeight,                 /* crop_height */
+                    csc_dst_color_format,   /* color_format */
+                    cacheable);             /* cacheable */
+                csc_set_src_buffer(
+                    pVideoEnc->csc_handle,  /* handle */
+                    pSrcBuf[0],             /* y addr */
+                    pSrcBuf[1],             /* u addr or uv addr */
+                    pSrcBuf[2],             /* v addr or none */
+                    0);                     /* ion fd */
+                csc_set_dst_buffer(
+                    pVideoEnc->csc_handle,  /* handle */
+                    pDstBuf[0],             /* y addr */
+                    pDstBuf[1],             /* u addr or uv addr */
+                    pDstBuf[2],             /* v addr or none */
+                    0);                     /* ion fd */
+                csc_convert(pVideoEnc->csc_handle);
+
 #ifdef USE_METADATABUFFERTYPE
-                    else {
-                        if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
-                            OMX_PTR pOutBuffer;
-                            ExynosVideoPlane planes[MAX_BUFFER_PLANE];
-                            /* ARGB8888 converted to YUV420SemiPlanar */
-                            csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_Format32bitARGB8888);
-                            csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar);
-
-                            Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf);
-                            Exynos_OSAL_LockANBHandle((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatAndroidOpaque, planes);
-                            pSrcBuf[0]  = (unsigned char *)planes[0].addr;
-                            pSrcBuf[1]  = NULL;
-                            pSrcBuf[2]  = NULL;
-                        }
-                    }
-#endif
-                    csc_set_src_format(
-                        pVideoEnc->csc_handle,  /* handle */
-                        nFrameWidth,                  /* width */
-                        nFrameHeight,                 /* height */
-                        0,                      /* crop_left */
-                        0,                      /* crop_right */
-                        nFrameWidth,                  /* crop_width */
-                        nFrameHeight,                 /* crop_height */
-                        csc_src_color_format,   /* color_format */
-                        cacheable);             /* cacheable */
-                    csc_set_dst_format(
-                        pVideoEnc->csc_handle,  /* handle */
-                        nFrameWidth,                  /* width */
-                        nFrameHeight,                 /* height */
-                        0,                      /* crop_left */
-                        0,                      /* crop_right */
-                        nFrameWidth,                  /* crop_width */
-                        nFrameHeight,                 /* crop_height */
-                        csc_dst_color_format,   /* color_format */
-                        cacheable);             /* cacheable */
-                    csc_set_src_buffer(
-                        pVideoEnc->csc_handle,  /* handle */
-                        pSrcBuf[0],             /* y addr */
-                        pSrcBuf[1],             /* u addr or uv addr */
-                        pSrcBuf[2],             /* v addr or none */
-                        0);                     /* ion fd */
-                    csc_set_dst_buffer(
-                        pVideoEnc->csc_handle,  /* handle */
-                        pDstBuf[0],             /* y addr */
-                        pDstBuf[1],             /* u addr or uv addr */
-                        pDstBuf[2],             /* v addr or none */
-                        0);                     /* ion fd */
-                    csc_convert(pVideoEnc->csc_handle);
-#ifdef USE_METADATABUFFERTYPE
-                    if (exynosInputPort->bStoreMetaData == OMX_TRUE) {
-                        Exynos_OSAL_UnlockANBHandle((OMX_U32)ppBuf[0]);
-                    }
-#endif
+                if (exynosInputPort->bStoreMetaData == OMX_TRUE) {
+                    Exynos_OSAL_UnlockANBHandle((OMX_U32)ppBuf[0]);
                 }
-
+#endif
                 inputUseBuffer->dataLen -= copySize;
                 inputUseBuffer->remainDataLen -= copySize;
                 inputUseBuffer->usedDataLen += copySize;
@@ -384,7 +329,7 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_
                 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
                                                         pExynosComponent->callbackData,
                                                         OMX_EventError, OMX_ErrorUndefined, 0, NULL);
-                flagEOF = OMX_FALSE;
+                ret = OMX_FALSE;
             }
 
             if (((exynosInputPort->bStoreMetaData == OMX_TRUE) && (eColorFormat == OMX_COLOR_FormatAndroidOpaque)) ||
@@ -402,20 +347,16 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_
             pExynosComponent->bSaveFlagEOS = OMX_TRUE;
         }
 
-        if (flagEOF == OMX_TRUE) {
-            if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
-                pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
-                pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp;
-                pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags;
-                pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "first frame timestamp after seeking %lld us (%.2f secs)",
-                    srcInputData->timeStamp, srcInputData->timeStamp / 1E6);
-            }
-
-            ret = OMX_TRUE;
-        } else {
-            ret = OMX_FALSE;
+        if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
+            pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
+            pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp;
+            pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags;
+            pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)",
+                            srcInputData->timeStamp, srcInputData->timeStamp / 1E6);
         }
+
+        ret = OMX_TRUE;
     }
 
 EXIT:
@@ -679,12 +620,6 @@ OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent)
             }
             ret = pVideoEnc->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData);
 
-            if (pVideoEnc->bFirstOutput == OMX_FALSE) {
-                Exynos_OSAL_SignalSet(pVideoEnc->headerGeneratedEvent);
-                Exynos_OSAL_SleepMillisec(0);
-                pVideoEnc->bFirstOutput = OMX_TRUE;
-            }
-
             Exynos_ResetCodecData(&dstInputData);
             Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
         }
@@ -1010,8 +945,6 @@ OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hCompone
     Exynos_OSAL_Memset(pVideoEnc, 0, sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT));
     pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoEnc;
 
-    Exynos_OSAL_SignalCreate(&pVideoEnc->headerGeneratedEvent);
-
     pExynosComponent->bSaveFlagEOS = OMX_FALSE;
 
     pVideoEnc->configChange = OMX_FALSE;
@@ -1115,8 +1048,6 @@ OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hCompo
 
     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
 
-    Exynos_OSAL_SignalTerminate(pVideoEnc->headerGeneratedEvent);
-
     Exynos_OSAL_Free(pVideoEnc);
     pExynosComponent->hComponentHandle = pVideoEnc = NULL;
 
index 88bce4f5d2ad0e3e2e4b25148544ffb0579bf583..7a387bb2271bd32b60dac4ea32f936e75c885c7f 100644 (file)
@@ -107,7 +107,6 @@ typedef struct _EXYNOS_OMX_VIDEOENC_COMPONENT
     OMX_VIDEO_CONTROLRATETYPE eControlRate[ALL_PORT_NUM];
     OMX_VIDEO_PARAM_QUANTIZATIONTYPE quantization;
 
-    OMX_HANDLETYPE           headerGeneratedEvent;
     OMX_BOOL bFirstOutput;
 
     /* CSC handle */
index 2eec7eaf6cd851693077dca6dfe502bc19476130..812b2003b978329eb46ec61b4cc07565233a095b 100644 (file)
@@ -748,6 +748,11 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT
     ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
     ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
     ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+    ExynosVideoEncParam     *pEncParam    = NULL;
+
+    ExynosVideoGeometry      bufferConf;
+    OMX_U32                  inputBufferNumber = 0;
+    int i, nOutbufs;
 
     FunctionIn();
 
@@ -767,48 +772,84 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT
         goto EXIT;
     }
 
-    OMX_PTR pMFCYUVVirBuffer[2] = {NULL, NULL};
-    OMX_U32 pMFCYUVDataSize[2]  = {0, 0};
-
-    pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp;
-    pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags;
-    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pH264Enc->hMFCH264Handle.indexTimestamp, pSrcInputData->nFlags);
-    pEncOps->Set_FrameTag(pH264Enc->hMFCH264Handle.hMFCHandle, pH264Enc->hMFCH264Handle.indexTimestamp);
-    pH264Enc->hMFCH264Handle.indexTimestamp++;
-    pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
-
-    /* queue work for input buffer */
-    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d H264CodecSetup(): oneFrameSize: %d, bufferHeader: 0x%x",  __FUNCTION__, __LINE__, oneFrameSize, pSrcInputData->bufferHeader);
-    if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
-        CODEC_ENC_INPUT_BUFFER *codecInputBuffer = (CODEC_ENC_INPUT_BUFFER *)pSrcInputData->pPrivate;
-        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d codecInputBuffer:0x%x",  __FUNCTION__, __LINE__, codecInputBuffer);
-        pMFCYUVDataSize[0] = codecInputBuffer->YDataSize;
-        pMFCYUVDataSize[1] = codecInputBuffer->CDataSize;
-    } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
-        pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight; //codecInputBuffer->YDataSize;
-        pMFCYUVDataSize[1] = pMFCYUVDataSize[0]/2;
-        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d Ysize:%d CSize %d",  __FUNCTION__, __LINE__, pMFCYUVDataSize[0], pMFCYUVDataSize[1]);
+    Set_H264Enc_Param(pExynosComponent);
+    pEncParam = &pMFCH264Handle->encParam;
+    if (pEncOps->Set_EncParam) {
+        if(pEncOps->Set_EncParam(pH264Enc->hMFCH264Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
     }
 
-    pMFCYUVVirBuffer[0] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0];
-    pMFCYUVVirBuffer[1] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[1];
+    /* input buffer info: only 3 config values needed */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+    bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12;
+    bufferConf.nFrameWidth = pExynosInputPort->portDefinition.format.video.nFrameWidth;
+    bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight;
+    pInbufOps->Set_Shareable(hMFCHandle);
+    if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
+        inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM;
+    } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
+        inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
+    }
 
-    if (pInbufOps->Enqueue(pH264Enc->hMFCH264Handle.hMFCHandle, (unsigned char **)pMFCYUVVirBuffer,
-                          (unsigned int *)pMFCYUVDataSize, 2, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
-        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer");
-        ret = OMX_ErrorUndefined;
+    /* should be done before prepare input buffer */
+    if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
         goto EXIT;
     }
-    /* input start */
-    if (pInbufOps->Run(pH264Enc->hMFCH264Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
-        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
-        ret = OMX_ErrorCodecInit;
+
+    /* set input buffer geometry */
+    if (pInbufOps->Set_Geometry) {
+        if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* setup input buffer */
+    if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
+        ret = OMX_ErrorInsufficientResources;
         goto EXIT;
     }
 
-    pH264Enc->bSourceStart = OMX_TRUE;
-    Exynos_OSAL_SignalSet(pH264Enc->hSourceStartEvent);
-    Exynos_OSAL_SleepMillisec(0);
+    OMX_PTR pTempAddress[MFC_INPUT_BUFFER_PLANE] = {NULL, NULL};
+    OMX_U32 TempAllocSize[MFC_INPUT_BUFFER_PLANE] = {0, 0};
+    if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
+        /* Register input buffer */
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+            pTempAddress[0] = pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr;
+            pTempAddress[1] = pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr;
+            TempAllocSize[0] = pVideoEnc->pMFCEncInputBuffer[i]->YBufferSize;
+            TempAllocSize[1] = pVideoEnc->pMFCEncInputBuffer[i]->CBufferSize;
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d", __FUNCTION__, __LINE__);
+            if (pInbufOps->Register(hMFCHandle, pTempAddress, TempAllocSize) != VIDEO_ERROR_NONE) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            }
+        }
+    } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
+        if (pExynosInputPort->bStoreMetaData == OMX_TRUE) {
+            TempAllocSize[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) *
+                                ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight);
+            TempAllocSize[1] = ALIGN(TempAllocSize[0]/2,256);
+        }
+        /* Register input buffer */
+        for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) {
+            if (pInbufOps->Register(pH264Enc->hMFCH264Handle.hMFCHandle,
+                        (unsigned char **)&pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer,
+                        (pExynosInputPort->bStoreMetaData ? (unsigned int *)TempAllocSize :
+                        (unsigned int *)&pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen)) != VIDEO_ERROR_NONE) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            }
+        }
+    }
 
     pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE;
     ret = OMX_ErrorNone;
@@ -827,35 +868,133 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
     EXYNOS_MFC_H264ENC_HANDLE     *pMFCH264Handle    = &pH264Enc->hMFCH264Handle;
     void                          *hMFCHandle = pMFCH264Handle->hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
 
     ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
     ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
     ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
+    ExynosVideoGeometry      bufferConf;
+    OMX_U32                  inputBufferNumber = 0;
+    int i, nOutbufs;
 
     FunctionIn();
 
-    /* start header encoding */
-    if (pOutbufOps->Run) {
-        if (pOutbufOps->Run(pH264Enc->hMFCH264Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
-            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer for header parsing");
+    int OutBufferSize = pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
+    /* set geometry for output (dst) */
+    if (pOutbufOps->Set_Geometry) {
+        /* output buffer info: only 2 config values needed */
+        bufferConf.eCompressionFormat = VIDEO_CODING_AVC;
+        bufferConf.nSizeImage = OutBufferSize;
+
+        if (pOutbufOps->Set_Geometry(pH264Enc->hMFCH264Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
             ret = OMX_ErrorInsufficientResources;
             goto EXIT;
         }
     }
 
-    pH264Enc->bDestinationStart = OMX_TRUE;
-    Exynos_OSAL_SignalSet(pH264Enc->hDestinationStartEvent);
-    Exynos_OSAL_SleepMillisec(0);
+    /* should be done before prepare output buffer */
+    if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
 
-    /* bConfiguredMFCDst should be set true before waiting headerGeneratedEvent event.
-     * To make sure that the first dequeued destination buffer is enqueued before H264CodecDstSetup returns.
-     * If bConfiguredMFCDst is not set to be true, 
-     * Exynos_H264Enc_dstInputBufferProcess returns without enqueuing the first dequeued destination buffer.
-     */
-    pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE;
+    pOutbufOps->Set_Shareable(hMFCHandle);
+    int SetupBufferNumber = 0;
+    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY)
+        SetupBufferNumber = MFC_OUTPUT_BUFFER_NUM_MAX;
+    else
+        SetupBufferNumber = pExynosOutputPort->portDefinition.nBufferCountActual;
+    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SetupBufferNumber:%d", SetupBufferNumber);
 
-    Exynos_OSAL_SignalWait(pVideoEnc->headerGeneratedEvent, DEF_MAX_WAIT_TIME);
-    Exynos_OSAL_SignalReset(pVideoEnc->headerGeneratedEvent);
+    if (pOutbufOps->Setup(pH264Enc->hMFCH264Handle.hMFCHandle, SetupBufferNumber) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0};
+    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
+        /* Register input buffer */
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            pVideoEnc->pMFCEncOutputBuffer[i] = (CODEC_ENC_OUTPUT_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_OUTPUT_BUFFER));
+            pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr =
+                (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, OutBufferSize, NORMAL_MEMORY);
+            pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize = OutBufferSize;
+
+            if (pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr == NULL) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer");
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            }
+            if (pOutbufOps->Register(hMFCHandle,
+                                     &pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr,
+                                     &pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize) != VIDEO_ERROR_NONE) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            }
+            pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)&pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr, (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
+        }
+    } else if ((pExynosOutputPort->bufferProcessType & BUFFER_SHARE) == BUFFER_SHARE) {
+        /* Register input buffer */
+        /*************/
+        /*    TBD    */
+        /*************/
+        for (i = 0; i < pExynosOutputPort->portDefinition.nBufferCountActual; i++) {
+            if (pOutbufOps->Register(hMFCHandle, &pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer, &pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen) != VIDEO_ERROR_NONE) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            }
+            pOutbufOps->Enqueue(hMFCHandle, &pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer, (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
+        }
+    }
+
+    /* start header encoding */
+    if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
+        OMX_BUFFERHEADERTYPE *OMXBuffer = NULL;
+        ExynosVideoBuffer *pVideoBuffer = NULL;
+
+        OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+        if (OMXBuffer == OMX_ErrorNone) {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+
+        if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Dequeue", __FUNCTION__, __LINE__);
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "dst:0x%x, src:0x%x, dataSize:%d",
+                            OMXBuffer->pBuffer,
+                            pVideoBuffer->planes[0].addr,
+                            pVideoBuffer->planes[0].dataSize);
+        Exynos_OSAL_Memcpy(OMXBuffer->pBuffer,
+                           pVideoBuffer->planes[0].addr,
+                           pVideoBuffer->planes[0].dataSize);
+        OMXBuffer->nFilledLen = pVideoBuffer->planes[0].dataSize;
+        OMXBuffer->nOffset = 0;
+        OMXBuffer->nTimeStamp = 0;
+        OMXBuffer->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
+        OMXBuffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
+        Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer);
+
+        pVideoEnc->bFirstOutput = OMX_TRUE;
+        ret = OMX_ErrorNone;
+
+        H264CodecStop(pOMXComponent, OUTPUT_PORT_INDEX);
+    }
+    pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE;
 
     ret = OMX_ErrorNone;
 
@@ -1377,12 +1516,6 @@ OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
     ExynosVideoEncBufferOps *pOutbufOps = NULL;
 
     CSC_METHOD csc_method = CSC_METHOD_SW;
-
-    ExynosVideoEncParam     *pEncParam    = NULL;
-    ExynosVideoGeometry      bufferConf;
-    OMX_U32                  inputBufferNumber = 0;
-    ExynosVideoBuffer bufferInfo;
-
     int i = 0;
 
     FunctionIn();
@@ -1400,6 +1533,8 @@ OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
         } else {
             pExynosInputPort->bufferProcessType = BUFFER_SHARE;
         }
+    } else {
+        pExynosInputPort->bufferProcessType = BUFFER_COPY;
     }
 
     /* H.264 Codec Open */
@@ -1415,69 +1550,6 @@ OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
     if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
         Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
         Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
-    } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
-        /*************/
-        /*    TBD    */
-        /*************/
-        /* Does not require any actions? */
-    }
-
-    Set_H264Enc_Param(pExynosComponent);
-    pEncParam = &pMFCH264Handle->encParam;
-    if (pEncOps->Set_EncParam) {
-        if(pEncOps->Set_EncParam(pH264Enc->hMFCH264Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) {
-            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
-            ret = OMX_ErrorInsufficientResources;
-            goto EXIT;
-        }
-    }
-
-    if (pInbufOps->Set_Shareable) {
-        pInbufOps->Set_Shareable(pH264Enc->hMFCH264Handle.hMFCHandle);
-    }
-
-    if ((pExynosInputPort->bufferProcessType & BUFFER_SHARE) == BUFFER_SHARE) {
-        inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM;
-    } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
-        inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
-    }
-
-    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
-
-    /* input buffer info: only 3 config values needed */
-    bufferConf.eColorFormat = pEncParam->commonParam.FrameMap;
-    bufferConf.nFrameWidth = pExynosInputPort->portDefinition.format.video.nFrameWidth;
-    bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight;
-
-    /* set input buffer geometry */
-    if (pInbufOps->Set_Geometry) {
-        if (pInbufOps->Set_Geometry(pH264Enc->hMFCH264Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
-            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
-            ret = OMX_ErrorInsufficientResources;
-            goto EXIT;
-        }
-    }
-
-    /* should be done before prepare input buffer */
-    if (pInbufOps->Enable_Cacheable) {
-        if (pInbufOps->Enable_Cacheable(pH264Enc->hMFCH264Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
-            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup cacheable input buffer");
-            ret = OMX_ErrorInsufficientResources;
-            goto EXIT;
-        }
-    }
-
-    /* setup input buffer */
-    if (pInbufOps->Setup(pH264Enc->hMFCH264Handle.hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
-        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
-        ret = OMX_ErrorInsufficientResources;
-        goto EXIT;
-    }
-
-    if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
-        /* Register input buffer */
-        OMX_PTR pTempAddress[2] = {NULL, NULL};
-        OMX_U32 TempAllocSize[2] = {0, 0};
 
         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
             pVideoEnc->pMFCEncInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_ENC_INPUT_BUFFER));
@@ -1491,11 +1563,6 @@ OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
             pVideoEnc->pMFCEncInputBuffer[i]->CBufferSize = DEFAULT_MFC_INPUT_CBUFFER_SIZE;
             pVideoEnc->pMFCEncInputBuffer[i]->CDataSize = 0;
 
-            pTempAddress[0] = pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr;
-            pTempAddress[1] = pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr;
-            TempAllocSize[0] = pVideoEnc->pMFCEncInputBuffer[i]->YBufferSize;
-            TempAllocSize[1] = pVideoEnc->pMFCEncInputBuffer[i]->CBufferSize;
-
             if ((pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr == NULL) ||
                 (pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr == NULL)) {
                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer");
@@ -1503,127 +1570,27 @@ OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
                 goto EXIT;
             }
 
-            if (pInbufOps->Register(pH264Enc->hMFCH264Handle.hMFCHandle,
-                                    (unsigned char **)pTempAddress,
-                                    (unsigned int *)TempAllocSize) != VIDEO_ERROR_NONE) {
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
-                ret = OMX_ErrorInsufficientResources;
-                goto EXIT;
-            }
-
-            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
-            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->YVirAddr: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr);
-            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->CVirAddr: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr);
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->YVirAddr: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr);
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->CVirAddr: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr);
 
             Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
         }
     } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
-        OMX_U32 TempAllocSize[2] = {0, 0};
-        if (pExynosInputPort->bStoreMetaData == OMX_TRUE) {
-            TempAllocSize[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) * ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight);
-            TempAllocSize[1] = ALIGN(TempAllocSize[0]/2,256);
-        }
-
-        /* Register input buffer */
-        for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) {
-            if (pInbufOps->Register(pH264Enc->hMFCH264Handle.hMFCHandle,
-                                    (unsigned char **)&pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer,
-                                    (pExynosInputPort->bStoreMetaData ? (unsigned int *)TempAllocSize :
-                                    (unsigned int *)&pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen)) != VIDEO_ERROR_NONE) {
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
-                ret = OMX_ErrorInsufficientResources;
-                goto EXIT;
-            }
-        }
-    }
-
-    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
-        Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
-        Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
-    } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
         /*************/
         /*    TBD    */
         /*************/
         /* Does not require any actions. */
     }
 
-    /* set geometry for output (dst) */
-    if (pOutbufOps->Set_Geometry) {
-        /* only 2 config values needed */
-        bufferConf.eCompressionFormat = VIDEO_CODING_AVC;
-        bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
-
-        if (pOutbufOps->Set_Geometry(pH264Enc->hMFCH264Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
-            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
-            ret = OMX_ErrorInsufficientResources;
-            goto EXIT;
-        }
-    }
-    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d", __FUNCTION__, __LINE__);
-
-    /* should be done before prepare output buffer */
-    if (pOutbufOps->Enable_Cacheable) {
-        if (pOutbufOps->Enable_Cacheable(pH264Enc->hMFCH264Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
-            ret = OMX_ErrorInsufficientResources;
-            goto EXIT;
-        }
-    }
-
-    if (pOutbufOps->Set_Shareable) {
-        pOutbufOps->Set_Shareable(pH264Enc->hMFCH264Handle.hMFCHandle);
-    }
-
-    if (pOutbufOps->Setup(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_OUTPUT_BUFFER_NUM_MAX) != VIDEO_ERROR_NONE) {
-        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
-        ret = OMX_ErrorInsufficientResources;
-        goto EXIT;
-    }
-
-    OMX_U32 dataLen[2] = {0, 0};
     if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
-        int OutBufferSize = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
-        /* Register input buffer */
-        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
-            pVideoEnc->pMFCEncOutputBuffer[i] = (CODEC_ENC_OUTPUT_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_OUTPUT_BUFFER));
-            pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr =
-                (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, OutBufferSize, NORMAL_MEMORY);
-            pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize = OutBufferSize;
-            pVideoEnc->pMFCEncOutputBuffer[i]->dataSize = 0;
-
-            if (pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr == NULL) {
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer");
-                ret = OMX_ErrorInsufficientResources;
-                goto EXIT;
-            }
-
-            if (pOutbufOps->Register(pH264Enc->hMFCH264Handle.hMFCHandle,
-                                     (unsigned char **)(&pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr),
-                                     (unsigned int *)&pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize) != VIDEO_ERROR_NONE) {
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
-                ret = OMX_ErrorInsufficientResources;
-                goto EXIT;
-            }
-            pOutbufOps->Enqueue(pH264Enc->hMFCH264Handle.hMFCHandle,
-                                     (unsigned char **)&pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr,
-                                     (unsigned int *)dataLen, 1, NULL);
-        }
+        Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
     } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
-        /* Register input buffer */
         /*************/
         /*    TBD    */
         /*************/
-        for (i = 0; i < pExynosOutputPort->portDefinition.nBufferCountActual; i++) {
-            if (pOutbufOps->Register(hMFCHandle,
-                                     (unsigned char **)&pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer,
-                                     (unsigned int *)&pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen) != VIDEO_ERROR_NONE) {
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
-                ret = OMX_ErrorInsufficientResources;
-                goto EXIT;
-            }
-            pOutbufOps->Enqueue(pH264Enc->hMFCH264Handle.hMFCHandle,
-                                     (unsigned char **)&pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer,
-                                     (unsigned int *)dataLen, 1, NULL);
-        }
+        /* Does not require any actions. */
     }
 
     pH264Enc->bSourceStart = OMX_FALSE;
@@ -1685,6 +1652,25 @@ OMX_ERRORTYPE Exynos_H264Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
     pH264Enc->hSourceStartEvent = NULL;
     pH264Enc->bSourceStart = OMX_FALSE;
 
+    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pVideoEnc->pMFCEncOutputBuffer[i] != NULL) {
+                if (pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr != NULL)
+                    Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr);
+                Exynos_OSAL_Free(pVideoEnc->pMFCEncOutputBuffer[i]);
+                pVideoEnc->pMFCEncOutputBuffer[i] = NULL;
+            }
+        }
+
+        Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
+    } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
     if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
             if (pVideoEnc->pMFCEncInputBuffer[i] != NULL) {
@@ -1705,25 +1691,6 @@ OMX_ERRORTYPE Exynos_H264Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
         /*************/
         /* Does not require any actions. */
     }
-
-    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
-        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
-            if (pVideoEnc->pMFCEncOutputBuffer[i] != NULL) {
-                if (pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr != NULL)
-                    Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr);
-                Exynos_OSAL_Free(pVideoEnc->pMFCEncOutputBuffer[i]);
-                pVideoEnc->pMFCEncOutputBuffer[i] = NULL;
-            }
-        }
-
-        Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
-        Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
-    } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
-        /*************/
-        /*    TBD    */
-        /*************/
-        /* Does not require any actions. */
-    }
     H264CodecClose(pH264Enc);
 
 EXIT:
@@ -1750,19 +1717,19 @@ OMX_ERRORTYPE Exynos_H264Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_
 
     FunctionIn();
 
-    if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) {
-        ret = H264CodecDstSetup(pOMXComponent);
-    }
-
     if (pH264Enc->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
         ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData);
-        goto EXIT;
+        if ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)
+            goto EXIT;
+    }
+    if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) {
+        ret = H264CodecDstSetup(pOMXComponent);
     }
 
     if ((pSrcInputData->dataLen >= 0) ||
         ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
-        OMX_PTR pMFCYUVVirBuffer[2] = {NULL, NULL};
-        OMX_U32 pMFCYUVDataSize[2]  = {NULL, NULL};
+        OMX_PTR pMFCYUVVirBuffer[MFC_INPUT_BUFFER_PLANE] = {NULL, NULL};
+        OMX_U32 pMFCYUVDataSize[MFC_INPUT_BUFFER_PLANE]  = {NULL, NULL};
 
         pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp;
         pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags;
@@ -1772,30 +1739,39 @@ OMX_ERRORTYPE Exynos_H264Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_
         pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
 
         /* queue work for input buffer */
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_H264Enc_SrcIn(): oneFrameSize: %d, bufferHeader: 0x%x", oneFrameSize, pSrcInputData->bufferHeader);
+        CODEC_ENC_INPUT_BUFFER *codecInputBuffer = (CODEC_ENC_INPUT_BUFFER *)pSrcInputData->pPrivate;
+
+        pMFCYUVVirBuffer[0] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0];
+        pMFCYUVVirBuffer[1] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[1];
+
         if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
             CODEC_ENC_INPUT_BUFFER *codecInputBuffer = (CODEC_ENC_INPUT_BUFFER *)pSrcInputData->pPrivate;
             pMFCYUVDataSize[0] = codecInputBuffer->YDataSize;
             pMFCYUVDataSize[1] = codecInputBuffer->CDataSize;
         } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
-            pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight; //codecInputBuffer->YDataSize;
+            pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight;
             pMFCYUVDataSize[1] = pMFCYUVDataSize[0]/2;
         }
 
-        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_H264Enc_SrcIn(): oneFrameSize: %d, bufferHeader: 0x%x", oneFrameSize, pSrcInputData->bufferHeader);
-
-        pMFCYUVVirBuffer[0] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0];
-        pMFCYUVVirBuffer[1] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[1];
-
         codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pMFCYUVVirBuffer,
-                              (unsigned int *)pMFCYUVDataSize, 2, pSrcInputData->bufferHeader);
+                              (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
         if (codecReturn != VIDEO_ERROR_NONE) {
             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__);
             ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
             goto EXIT;
         }
-
-//        if (pH264Enc->bSourceStart ==OMX_TRUE)
-//            H264CodecStart(pOMXComponent, INPUT_PORT_INDEX);
+        H264CodecStart(pOMXComponent, INPUT_PORT_INDEX);
+        if (pH264Enc->bSourceStart == OMX_FALSE) {
+            pH264Enc->bSourceStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pH264Enc->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+        if (pH264Enc->bDestinationStart == OMX_FALSE) {
+            pH264Enc->bDestinationStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pH264Enc->hDestinationStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
     }
 
     ret = OMX_ErrorNone;
@@ -1837,7 +1813,7 @@ OMX_ERRORTYPE Exynos_H264Enc_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX
         pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
         pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[1] = pVideoBuffer->planes[1].addr;
         pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[2] = pVideoBuffer->planes[2].addr;
-        pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize +
+        pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize +
                                         pVideoBuffer->planes[1].allocSize +
                                         pVideoBuffer->planes[2].allocSize;
 
@@ -1890,16 +1866,14 @@ OMX_ERRORTYPE Exynos_H264Enc_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_
 
     codecReturn = pOutbufOps->Enqueue(hMFCHandle,
                      (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.dataBuffer,
-                     (unsigned int *)&dataLen, 1, pDstInputData->bufferHeader);
+                     (unsigned int *)&dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
 
     if (codecReturn != VIDEO_ERROR_NONE) {
         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__);
         ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
         goto EXIT;
     }
-
-//    if (pH264Enc->bDestinationStart ==OMX_TRUE)
-//        H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
+    H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
 
     ret = OMX_ErrorNone;
 
@@ -1969,6 +1943,7 @@ OMX_ERRORTYPE Exynos_H264Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX
         pDstOutputData->timeStamp = 0;
         pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
         pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
+        pVideoEnc->bFirstOutput = OMX_TRUE;
     } else {
         indexTimestamp = pEncOps->Get_FrameTag(pH264Enc->hMFCH264Handle.hMFCHandle);
         if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
@@ -1986,6 +1961,7 @@ OMX_ERRORTYPE Exynos_H264Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX
 
     if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
         ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%x displayStatus:%d, nFlags0x%x", pExynosComponent, displayStatus, pDstOutputData->nFlags);
         pDstOutputData->remainDataLen = 0;
     }
 
@@ -2240,7 +2216,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent
     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
-    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->bufferProcessType = BUFFER_SHARE;
     pExynosPort->portWayType = WAY2_PORT;
 
     for(i = 0; i < ALL_PORT_NUM; i++) {
index 799febdcb66cfb59bb9256fec14d2f05bf82fe11..937e9d5817c38a42e4a311409ee7ceced2ddaff3 100644 (file)
@@ -865,6 +865,11 @@ OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA
     ExynosVideoEncOps       *pEncOps    = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
     ExynosVideoEncBufferOps *pInbufOps  = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
     ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+    ExynosVideoEncParam     *pEncParam    = NULL;
+
+    ExynosVideoGeometry      bufferConf;
+    OMX_U32                  inputBufferNumber = 0;
+    int i, nOutbufs;
 
     FunctionIn();
 
@@ -884,48 +889,88 @@ OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA
         goto EXIT;
     }
 
-    OMX_PTR pMFCYUVVirBuffer[2] = {NULL, NULL};
-    OMX_U32 pMFCYUVDataSize[2]  = {0, 0};
-
-    pExynosComponent->timeStamp[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->timeStamp;
-    pExynosComponent->nFlags[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->nFlags;
-    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp, pSrcInputData->nFlags);
-    pEncOps->Set_FrameTag(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp);
-    pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp++;
-    pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP;
+    if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4)
+        Set_Mpeg4Enc_Param(pExynosComponent);
+    else
+        Set_H263Enc_Param(pExynosComponent);
 
-    /* queue work for input buffer */
-    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d Mpeg4CodecSetup(): oneFrameSize: %d, bufferHeader: 0x%x",  __FUNCTION__, __LINE__, oneFrameSize, pSrcInputData->bufferHeader);
-    if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
-        CODEC_ENC_INPUT_BUFFER *codecInputBuffer = (CODEC_ENC_INPUT_BUFFER *)pSrcInputData->pPrivate;
-        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d codecInputBuffer:0x%x",  __FUNCTION__, __LINE__, codecInputBuffer);
-        pMFCYUVDataSize[0] = codecInputBuffer->YDataSize;
-        pMFCYUVDataSize[1] = codecInputBuffer->CDataSize;
-    } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
-        pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight; //codecInputBuffer->YDataSize;
-        pMFCYUVDataSize[1] = pMFCYUVDataSize[0]/2;
-        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d Ysize:%d CSize %d",  __FUNCTION__, __LINE__, pMFCYUVDataSize[0], pMFCYUVDataSize[1]);
+    pEncParam = &pMFCMpeg4Handle->encParam;
+    if (pEncOps->Set_EncParam) {
+        if(pEncOps->Set_EncParam(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
     }
 
-    pMFCYUVVirBuffer[0] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0];
-    pMFCYUVVirBuffer[1] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[1];
+    /* input buffer info: only 3 config values needed */
+    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+    bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12;
+    bufferConf.nFrameWidth = pExynosInputPort->portDefinition.format.video.nFrameWidth;
+    bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight;
+    pInbufOps->Set_Shareable(hMFCHandle);
+    if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
+        inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM;
+    } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
+        inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
+    }
 
-    if (pInbufOps->Enqueue(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, (unsigned char **)pMFCYUVVirBuffer,
-                          (unsigned int *)pMFCYUVDataSize, 2, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
-        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer");
-        ret = OMX_ErrorUndefined;
+    /* should be done before prepare input buffer */
+    if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+        ret = OMX_ErrorInsufficientResources;
         goto EXIT;
     }
-    /* input start */
-    if (pInbufOps->Run(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
-        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
-        ret = OMX_ErrorCodecInit;
+
+    /* set input buffer geometry */
+    if (pInbufOps->Set_Geometry) {
+        if (pInbufOps->Set_Geometry(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* setup input buffer */
+    if (pInbufOps->Setup(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
+        ret = OMX_ErrorInsufficientResources;
         goto EXIT;
     }
 
-    pMpeg4Enc->bSourceStart = OMX_TRUE;
-    Exynos_OSAL_SignalSet(pMpeg4Enc->hSourceStartEvent);
-    Exynos_OSAL_SleepMillisec(0);
+    OMX_PTR pTempAddress[MFC_INPUT_BUFFER_PLANE] = {NULL, NULL};
+    OMX_U32 TempAllocSize[MFC_INPUT_BUFFER_PLANE] = {0, 0};
+    if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
+        /* Register input buffer */
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+            pTempAddress[0] = pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr;
+            pTempAddress[1] = pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr;
+            TempAllocSize[0] = pVideoEnc->pMFCEncInputBuffer[i]->YBufferSize;
+            TempAllocSize[1] = pVideoEnc->pMFCEncInputBuffer[i]->CBufferSize;
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d", __FUNCTION__, __LINE__);
+            if (pInbufOps->Register(hMFCHandle, pTempAddress, TempAllocSize) != VIDEO_ERROR_NONE) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            }
+        }
+    } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
+        if (pExynosInputPort->bStoreMetaData == OMX_TRUE) {
+            TempAllocSize[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) *
+                                ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight);
+            TempAllocSize[1] = ALIGN(TempAllocSize[0]/2,256);
+        }
+        /* Register input buffer */
+        for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) {
+            if (pInbufOps->Register(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle,
+                        (unsigned char **)&pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer,
+                        (pExynosInputPort->bStoreMetaData ? (unsigned int *)TempAllocSize :
+                        (unsigned int *)&pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen)) != VIDEO_ERROR_NONE) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            }
+        }
+    }
 
     pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_TRUE;
     ret = OMX_ErrorNone;
@@ -944,35 +989,144 @@ OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
     EXYNOS_MPEG4ENC_HANDLE         *pMpeg4Enc = (EXYNOS_MPEG4ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
     EXYNOS_MFC_MPEG4ENC_HANDLE     *pMFCMpeg4Handle    = &pMpeg4Enc->hMFCMpeg4Handle;
     void                          *hMFCHandle = pMFCMpeg4Handle->hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
 
     ExynosVideoEncOps       *pEncOps    = pMpeg4Enc->hMFCMpeg4Handle.pEncOps;
     ExynosVideoEncBufferOps *pInbufOps  = pMpeg4Enc->hMFCMpeg4Handle.pInbufOps;
     ExynosVideoEncBufferOps *pOutbufOps = pMpeg4Enc->hMFCMpeg4Handle.pOutbufOps;
+    ExynosVideoGeometry      bufferConf;
+    OMX_U32                  inputBufferNumber = 0;
+    int i, nOutbufs;
 
     FunctionIn();
 
+    int OutBufferSize = pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
+    /* set geometry for output (dst) */
+    if (pOutbufOps->Set_Geometry) {
+        /* only 2 config values needed */
+        if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4)
+            bufferConf.eCompressionFormat = VIDEO_CODING_MPEG4;
+        else
+            bufferConf.eCompressionFormat = OMX_VIDEO_CodingH263;
+        bufferConf.nSizeImage = OutBufferSize;
+
+        if (pOutbufOps->Set_Geometry(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    /* should be done before prepare output buffer */
+    if (pOutbufOps->Enable_Cacheable) {
+        if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+    }
+
+    if (pOutbufOps->Set_Shareable) {
+        pOutbufOps->Set_Shareable(hMFCHandle);
+    }
+    int SetupBufferNumber = 0;
+    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY)
+        SetupBufferNumber = MFC_OUTPUT_BUFFER_NUM_MAX;
+    else
+        SetupBufferNumber = pExynosOutputPort->portDefinition.nBufferCountActual;
+    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "SetupBufferNumber:%d", SetupBufferNumber);
+
+    if (pOutbufOps->Setup(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, SetupBufferNumber) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0};
+Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "nFrameWidth:%d, nFrameHeight:%d, OutBufferSize:%d",
+    pExynosOutputPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight, OutBufferSize);
+    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
+        /* Register input buffer */
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            pVideoEnc->pMFCEncOutputBuffer[i] = (CODEC_ENC_OUTPUT_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_OUTPUT_BUFFER));
+            pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr =
+                (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, OutBufferSize, NORMAL_MEMORY);
+            pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize = OutBufferSize;
+
+            if (pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr == NULL) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer");
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            }
+            if (pOutbufOps->Register(hMFCHandle,
+                                     &pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr,
+                                     &pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize) != VIDEO_ERROR_NONE) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            }
+            pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)&pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr, (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
+        }
+    } else if ((pExynosOutputPort->bufferProcessType & BUFFER_SHARE) == BUFFER_SHARE) {
+        /* Register input buffer */
+        /*************/
+        /*    TBD    */
+        /*************/
+        for (i = 0; i < pExynosOutputPort->portDefinition.nBufferCountActual; i++) {
+            if (pOutbufOps->Register(hMFCHandle, &pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer, &pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen) != VIDEO_ERROR_NONE) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
+                ret = OMX_ErrorInsufficientResources;
+                goto EXIT;
+            }
+            pOutbufOps->Enqueue(hMFCHandle, &pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer, (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
+        }
+    }
+
     /* start header encoding */
     if (pOutbufOps->Run) {
-        if (pOutbufOps->Run(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
-            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer for header parsing");
+        if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
             ret = OMX_ErrorInsufficientResources;
             goto EXIT;
         }
     }
 
-    pMpeg4Enc->bDestinationStart = OMX_TRUE;
-    Exynos_OSAL_SignalSet(pMpeg4Enc->hDestinationStartEvent);
-    Exynos_OSAL_SleepMillisec(0);
+    if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
+        OMX_BUFFERHEADERTYPE *OMXBuffer = NULL;
+        ExynosVideoBuffer *pVideoBuffer = NULL;
 
-    /* bConfiguredMFCDst should be set true before waiting headerGeneratedEvent event.
-     * To make sure that the first dequeued destination buffer is enqueued before Mpeg4CodecDstSetup returns.
-     * If bConfiguredMFCDst is not set to be true,
-     * Exynos_Mpeg4Enc_dstInputBufferProcess returns without enqueuing the first dequeued destination buffer.
-     */
-    pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_TRUE;
+        OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+        if (OMXBuffer == OMX_ErrorNone) {
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+
+        if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Dequeue", __FUNCTION__, __LINE__);
+            ret = OMX_ErrorUndefined;
+            goto EXIT;
+        }
+
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "dst:0x%x, src:0x%x, dataSize:%d",
+                            OMXBuffer->pBuffer,
+                            pVideoBuffer->planes[0].addr,
+                            pVideoBuffer->planes[0].dataSize);
+        Exynos_OSAL_Memcpy(OMXBuffer->pBuffer,
+                           pVideoBuffer->planes[0].addr,
+                           pVideoBuffer->planes[0].dataSize);
+        OMXBuffer->nFilledLen = pVideoBuffer->planes[0].dataSize;
+        OMXBuffer->nOffset = 0;
+        OMXBuffer->nTimeStamp = 0;
+        OMXBuffer->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
+        OMXBuffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
+        Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer);
 
-    Exynos_OSAL_SignalWait(pVideoEnc->headerGeneratedEvent, DEF_MAX_WAIT_TIME);
-    Exynos_OSAL_SignalReset(pVideoEnc->headerGeneratedEvent);
+        pVideoEnc->bFirstOutput = OMX_TRUE;
+        ret = OMX_ErrorNone;
+
+        Mpeg4CodecStop(pOMXComponent, OUTPUT_PORT_INDEX);
+    }
+    pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_TRUE;
 
     ret = OMX_ErrorNone;
 
@@ -1569,12 +1723,6 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
     ExynosVideoEncBufferOps *pOutbufOps = NULL;
 
     CSC_METHOD csc_method = CSC_METHOD_SW;
-
-    ExynosVideoEncParam     *pEncParam    = NULL;
-    ExynosVideoGeometry      bufferConf;
-    OMX_U32                  inputBufferNumber = 0;
-    ExynosVideoBuffer bufferInfo;
-
     int i = 0;
 
     FunctionIn();
@@ -1592,6 +1740,8 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
         } else {
             pExynosInputPort->bufferProcessType = BUFFER_SHARE;
         }
+    } else {
+        pExynosInputPort->bufferProcessType = BUFFER_COPY;
     }
 
     /* Mpeg4/H.263 Codec Open */
@@ -1607,75 +1757,6 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
     if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
         Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
         Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
-    } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
-        /*************/
-        /*    TBD    */
-        /*************/
-        /* Does not require any actions? */
-    }
-
-    if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4)
-        Set_Mpeg4Enc_Param(pExynosComponent);
-    else
-        Set_H263Enc_Param(pExynosComponent);
-
-    pEncParam = &pMFCMpeg4Handle->encParam;
-    if (pEncOps->Set_EncParam) {
-        if(pEncOps->Set_EncParam(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) {
-            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
-            ret = OMX_ErrorInsufficientResources;
-            goto EXIT;
-        }
-    }
-
-#if 1
-    if (pInbufOps->Set_Shareable) {
-        pInbufOps->Set_Shareable(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle);
-    }
-#endif
-
-    if ((pExynosInputPort->bufferProcessType & BUFFER_SHARE) == BUFFER_SHARE) {
-        inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM;
-    } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
-        inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
-    }
-
-    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
-
-    /* input buffer info: only 3 config values needed */
-    bufferConf.eColorFormat = pEncParam->commonParam.FrameMap;
-    bufferConf.nFrameWidth = pExynosInputPort->portDefinition.format.video.nFrameWidth;
-    bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight;
-
-    /* set input buffer geometry */
-    if (pInbufOps->Set_Geometry) {
-        if (pInbufOps->Set_Geometry(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
-            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
-            ret = OMX_ErrorInsufficientResources;
-            goto EXIT;
-        }
-    }
-
-    /* should be done before prepare input buffer */
-    if (pInbufOps->Enable_Cacheable) {
-        if (pInbufOps->Enable_Cacheable(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
-            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup cacheable input buffer");
-            ret = OMX_ErrorInsufficientResources;
-            goto EXIT;
-        }
-    }
-
-    /* setup input buffer */
-    if (pInbufOps->Setup(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
-        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
-        ret = OMX_ErrorInsufficientResources;
-        goto EXIT;
-    }
-
-    if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
-        /* Register input buffer */
-        OMX_PTR pTempAddress[2] = {NULL, NULL};
-        OMX_U32 TempAllocSize[2] = {0, 0};
 
         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
             pVideoEnc->pMFCEncInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_ENC_INPUT_BUFFER));
@@ -1689,11 +1770,6 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
             pVideoEnc->pMFCEncInputBuffer[i]->CBufferSize = DEFAULT_MFC_INPUT_CBUFFER_SIZE;
             pVideoEnc->pMFCEncInputBuffer[i]->CDataSize = 0;
 
-            pTempAddress[0] = pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr;
-            pTempAddress[1] = pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr;
-            TempAllocSize[0] = pVideoEnc->pMFCEncInputBuffer[i]->YBufferSize;
-            TempAllocSize[1] = pVideoEnc->pMFCEncInputBuffer[i]->CBufferSize;
-
             if ((pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr == NULL) ||
                 (pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr == NULL)) {
                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer");
@@ -1701,132 +1777,27 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
                 goto EXIT;
             }
 
-            if (pInbufOps->Register(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle,
-                                    (unsigned char **)pTempAddress,
-                                    (unsigned int *)TempAllocSize) != VIDEO_ERROR_NONE) {
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
-                ret = OMX_ErrorInsufficientResources;
-                goto EXIT;
-            }
-
-            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->YVirAddr: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr);
             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->CVirAddr: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr);
 
             Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
         }
     } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
-        OMX_U32 TempAllocSize[2] = {0, 0};
-        if (pExynosInputPort->bStoreMetaData == OMX_TRUE) {
-            TempAllocSize[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) * ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight);
-            TempAllocSize[1] = ALIGN(TempAllocSize[0]/2,256);
-        }
-
-        /* Register input buffer */
-        for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) {
-            if (pInbufOps->Register(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle,
-                                    (unsigned char **)&pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer,
-                                    (pExynosInputPort->bStoreMetaData ? (unsigned int *) TempAllocSize :
-                                    (unsigned int *)&pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen)) != VIDEO_ERROR_NONE) {
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
-                ret = OMX_ErrorInsufficientResources;
-                goto EXIT;
-            }
-        }
-    }
-
-    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
-        Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
-        Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
-    } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
         /*************/
         /*    TBD    */
         /*************/
         /* Does not require any actions. */
     }
 
-    /* set geometry for output (dst) */
-    if (pOutbufOps->Set_Geometry) {
-        /* only 2 config values needed */
-        if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4)
-            bufferConf.eCompressionFormat = VIDEO_CODING_MPEG4;
-        else
-            bufferConf.eCompressionFormat = OMX_VIDEO_CodingH263;
-        bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
-
-        if (pOutbufOps->Set_Geometry(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
-            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
-            ret = OMX_ErrorInsufficientResources;
-            goto EXIT;
-        }
-    }
-    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d", __FUNCTION__, __LINE__);
-
-    /* should be done before prepare output buffer */
-    if (pOutbufOps->Enable_Cacheable) {
-        if (pOutbufOps->Enable_Cacheable(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
-            ret = OMX_ErrorInsufficientResources;
-            goto EXIT;
-        }
-    }
-
-#if 1
-    if (pOutbufOps->Set_Shareable) {
-        pOutbufOps->Set_Shareable(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle);
-    }
-#endif
-
-    if (pOutbufOps->Setup(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle, MFC_OUTPUT_BUFFER_NUM_MAX) != VIDEO_ERROR_NONE) {
-        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
-        ret = OMX_ErrorInsufficientResources;
-        goto EXIT;
-    }
-
-    OMX_U32 dataLen[2] = {0, 0};
     if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
-        int OutBufferSize = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
-        /* Register input buffer */
-        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
-            pVideoEnc->pMFCEncOutputBuffer[i] = (CODEC_ENC_OUTPUT_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_OUTPUT_BUFFER));
-            pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr =
-                (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, OutBufferSize, NORMAL_MEMORY);
-            pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize = OutBufferSize;
-            pVideoEnc->pMFCEncOutputBuffer[i]->dataSize = 0;
-
-            if (pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr == NULL) {
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer");
-                ret = OMX_ErrorInsufficientResources;
-                goto EXIT;
-            }
-
-            if (pOutbufOps->Register(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle,
-                                     (unsigned char **)&pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr,
-                                     (unsigned int *)&pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize) != VIDEO_ERROR_NONE) {
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
-                ret = OMX_ErrorInsufficientResources;
-                goto EXIT;
-            }
-            pOutbufOps->Enqueue(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle,
-                                     (unsigned char **)&pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr,
-                                     (unsigned int *)dataLen, 1, NULL);
-        }
+        Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
+        Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
     } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
-        /* Register input buffer */
         /*************/
         /*    TBD    */
         /*************/
-        for (i = 0; i < pExynosOutputPort->portDefinition.nBufferCountActual; i++) {
-            if (pOutbufOps->Register(hMFCHandle,
-                                     (unsigned char **)&pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer,
-                                     (unsigned int *)&pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen) != VIDEO_ERROR_NONE) {
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
-                ret = OMX_ErrorInsufficientResources;
-                goto EXIT;
-            }
-            pOutbufOps->Enqueue(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle,
-                                     (unsigned char **)&pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer,
-                                     (unsigned int *)dataLen, 1, NULL);
-        }
+        /* Does not require any actions. */
     }
 
     pMpeg4Enc->bSourceStart = OMX_FALSE;
@@ -1888,6 +1859,25 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
     pMpeg4Enc->hSourceStartEvent = NULL;
     pMpeg4Enc->bSourceStart = OMX_FALSE;
 
+    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pVideoEnc->pMFCEncOutputBuffer[i] != NULL) {
+                if (pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr != NULL)
+                    Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr);
+                Exynos_OSAL_Free(pVideoEnc->pMFCEncOutputBuffer[i]);
+                pVideoEnc->pMFCEncOutputBuffer[i] = NULL;
+            }
+        }
+
+        Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
+        Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
+    } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
+        /*************/
+        /*    TBD    */
+        /*************/
+        /* Does not require any actions. */
+    }
+
     if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
             if (pVideoEnc->pMFCEncInputBuffer[i] != NULL) {
@@ -1908,25 +1898,6 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
         /*************/
         /* Does not require any actions. */
     }
-
-    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
-        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
-            if (pVideoEnc->pMFCEncOutputBuffer[i] != NULL) {
-                if (pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr != NULL)
-                    Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr);
-                Exynos_OSAL_Free(pVideoEnc->pMFCEncOutputBuffer[i]);
-                pVideoEnc->pMFCEncOutputBuffer[i] = NULL;
-            }
-        }
-
-        Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
-        Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
-    } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
-        /*************/
-        /*    TBD    */
-        /*************/
-        /* Does not require any actions. */
-    }
     Mpeg4CodecClose(pMpeg4Enc);
 
 EXIT:
@@ -1953,19 +1924,19 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX
 
     FunctionIn();
 
-    if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_FALSE) {
-        ret = Mpeg4CodecDstSetup(pOMXComponent);
-    }
-
     if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCSrc == OMX_FALSE) {
         ret = Mpeg4CodecSrcSetup(pOMXComponent, pSrcInputData);
-        goto EXIT;
+        if ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)
+            goto EXIT;
+    }
+    if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_FALSE) {
+        ret = Mpeg4CodecDstSetup(pOMXComponent);
     }
 
     if ((pSrcInputData->dataLen >= 0) ||
         ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
-        OMX_PTR pMFCYUVVirBuffer[2] = {NULL, NULL};
-        OMX_U32 pMFCYUVDataSize[2]  = {NULL, NULL};
+        OMX_PTR pMFCYUVVirBuffer[MFC_INPUT_BUFFER_PLANE] = {NULL, NULL};
+        OMX_U32 pMFCYUVDataSize[MFC_INPUT_BUFFER_PLANE]  = {NULL, NULL};
 
         pExynosComponent->timeStamp[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->timeStamp;
         pExynosComponent->nFlags[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->nFlags;
@@ -1975,26 +1946,39 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX
         pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP;
 
         /* queue work for input buffer */
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_Mpeg4Enc_SrcIn(): oneFrameSize: %d, bufferHeader: 0x%x", oneFrameSize, pSrcInputData->bufferHeader);
+        CODEC_ENC_INPUT_BUFFER *codecInputBuffer = (CODEC_ENC_INPUT_BUFFER *)pSrcInputData->pPrivate;
+
+        pMFCYUVVirBuffer[0] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0];
+        pMFCYUVVirBuffer[1] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[1];
+
         if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
             CODEC_ENC_INPUT_BUFFER *codecInputBuffer = (CODEC_ENC_INPUT_BUFFER *)pSrcInputData->pPrivate;
             pMFCYUVDataSize[0] = codecInputBuffer->YDataSize;
             pMFCYUVDataSize[1] = codecInputBuffer->CDataSize;
         } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
-            pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight; //codecInputBuffer->YDataSize;
+            pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight;
             pMFCYUVDataSize[1] = pMFCYUVDataSize[0]/2;
         }
-        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_Mpeg4Enc_SrcIn(): oneFrameSize: %d, bufferHeader: 0x%x", oneFrameSize, pSrcInputData->bufferHeader);
-
-        pMFCYUVVirBuffer[0] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0];
-        pMFCYUVVirBuffer[1] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[1];
 
         codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pMFCYUVVirBuffer,
-                              (unsigned int *)pMFCYUVDataSize, 2, pSrcInputData->bufferHeader);
+                              (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
         if (codecReturn != VIDEO_ERROR_NONE) {
             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__);
             ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
             goto EXIT;
         }
+        Mpeg4CodecStart(pOMXComponent, INPUT_PORT_INDEX);
+        if (pMpeg4Enc->bSourceStart == OMX_FALSE) {
+            pMpeg4Enc->bSourceStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pMpeg4Enc->hSourceStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
+        if (pMpeg4Enc->bDestinationStart == OMX_FALSE) {
+            pMpeg4Enc->bDestinationStart = OMX_TRUE;
+            Exynos_OSAL_SignalSet(pMpeg4Enc->hDestinationStartEvent);
+            Exynos_OSAL_SleepMillisec(0);
+        }
     }
 
     ret = OMX_ErrorNone;
@@ -2036,7 +2020,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM
         pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
         pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[1] = pVideoBuffer->planes[1].addr;
         pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[2] = pVideoBuffer->planes[2].addr;
-        pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize +
+        pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize +
                                         pVideoBuffer->planes[1].allocSize +
                                         pVideoBuffer->planes[2].allocSize;
 
@@ -2089,13 +2073,14 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX
 
     codecReturn = pOutbufOps->Enqueue(hMFCHandle,
                      (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.dataBuffer,
-                     (unsigned int *)&dataLen, 1, pDstInputData->bufferHeader);
+                     (unsigned int *)&dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
 
     if (codecReturn != VIDEO_ERROR_NONE) {
         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__);
         ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
         goto EXIT;
     }
+    Mpeg4CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
 
     ret = OMX_ErrorNone;
 
@@ -2149,6 +2134,7 @@ OMX_ERRORTYPE Exynos_Mpeg4Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM
         pDstOutputData->timeStamp = 0;
         pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
         pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
+        pVideoEnc->bFirstOutput = OMX_TRUE;
     } else {
         indexTimestamp = pEncOps->Get_FrameTag(pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle);
         if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
@@ -2439,7 +2425,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent
     pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
-    pExynosPort->bufferProcessType = BUFFER_COPY;
+    pExynosPort->bufferProcessType = BUFFER_SHARE;
     pExynosPort->portWayType = WAY2_PORT;
 
     if (codecType == CODEC_TYPE_MPEG4) {