video: Add missing function prototypes
[GitHub/LineageOS/android_hardware_samsung_slsi_openmax.git] / component / video / dec / h264 / Exynos_OMX_H264dec.c
index 2868d8b41e8ecbb4df9bcaec6621d3090ac9fc47..3d99689e7812880586586e006e6afd0d6a33a0e5 100644 (file)
@@ -32,6 +32,7 @@
 #include "Exynos_OMX_Basecomponent.h"
 #include "Exynos_OMX_Baseport.h"
 #include "Exynos_OMX_Vdec.h"
+#include "Exynos_OMX_VdecControl.h"
 #include "Exynos_OSAL_ETC.h"
 #include "Exynos_OSAL_Semaphore.h"
 #include "Exynos_OSAL_Thread.h"
@@ -107,6 +108,8 @@ EXYNOS_OMX_VIDEO_PROFILELEVEL supportedAVCProfileLevels[] ={
     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel41},
     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel42}};
 
+OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent);
+
 static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, void *pVirtAddr, OMX_U32 *dataSize)
 {
     OMX_ERRORTYPE       ret = OMX_ErrorNone;
@@ -309,7 +312,11 @@ OMX_ERRORTYPE H264CodecOpen(EXYNOS_H264DEC_HANDLE *pH264Dec)
     }
 
     /* alloc context, open, querycap */
+#ifdef USE_DMA_BUF
     pH264Dec->hMFCH264Handle.hMFCHandle = pH264Dec->hMFCH264Handle.pDecOps->Init(V4L2_MEMORY_DMABUF);
+#else
+    pH264Dec->hMFCH264Handle.hMFCHandle = pH264Dec->hMFCH264Handle.pDecOps->Init(V4L2_MEMORY_USERPTR);
+#endif
     if (pH264Dec->hMFCH264Handle.hMFCHandle == NULL) {
         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
         ret = OMX_ErrorInsufficientResources;
@@ -541,6 +548,121 @@ EXIT:
     return ret;
 }
 
+OMX_ERRORTYPE H264CodecRegistCodecBuffers(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex,
+    OMX_U32              nBufferCnt)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec           = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
+    void                            *hMFCHandle         = pH264Dec->hMFCH264Handle.hMFCHandle;
+    CODEC_DEC_BUFFER               **ppCodecBuffer      = NULL;
+    ExynosVideoDecBufferOps         *pBufOps            = NULL;
+    ExynosVideoPlane                *pPlanes            = NULL;
+
+    OMX_U32 nPlaneCnt = 0;
+    int i, j;
+
+    FunctionIn();
+
+    if (nPortIndex == INPUT_PORT_INDEX) {
+        ppCodecBuffer   = &(pVideoDec->pMFCDecInputBuffer[0]);
+        pBufOps         = pH264Dec->hMFCH264Handle.pInbufOps;
+    } else {
+        ppCodecBuffer   = &(pVideoDec->pMFCDecOutputBuffer[0]);
+        pBufOps         = pH264Dec->hMFCH264Handle.pOutbufOps;
+    }
+    nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt;
+
+    pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
+    if (pPlanes == NULL) {
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* Register buffer */
+    for (i = 0; i < nBufferCnt; i++) {
+        for (j = 0; j < nPlaneCnt; j++) {
+            pPlanes[j].addr         = ppCodecBuffer[i]->pVirAddr[j];
+            pPlanes[j].fd           = ppCodecBuffer[i]->fd[j];
+            pPlanes[j].allocSize    = ppCodecBuffer[i]->bufferSize[j];
+        }
+
+        if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
+            ret = OMX_ErrorInsufficientResources;
+            Exynos_OSAL_Free(pPlanes);
+            goto EXIT;
+        }
+    }
+
+    Exynos_OSAL_Free(pPlanes);
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
+OMX_ERRORTYPE H264CodecReconfigAllBuffers(
+    OMX_COMPONENTTYPE   *pOMXComponent,
+    OMX_U32              nPortIndex)
+{
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosPort        = &pExynosComponent->pExynosPort[nPortIndex];
+    EXYNOS_H264DEC_HANDLE           *pH264Dec           = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pH264Dec->hMFCH264Handle.hMFCHandle;
+    ExynosVideoDecBufferOps         *pBufferOps         = NULL;
+
+    FunctionIn();
+
+    if ((nPortIndex == INPUT_PORT_INDEX) &&
+        (pH264Dec->bSourceStart == OMX_TRUE)) {
+        ret = OMX_ErrorNotImplemented;
+        goto EXIT;
+    } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
+               (pH264Dec->bDestinationStart == OMX_TRUE)) {
+        pBufferOps  = pH264Dec->hMFCH264Handle.pOutbufOps;
+
+        if (pExynosPort->bufferProcessType & BUFFER_COPY) {
+            /**********************************/
+            /* Codec Buffer Free & Unregister */
+            /**********************************/
+            Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
+            Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+
+            /******************************************************/
+            /* V4L2 Destnation Setup for DPB Buffer Number Change */
+            /******************************************************/
+            H264CodecDstSetup(pOMXComponent);
+
+            pVideoDec->bReconfigDPB = OMX_FALSE;
+        } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
+            /**********************************/
+            /* Codec Buffer Unregister */
+            /**********************************/
+            pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
+            pBufferOps->Cleanup_Buffer(hMFCHandle);
+        }
+    } else {
+        ret = OMX_ErrorBadParameter;
+        goto EXIT;
+    }
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
 OMX_ERRORTYPE H264CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
 {
     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
@@ -558,6 +680,11 @@ OMX_ERRORTYPE H264CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U3
 
     FunctionIn();
 
+    if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
+        ret = OMX_ErrorBadPortIndex;
+        goto EXIT;
+    }
+
     if ((nPortIndex == INPUT_PORT_INDEX) &&
         (pH264Dec->bSourceStart == OMX_TRUE)) {
         Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
@@ -572,21 +699,15 @@ OMX_ERRORTYPE H264CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U3
         pInbufOps->Clear_Queue(hMFCHandle);
     } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
                (pH264Dec->bDestinationStart == OMX_TRUE)) {
-        OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
-        ExynosVideoBuffer *pBuffer = NULL;
-
         Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
 
-        nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle);
-        nOutbufs += EXTRA_DPB_NUM;
-        for (i = 0; i < nOutbufs; i++) {
-            pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer);
-            Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer);
+        for (i = 0; i < pH264Dec->hMFCH264Handle.maxDPBNum; i++) {
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]);
+            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
+
+            Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
         }
         pOutbufOps->Clear_Queue(hMFCHandle);
-    } else {
-        ret = OMX_ErrorBadParameter;
-        goto EXIT;
     }
 
 EXIT:
@@ -623,23 +744,140 @@ OMX_BOOL H264CodecCheckFramePacking(OMX_COMPONENTTYPE *pOMXComponent)
 
         pH264Dec->hMFCH264Handle.S3DFPArgmtType = (EXYNOS_OMX_FPARGMT_TYPE) framePacking.arrangement_type;
         /** Send Port Settings changed call back - output color format change */
-       (*(pExynosComponent->pCallbacks->EventHandler))
+        (*(pExynosComponent->pCallbacks->EventHandler))
               (pOMXComponent,
                pExynosComponent->callbackData,
-               OMX_EventPortSettingsChanged, /* The command was completed */
-               OMX_DirOutput, /* This is the port index */
-               0,
+               OMX_EventS3DInformation,                             /* The command was completed */
+               OMX_TRUE,                                            /* S3D is enabled */
+               (OMX_S32)pH264Dec->hMFCH264Handle.S3DFPArgmtType,    /* S3D FPArgmtType */
                NULL);
 
         Exynos_OSAL_SleepMillisec(0);
-        ret = OMX_TRUE;
+    } else {
+        pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_NONE;
     }
 
+    ret = OMX_TRUE;
+
 EXIT:
     return ret;
 }
 #endif
 
+OMX_ERRORTYPE H264CodecCheckResolutionChange(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE         *pH264Dec           = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle         = pH264Dec->hMFCH264Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    ExynosVideoDecOps             *pDecOps            = pH264Dec->hMFCH264Handle.pDecOps;
+    ExynosVideoDecBufferOps       *pOutbufOps         = pH264Dec->hMFCH264Handle.pOutbufOps;
+
+    FunctionIn();
+    /* get geometry for output */
+    Exynos_OSAL_Memset(&pH264Dec->hMFCH264Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
+    if (pOutbufOps->Get_Geometry(hMFCHandle, &pH264Dec->hMFCH264Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
+        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info");
+        ret = OMX_ErrorInsufficientResources;
+        goto EXIT;
+    }
+
+    /* get dpb count */
+    pH264Dec->hMFCH264Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
+    if (pVideoDec->bThumbnailMode == OMX_FALSE)
+        pH264Dec->hMFCH264Handle.maxDPBNum += EXTRA_DPB_NUM;
+    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "H264CodecSetup nOutbufs: %d", pH264Dec->hMFCH264Handle.maxDPBNum);
+
+    pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE;
+
+    pOutputPort->cropRectangle.nTop     = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nTop;
+    pOutputPort->cropRectangle.nLeft    = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nLeft;
+    pOutputPort->cropRectangle.nWidth   = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth;
+    pOutputPort->cropRectangle.nHeight  = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight;
+
+    if (pVideoDec->bReconfigDPB == OMX_TRUE)
+        pVideoDec->nSavedDPBCnt = pOutputPort->portDefinition.nBufferCountActual;
+
+    if (pOutputPort->bufferProcessType & BUFFER_COPY) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pInputPort->portDefinition.format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
+            (pInputPort->portDefinition.format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPort->portDefinition.format.video.nFrameWidth     = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
+            pInputPort->portDefinition.format.video.nFrameHeight    = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
+            pInputPort->portDefinition.format.video.nStride         = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
+            pInputPort->portDefinition.format.video.nSliceHeight    = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
+
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
+        if ((pVideoDec->bReconfigDPB) ||
+            (pInputPort->portDefinition.format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
+            (pInputPort->portDefinition.format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight) ||
+            (pOutputPort->portDefinition.nBufferCountActual != pH264Dec->hMFCH264Handle.maxDPBNum)) {
+            pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
+
+            pInputPort->portDefinition.format.video.nFrameWidth     = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
+            pInputPort->portDefinition.format.video.nFrameHeight    = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
+            pInputPort->portDefinition.format.video.nStride         = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
+            pInputPort->portDefinition.format.video.nSliceHeight    = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
+
+            pOutputPort->portDefinition.nBufferCountActual  = pH264Dec->hMFCH264Handle.maxDPBNum - 2;
+            pOutputPort->portDefinition.nBufferCountMin     = pH264Dec->hMFCH264Handle.maxDPBNum - 2;
+
+            Exynos_UpdateFrameSize(pOMXComponent);
+
+            /** Send Port Settings changed call back **/
+            (*(pExynosComponent->pCallbacks->EventHandler))
+                (pOMXComponent,
+                 pExynosComponent->callbackData,
+                 OMX_EventPortSettingsChanged, /* The command was completed */
+                 OMX_DirOutput, /* This is the port index */
+                 0,
+                 NULL);
+        }
+    }
+    if ((pVideoDec->bReconfigDPB == OMX_TRUE) ||
+        (pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth) ||
+        (pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight)) {
+        /* Check Crop */
+        pInputPort->portDefinition.format.video.nFrameWidth     = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
+        pInputPort->portDefinition.format.video.nFrameHeight    = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
+        pInputPort->portDefinition.format.video.nStride         = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
+        pInputPort->portDefinition.format.video.nSliceHeight    = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
+        Exynos_UpdateFrameSize(pOMXComponent);
+
+        /** Send crop info call back **/
+        (*(pExynosComponent->pCallbacks->EventHandler))
+            (pOMXComponent,
+             pExynosComponent->callbackData,
+             OMX_EventPortSettingsChanged, /* The command was completed */
+             OMX_DirOutput, /* This is the port index */
+             OMX_IndexConfigCommonOutputCrop,
+             NULL);
+    }
+
+    ret = OMX_ErrorNone;
+
+EXIT:
+    FunctionOut();
+
+    return ret;
+}
+
 OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
 {
     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
@@ -661,16 +899,16 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT
     FunctionIn();
 
     if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
-        OMX_BUFFERHEADERTYPE *OMXBuffer = NULL;
-        OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
-        if (OMXBuffer == NULL) {
-            ret = OMX_ErrorUndefined;
+        BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
+        if (pBufferInfo == NULL) {
+            ret = OMX_ErrorInsufficientResources;
             goto EXIT;
         }
 
-        OMXBuffer->nTimeStamp = pSrcInputData->timeStamp;
-        OMXBuffer->nFlags = pSrcInputData->nFlags;
-        Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer);
+        pBufferInfo->nFlags     = pSrcInputData->nFlags;
+        pBufferInfo->timeStamp  = pSrcInputData->timeStamp;
+        ret = Exynos_OSAL_Queue(&pH264Dec->bypassBufferInfoQ, (void *)pBufferInfo);
+        Exynos_OSAL_SignalSet(pH264Dec->hDestinationStartEvent);
 
         ret = OMX_ErrorNone;
         goto EXIT;
@@ -679,6 +917,10 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT
     if (pVideoDec->bThumbnailMode == OMX_TRUE)
         pDecOps->Set_DisplayDelay(hMFCHandle, 0);
 
+    if ((pDecOps->Enable_DTSMode != NULL) &&
+        (pVideoDec->bDTSMode == OMX_TRUE))
+        pDecOps->Enable_DTSMode(hMFCHandle);
+
     /* input buffer info */
     Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
     bufferConf.eCompressionFormat = VIDEO_CODING_AVC;
@@ -686,11 +928,11 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT
     if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
         bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth
                                 * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
-        inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM;
     } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
         bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
-        inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
     }
+    bufferConf.nPlaneCnt = pExynosInputPort->nPlaneCnt;
+    inputBufferNumber = MAX_INPUTBUFFER_NUM_DYNAMIC;
 
     /* should be done before prepare input buffer */
     if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
@@ -712,41 +954,46 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT
         goto EXIT;
     }
 
-    if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
-        /* Register input buffer */
-        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
-            ExynosVideoPlane plane;
-            plane.addr = pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0];
-            plane.allocSize = pVideoDec->pMFCDecInputBuffer[i]->bufferSize[0];
-            plane.fd = pVideoDec->pMFCDecInputBuffer[i]->fd[0];
-            if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != 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) {
-        /* Register input buffer */
-        for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) {
-            ExynosVideoPlane plane;
-            if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
-                plane.addr = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory, pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer);
-            } else {
-                plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer;
-            }
-            plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen;
-            plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0];
-            if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
-                ret = OMX_ErrorInsufficientResources;
-                goto EXIT;
-            }
-        }
-    }
-
     /* set output geometry */
     Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
+
+#ifdef USE_DUALDPB_MODE
+    switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) {
+    case OMX_COLOR_FormatYUV420SemiPlanar:
+        bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12;
+        break;
+    case OMX_COLOR_FormatYUV420Planar:
+        bufferConf.eColorFormat = VIDEO_COLORFORMAT_I420;
+        break;
+    case OMX_SEC_COLOR_FormatYVU420Planar:
+        bufferConf.eColorFormat = VIDEO_COLORFORMAT_YV12;
+        break;
+    case OMX_SEC_COLOR_FormatNV21Linear:
+        bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV21;
+        break;
+    case OMX_SEC_COLOR_FormatNV12Tiled:
+        bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
+        break;
+    default:
+        bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
+        break;
+    }
+
+    if (bufferConf.eColorFormat != VIDEO_COLORFORMAT_NV12_TILED) {
+        if ((pDecOps->Enable_DualDPBMode != NULL) &&
+            (pDecOps->Enable_DualDPBMode(hMFCHandle) == VIDEO_ERROR_NONE)) {
+            pVideoDec->bDualDPBMode = OMX_TRUE;
+            pExynosOutputPort->nPlaneCnt = Exynos_OSAL_GetPlaneCount(pExynosOutputPort->portDefinition.format.video.eColorFormat);
+        } else {
+            bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
+            pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE;
+        }
+    }
+    pH264Dec->hMFCH264Handle.MFCOutputColorType = bufferConf.eColorFormat;
+#else
     pH264Dec->hMFCH264Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
+#endif
+    bufferConf.nPlaneCnt = pExynosOutputPort->nPlaneCnt;
     if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
         ret = OMX_ErrorInsufficientResources;
@@ -755,8 +1002,12 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT
 
     /* input buffer enqueue for header parsing */
     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize);
-    if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
-                        (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
+    OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0};
+    if (pInbufOps->ExtensionEnqueue(hMFCHandle,
+                            (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
+                            (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd,
+                            (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize,
+                            pExynosInputPort->nPlaneCnt, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
 //        ret = OMX_ErrorInsufficientResources;
         ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
@@ -770,91 +1021,13 @@ OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DAT
         goto EXIT;
     }
 
-    /* get geometry for output */
-    Exynos_OSAL_Memset(&pH264Dec->hMFCH264Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
-    if (pOutbufOps->Get_Geometry(hMFCHandle, &pH264Dec->hMFCH264Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
-        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info");
-        ret = OMX_ErrorInsufficientResources;
+    ret = H264CodecCheckResolutionChange(pOMXComponent);
+    if (ret != OMX_ErrorNone) {
+        H264CodecStop(pOMXComponent, INPUT_PORT_INDEX);
+        pInbufOps->Cleanup_Buffer(hMFCHandle);
         goto EXIT;
     }
 
-    /* get dpb count */
-    pH264Dec->hMFCH264Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
-    if (pVideoDec->bThumbnailMode == OMX_FALSE)
-        pH264Dec->hMFCH264Handle.maxDPBNum += EXTRA_DPB_NUM;
-    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "H264CodecSetup nOutbufs: %d", pH264Dec->hMFCH264Handle.maxDPBNum);
-
-    pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE;
-
-    pExynosOutputPort->cropRectangle.nTop = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nTop;
-    pExynosOutputPort->cropRectangle.nLeft = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nLeft;
-    pExynosOutputPort->cropRectangle.nWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth;
-    pExynosOutputPort->cropRectangle.nHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight;
-
-    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
-        if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
-            (pExynosInputPort->portDefinition.format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight)) {
-            pExynosInputPort->portDefinition.format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
-            pExynosInputPort->portDefinition.format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
-            pExynosInputPort->portDefinition.format.video.nStride = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
-            pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
-
-            Exynos_UpdateFrameSize(pOMXComponent);
-            pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
-
-            /** Send Port Settings changed call back **/
-            (*(pExynosComponent->pCallbacks->EventHandler))
-                (pOMXComponent,
-                 pExynosComponent->callbackData,
-                 OMX_EventPortSettingsChanged, /* The command was completed */
-                 OMX_DirOutput, /* This is the port index */
-                 0,
-                 NULL);
-        }
-    } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
-        if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
-            (pExynosInputPort->portDefinition.format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight) ||
-            (pExynosOutputPort->portDefinition.nBufferCountActual != pH264Dec->hMFCH264Handle.maxDPBNum)) {
-            pExynosInputPort->portDefinition.format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
-            pExynosInputPort->portDefinition.format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
-            pExynosInputPort->portDefinition.format.video.nStride = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
-            pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
-
-            pExynosOutputPort->portDefinition.nBufferCountActual = pH264Dec->hMFCH264Handle.maxDPBNum - 2;
-            pExynosOutputPort->portDefinition.nBufferCountMin = pH264Dec->hMFCH264Handle.maxDPBNum - 2;
-
-            Exynos_UpdateFrameSize(pOMXComponent);
-            pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
-
-            /** Send Port Settings changed call back **/
-            (*(pExynosComponent->pCallbacks->EventHandler))
-                (pOMXComponent,
-                 pExynosComponent->callbackData,
-                 OMX_EventPortSettingsChanged, /* The command was completed */
-                 OMX_DirOutput, /* This is the port index */
-                 0,
-                 NULL);
-        }
-    }
-    if ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth) ||
-        (pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight)) {
-        /* Check Crop */
-        pExynosInputPort->portDefinition.format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
-        pExynosInputPort->portDefinition.format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
-        pExynosInputPort->portDefinition.format.video.nStride = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
-        pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
-        Exynos_UpdateFrameSize(pOMXComponent);
-
-        /** Send crop info call back **/
-        (*(pExynosComponent->pCallbacks->EventHandler))
-            (pOMXComponent,
-             pExynosComponent->callbackData,
-             OMX_EventPortSettingsChanged, /* The command was completed */
-             OMX_DirOutput, /* This is the port index */
-             OMX_IndexConfigCommonOutputCrop,
-             NULL);
-    }
-
     Exynos_OSAL_SleepMillisec(0);
     ret = OMX_ErrorInputDataDecodeYet;
     H264CodecStop(pOMXComponent, INPUT_PORT_INDEX);
@@ -881,10 +1054,15 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
 
     int i, nOutbufs;
 
+    OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    OMX_U32 dataLen[MAX_BUFFER_PLANE]   = {0, 0, 0};
+
     FunctionIn();
 
-    /* get dpb count */
-    nOutbufs = pH264Dec->hMFCH264Handle.maxDPBNum;
+    for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++)
+        nAllocLen[i] = pH264Dec->hMFCH264Handle.codecOutbufConf.nAlignPlaneSize[i];
+
+    pOutbufOps->Set_Shareable(hMFCHandle);
 
     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
         /* should be done before prepare output buffer */
@@ -892,64 +1070,46 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
             ret = OMX_ErrorInsufficientResources;
             goto EXIT;
         }
-    }
-
-    pOutbufOps->Set_Shareable(hMFCHandle);
-    if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
-        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
-        ret = OMX_ErrorInsufficientResources;
-        goto EXIT;
-    }
 
-    ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE];
-    OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
-    OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
-    int plane;
+        /* get dpb count */
+        nOutbufs = pH264Dec->hMFCH264Handle.maxDPBNum;
+        if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
 
-    nAllocLen[0] = calc_plane(pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth,
-                        pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight);
-    nAllocLen[1] = calc_plane(pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth,
-                        pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight >> 1);
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
 
-    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
-        MEMORY_TYPE memoryType;
-        if (pVideoDec->bDRMPlayerMode == OMX_TRUE)
-            memoryType = SECURE_MEMORY;
-        else
-            memoryType = NORMAL_MEMORY;
+        ret = H264CodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
 
-        /* Register output buffer */
+        /* Enqueue output buffer */
         for (i = 0; i < nOutbufs; i++) {
-            pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
-            Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
-
-            for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
-                pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] =
-                    (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nAllocLen[plane], memoryType);
-                if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] == NULL) {
-                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer");
-                    ret = OMX_ErrorInsufficientResources;
-                    goto EXIT;
-                }
-                pVideoDec->pMFCDecOutputBuffer[i]->fd[plane] =
-                    Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory,
-                                                       pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]);
-                pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = nAllocLen[plane];
-
-                planes[plane].addr = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane];
-                planes[plane].fd = pVideoDec->pMFCDecOutputBuffer[i]->fd[plane];
-                planes[plane].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane];
-            }
-
-            if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
-                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
-                ret = OMX_ErrorInsufficientResources;
-                goto EXIT;
-            }
             pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
-                            (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
+                            (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL);
+        }
+
+        if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
         }
     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
+        ExynosVideoPlane planes[MAX_BUFFER_PLANE] = {0, 0, 0};
+        int plane;
+
+        /* get dpb count */
+        nOutbufs = pExynosOutputPort->portDefinition.nBufferCountActual;
+        if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
+            ret = OMX_ErrorInsufficientResources;
+            goto EXIT;
+        }
+
         /* Register output buffer */
         /*************/
         /*    TBD    */
@@ -957,19 +1117,25 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
 #ifdef USE_ANB
         if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) {
             for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
-                for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
+                for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) {
                     planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
                     planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
                     planes[plane].allocSize = nAllocLen[plane];
                 }
 
-                if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
+                if (pOutbufOps->Register(hMFCHandle, planes, pExynosOutputPort->nPlaneCnt) != VIDEO_ERROR_NONE) {
                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
                     ret = OMX_ErrorInsufficientResources;
                     goto EXIT;
                 }
                 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
-                               (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
+                               (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, NULL);
+            }
+
+            if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Apply output buffer");
+                ret = OMX_ErrorHardware;
+                goto EXIT;
             }
         } else {
             ret = OMX_ErrorNotImplemented;
@@ -981,15 +1147,6 @@ OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
 #endif
     }
 
-    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) {
-        H264CodecStop(pOMXComponent, OUTPUT_PORT_INDEX);
-    }
     pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE;
 
     ret = OMX_ErrorNone;
@@ -1528,6 +1685,7 @@ OMX_ERRORTYPE Exynos_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
     pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
     pExynosComponent->bUseFlagEOF = OMX_TRUE;
     pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
 
     /* H.264 Codec Open */
     ret = H264CodecOpen(pH264Dec);
@@ -1539,31 +1697,18 @@ OMX_ERRORTYPE Exynos_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
     pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
     pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
 
+    pExynosInputPort->nPlaneCnt = MFC_DEFAULT_INPUT_BUFFER_PLANE;
     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
+        OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0};
         Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
         Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
 
-        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
-            pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
-            Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
-            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
-
-            for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
-                /* Use ION Allocator */
-                pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, DEFAULT_MFC_INPUT_BUFFER_SIZE, NORMAL_MEMORY);
-                pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
-                pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
-                pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
-                if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] == NULL) {
-                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer");
-                    ret = OMX_ErrorInsufficientResources;
-                    goto EXIT;
-                }
-                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
-            }
+        ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nPlaneSize);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
 
+        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
             Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
-        }
     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
         /*************/
         /*    TBD    */
@@ -1571,6 +1716,7 @@ OMX_ERRORTYPE Exynos_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
         /* Does not require any actions. */
     }
 
+    pExynosOutputPort->nPlaneCnt = MFC_DEFAULT_OUTPUT_BUFFER_PLANE;
     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
         Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
         Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
@@ -1593,8 +1739,10 @@ OMX_ERRORTYPE Exynos_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
 
     pExynosComponent->getAllDelayBuffer = OMX_FALSE;
 
-#if 0//defined(USE_CSC_GSCALER)
-    csc_method = CSC_METHOD_HW; //in case of Use ION buffer.
+    Exynos_OSAL_QueueCreate(&pH264Dec->bypassBufferInfoQ, QUEUE_ELEMENTS);
+
+#ifdef USE_CSC_HW
+    csc_method = CSC_METHOD_HW;
 #endif
     if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
         pVideoDec->csc_handle = csc_init(CSC_METHOD_HW);
@@ -1640,6 +1788,8 @@ OMX_ERRORTYPE Exynos_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
         pVideoDec->csc_handle = NULL;
     }
 
+    Exynos_OSAL_QueueTerminate(&pH264Dec->bypassBufferInfoQ);
+
     Exynos_OSAL_SignalTerminate(pH264Dec->hDestinationStartEvent);
     pH264Dec->hDestinationStartEvent = NULL;
     pH264Dec->bDestinationStart = OMX_FALSE;
@@ -1648,18 +1798,7 @@ OMX_ERRORTYPE Exynos_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
     pH264Dec->bSourceStart = OMX_FALSE;
 
     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
-        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
-            if (pVideoDec->pMFCDecOutputBuffer[i] != NULL) {
-                for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
-                    if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] != NULL)
-                        Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]);
-                }
-
-                Exynos_OSAL_Free(pVideoDec->pMFCDecOutputBuffer[i]);
-                pVideoDec->pMFCDecOutputBuffer[i] = NULL;
-            }
-        }
-
+        Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
         Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
         Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
@@ -1670,17 +1809,7 @@ OMX_ERRORTYPE Exynos_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
     }
 
     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
-        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
-            if (pVideoDec->pMFCDecInputBuffer[i] != NULL) {
-                for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
-                    if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] != NULL)
-                        Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
-                }
-                Exynos_OSAL_Free(pVideoDec->pMFCDecInputBuffer[i]);
-                pVideoDec->pMFCDecInputBuffer[i] = NULL;
-            }
-        }
-
+        Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
         Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
@@ -1691,6 +1820,8 @@ OMX_ERRORTYPE Exynos_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
     }
     H264CodecClose(pH264Dec);
 
+    Exynos_ResetAllPortConfig(pOMXComponent);
+
 EXIT:
     FunctionOut();
 
@@ -1699,18 +1830,25 @@ EXIT:
 
 OMX_ERRORTYPE Exynos_H264Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
 {
-    OMX_ERRORTYPE               ret = OMX_ErrorNone;
-    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
-    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
-    EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
-    void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
-    EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
-    EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE         *pH264Dec          = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                          *hMFCHandle        = pH264Dec->hMFCH264Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    OMX_BUFFERHEADERTYPE tempBufferHeader;
+    void *pPrivate = NULL;
+
     OMX_U32  oneFrameSize = pSrcInputData->dataLen;
-    ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
-    ExynosVideoDecBufferOps *pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
-    ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
-    ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
+    OMX_BOOL bInStartCode = OMX_FALSE;
+
+    ExynosVideoDecOps       *pDecOps     = pH264Dec->hMFCH264Handle.pDecOps;
+    ExynosVideoDecBufferOps *pInbufOps   = pH264Dec->hMFCH264Handle.pInbufOps;
+    ExynosVideoDecBufferOps *pOutbufOps  = pH264Dec->hMFCH264Handle.pOutbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
     int i;
 
     FunctionIn();
@@ -1724,7 +1862,7 @@ OMX_ERRORTYPE Exynos_H264Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_
     }
 
     if (((pVideoDec->bDRMPlayerMode == OMX_TRUE) ||
-            (Check_H264_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize) == OMX_TRUE)) ||
+            ((bInStartCode = Check_H264_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize)) == OMX_TRUE)) ||
         ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
         pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp;
         pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags;
@@ -1732,11 +1870,29 @@ OMX_ERRORTYPE Exynos_H264Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_
         pDecOps->Set_FrameTag(hMFCHandle, pH264Dec->hMFCH264Handle.indexTimestamp);
         pH264Dec->hMFCH264Handle.indexTimestamp++;
         pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
-
+#ifdef USE_QOS_CTRL
+        if ((pVideoDec->bQosChanged == OMX_TRUE) &&
+            (pDecOps->Set_QosRatio != NULL)) {
+            pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio);
+            pVideoDec->bQosChanged = OMX_FALSE;
+        }
+#endif
         /* queue work for input buffer */
         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer);
-        codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
-                                    (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
+        OMX_U32 nAllocLen[MAX_BUFFER_PLANE] = {pSrcInputData->bufferHeader->nAllocLen, 0, 0};
+
+        if (pExynosInputPort->bufferProcessType == BUFFER_COPY) {
+            tempBufferHeader.nFlags     = pSrcInputData->nFlags;
+            tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
+            pPrivate = (void *)&tempBufferHeader;
+        } else {
+            pPrivate = (void *)pSrcInputData->bufferHeader;
+        }
+        codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
+                                (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
+                                (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.fd,
+                                (unsigned int *)nAllocLen, (unsigned int *)&oneFrameSize,
+                                pExynosInputPort->nPlaneCnt, pPrivate);
         if (codecReturn != VIDEO_ERROR_NONE) {
             ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
@@ -1753,6 +1909,9 @@ OMX_ERRORTYPE Exynos_H264Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_
             Exynos_OSAL_SignalSet(pH264Dec->hDestinationStartEvent);
             Exynos_OSAL_SleepMillisec(0);
         }
+    } else if (bInStartCode == OMX_FALSE) {
+        ret = OMX_ErrorCorruptedFrame;
+        goto EXIT;
     }
 
     ret = OMX_ErrorNone;
@@ -1774,43 +1933,52 @@ OMX_ERRORTYPE Exynos_H264Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX
     ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
     ExynosVideoDecBufferOps *pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
     ExynosVideoBuffer       *pVideoBuffer;
+    ExynosVideoBuffer        videoBuffer;
 
     FunctionIn();
 
-    pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
+    if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
+        pVideoBuffer = &videoBuffer;
+    else
+        pVideoBuffer = NULL;
 
     pSrcOutputData->dataLen       = 0;
     pSrcOutputData->usedDataLen   = 0;
     pSrcOutputData->remainDataLen = 0;
-    pSrcOutputData->nFlags    = 0;
-    pSrcOutputData->timeStamp = 0;
+    pSrcOutputData->nFlags        = 0;
+    pSrcOutputData->timeStamp     = 0;
+    pSrcOutputData->bufferHeader  = NULL;
 
     if (pVideoBuffer == NULL) {
         pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
         pSrcOutputData->allocSize  = 0;
         pSrcOutputData->pPrivate = NULL;
-        pSrcOutputData->bufferHeader = NULL;
     } else {
         pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
         pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
         pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize;
 
         if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
-            int i = 0;
-            while (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer != pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
-                if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
-                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
-                    ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
-                    goto EXIT;
+            int i;
+            for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
+                if (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer ==
+                        pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
+                    pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
+                    pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
+                    break;
                 }
-                i++;
             }
-            pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
-            pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
+
+            if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
+                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
+                ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+                goto EXIT;
+            }
         }
 
         /* For Share Buffer */
-        pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
+        if (pExynosInputPort->bufferProcessType == BUFFER_SHARE)
+            pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
     }
 
     ret = OMX_ErrorNone;
@@ -1823,16 +1991,19 @@ EXIT:
 
 OMX_ERRORTYPE Exynos_H264Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
 {
-    OMX_ERRORTYPE                  ret = OMX_ErrorNone;
-    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
-    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
-    EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
-    void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
-    EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
-    ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
-    ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
-    OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,};
-    ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
+    OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
+    EXYNOS_H264DEC_HANDLE           *pH264Dec           = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
+    void                            *hMFCHandle         = pH264Dec->hMFCH264Handle.hMFCHandle;
+    EXYNOS_OMX_BASEPORT             *pExynosOutputPort  = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    ExynosVideoDecOps       *pDecOps     = pH264Dec->hMFCH264Handle.pDecOps;
+    ExynosVideoDecBufferOps *pOutbufOps  = pH264Dec->hMFCH264Handle.pOutbufOps;
+    ExynosVideoErrorType     codecReturn = VIDEO_ERROR_NONE;
+
+    OMX_U32 dataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
+    int i;
 
     FunctionIn();
 
@@ -1842,12 +2013,22 @@ OMX_ERRORTYPE Exynos_H264Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_
         goto EXIT;
     }
 
-    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__,
-                                        pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0],
-                                        pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]);
+    for (i = 0; i < pExynosOutputPort->nPlaneCnt; i++) {
+        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[%d]: 0x%x", __FUNCTION__, __LINE__, i,
+                                        pDstInputData->buffer.multiPlaneBuffer.dataBuffer[i]);
+    }
+
+    if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
+        (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
+        (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
+        ret = H264CodecDstSetup(pOMXComponent);
+        if (ret != OMX_ErrorNone)
+            goto EXIT;
+        pVideoDec->bReconfigDPB = OMX_FALSE;
+    }
 
     codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer,
-                     (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
+                     (unsigned int *)dataLen, pExynosOutputPort->nPlaneCnt, pDstInputData->bufferHeader);
 
     if (codecReturn != VIDEO_ERROR_NONE) {
         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
@@ -1890,7 +2071,14 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX
     }
 
     while (1) {
-        if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) {
+        pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
+        if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
+            ret = OMX_ErrorHardware;
+            goto EXIT;
+        }
+
+        if (pVideoBuffer == NULL) {
             ret = OMX_ErrorNone;
             goto EXIT;
         }
@@ -1900,17 +2088,50 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX
         if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
             (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
             (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+            (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
+            (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D) ||
             (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
             ret = OMX_ErrorNone;
             break;
         }
     }
 
+
+#ifdef USE_S3D_SUPPORT
+    /* Check Whether frame packing information is available */
+    if ((pH264Dec->hMFCH264Handle.S3DFPArgmtType == OMX_SEC_FPARGMT_INVALID) &&
+        (pVideoDec->bThumbnailMode == OMX_FALSE) &&
+        ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
+         (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
+         (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D))) {
+        if (H264CodecCheckFramePacking(pOMXComponent) != OMX_TRUE) {
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            goto EXIT;
+        }
+    }
+#endif
+
+    if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
+        ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+         (displayStatus == VIDEO_FRAME_STATUS_ENABLED_S3D))) {
+        if (pVideoDec->bReconfigDPB != OMX_TRUE) {
+            pExynosOutputPort->exceptionFlag = NEED_PORT_FLUSH;
+            pVideoDec->bReconfigDPB = OMX_TRUE;
+            H264CodecCheckResolutionChange(pOMXComponent);
+            pVideoDec->csc_set_format = OMX_FALSE;
+#ifdef USE_S3D_SUPPORT
+            pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_INVALID;
+#endif
+        }
+        ret = OMX_ErrorNone;
+        goto EXIT;
+    }
+
     pH264Dec->hMFCH264Handle.outputIndexTimestamp++;
     pH264Dec->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
 
     pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
-    for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
+    for (plane = 0; plane < pExynosOutputPort->nPlaneCnt; plane++) {
         pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
         pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
         pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
@@ -1918,6 +2139,24 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX
     }
     pDstOutputData->usedDataLen = 0;
     pDstOutputData->pPrivate = pVideoBuffer;
+    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
+        int i = 0;
+        pDstOutputData->pPrivate = NULL;
+        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+            if (pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[0] ==
+                pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
+                pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
+                break;
+            }
+        }
+
+        if (pDstOutputData->pPrivate == NULL) {
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
+            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
+            goto EXIT;
+        }
+    }
+
     /* For Share Buffer */
     pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
 
@@ -1929,29 +2168,36 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX
     case VIDEO_COLORFORMAT_NV12:
         pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
         break;
+#ifdef USE_DUALDPB_MODE
+    case VIDEO_COLORFORMAT_I420:
+        pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420Planar;
+        break;
+    case VIDEO_COLORFORMAT_YV12:
+        pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatYVU420Planar;
+        break;
+    case VIDEO_COLORFORMAT_NV21:
+        pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV21Linear;
+        break;
+#endif
     case VIDEO_COLORFORMAT_NV12_TILED:
     default:
         pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled;
         break;
     }
 
-#ifdef USE_S3D_SUPPORT
-    /* Check Whether frame packing information is available */
-    if (pExynosOutputPort->bufferProcessType & BUFFER_COPY &&
-        pVideoDec->bThumbnailMode == OMX_FALSE &&
-        pH264Dec->hMFCH264Handle.S3DFPArgmtType == OMX_SEC_FPARGMT_NONE) {
-        H264CodecCheckFramePacking(pOMXComponent);
-    }
-#endif
-
     indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp);
     if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
         if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
             (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
-            pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
-            pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
-            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp);
+            if (indexTimestamp == INDEX_AFTER_EOS) {
+                pDstOutputData->timeStamp = 0x00;
+                pDstOutputData->nFlags = 0x00;
+            } else {
+                pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
+                pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
+                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp);
+            }
         } else {
             pDstOutputData->timeStamp = 0x00;
             pDstOutputData->nFlags = 0x00;
@@ -1959,26 +2205,34 @@ OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX
     } else {
         /* For timestamp correction. if mfc support frametype detect */
         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType);
-#ifdef NEED_TIMESTAMP_REORDER
-        if ((pVideoBuffer->frameType == VIDEO_FRAME_I)) {
-            pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
-            pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
-            pH264Dec->hMFCH264Handle.outputIndexTimestamp = indexTimestamp;
-        } else {
-            pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
-            pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
+
+        /* NEED TIMESTAMP REORDER */
+        if (pVideoDec->bDTSMode == OMX_TRUE) {
+            if ((pVideoBuffer->frameType == VIDEO_FRAME_I) ||
+                ((pVideoBuffer->frameType == VIDEO_FRAME_OTHERS) &&
+                    ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) ||
+                (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE))
+                pH264Dec->hMFCH264Handle.outputIndexTimestamp = indexTimestamp;
+            else
+                indexTimestamp = pH264Dec->hMFCH264Handle.outputIndexTimestamp;
         }
-#else
+
         pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
         pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
-#endif
+
         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
     }
 
-    if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
+    if ((displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
         ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags);
         pDstOutputData->remainDataLen = 0;
+
+        if (((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) &&
+            (pExynosComponent->bBehaviorEOS == OMX_TRUE)) {
+            pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
+            pExynosComponent->bBehaviorEOS = OMX_FALSE;
+        }
     } else {
         pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
     }
@@ -2010,7 +2264,9 @@ OMX_ERRORTYPE Exynos_H264Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXCompon
     }
 
     ret = Exynos_H264Dec_SrcIn(pOMXComponent, pSrcInputData);
-    if ((ret != OMX_ErrorNone) && (ret != OMX_ErrorInputDataDecodeYet)) {
+    if ((ret != OMX_ErrorNone) &&
+        (ret != OMX_ErrorInputDataDecodeYet) &&
+        (ret != OMX_ErrorCorruptedFrame)) {
         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
                                                 pExynosComponent->callbackData,
                                                 OMX_EventError, ret, 0, NULL);
@@ -2084,6 +2340,21 @@ OMX_ERRORTYPE Exynos_H264Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXCompon
             Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
             Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent);
         }
+        if (Exynos_OSAL_GetElemNum(&pH264Dec->bypassBufferInfoQ) > 0) {
+            BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pH264Dec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            pDstInputData->bufferHeader->nFlags     = pBufferInfo->nFlags;
+            pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
     }
     if (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) {
         ret = Exynos_H264Dec_DstIn(pOMXComponent, pDstInputData);
@@ -2124,6 +2395,38 @@ OMX_ERRORTYPE Exynos_H264Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXCompo
             Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
             Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent);
         }
+
+        if (Exynos_OSAL_GetElemNum(&pH264Dec->bypassBufferInfoQ) > 0) {
+            EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer   = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
+            OMX_BUFFERHEADERTYPE  *pOMXBuffer           = NULL;
+            BYPASS_BUFFER_INFO    *pBufferInfo          = NULL;
+
+            if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
+                pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
+                if (pOMXBuffer == NULL) {
+                    ret = OMX_ErrorUndefined;
+                    goto EXIT;
+                }
+            } else {
+                pOMXBuffer = dstOutputUseBuffer->bufferHeader;
+            }
+
+            pBufferInfo = Exynos_OSAL_Dequeue(&pH264Dec->bypassBufferInfoQ);
+            if (pBufferInfo == NULL) {
+                ret = OMX_ErrorUndefined;
+                goto EXIT;
+            }
+
+            pOMXBuffer->nFlags      = pBufferInfo->nFlags;
+            pOMXBuffer->nTimeStamp  = pBufferInfo->timeStamp;
+            Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
+            Exynos_OSAL_Free(pBufferInfo);
+
+            dstOutputUseBuffer->dataValid = OMX_FALSE;
+
+            ret = OMX_ErrorNone;
+            goto EXIT;
+        }
     }
     ret = Exynos_H264Dec_DstOut(pOMXComponent, pDstOutputData);
     if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
@@ -2202,7 +2505,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent
 
     pVideoDec->bDRMPlayerMode = bDRMPlayerMode;
 #ifdef USE_S3D_SUPPORT
-    pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_NONE;
+    pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_INVALID;
 #endif
 
     /* Set componentVersion */
@@ -2283,6 +2586,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent
     pVideoDec->exynos_checkInputFrame                 = &Check_H264_Frame;
     pVideoDec->exynos_codec_getCodecInputPrivateData  = &GetCodecInputPrivateData;
     pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
+    pVideoDec->exynos_codec_reconfigAllBuffers        = &H264CodecReconfigAllBuffers;
 
     pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
     if (pVideoDec->hSharedMemory == NULL) {