osal: Fix OSAL lock anb type casting
[GitHub/LineageOS/android_hardware_samsung_slsi_openmax.git] / component / video / dec / Exynos_OMX_Vdec.c
index 145c210abe60546993ee89ad093e64d77fc30544..154f8142ea7d5a4797ea7a8ae241284e23f01ffd 100644 (file)
 //#define EXYNOS_TRACE_ON
 #include "Exynos_OSAL_Log.h"
 
-
-int calc_plane(int width, int height)
-{
-    int mbX, mbY;
-
-    mbX = (width + 15)/16;
-    mbY = (height + 15)/16;
-
-    /* Alignment for interlaced processing */
-    mbY = (mbY + 1) / 2 * 2;
-
-    return (mbX * 16) * (mbY * 16);
-}
-
 inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent)
 {
     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
@@ -91,18 +77,12 @@ inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent)
         switch(exynosOutputPort->portDefinition.format.video.eColorFormat) {
         case OMX_COLOR_FormatYUV420Planar:
         case OMX_COLOR_FormatYUV420SemiPlanar:
+        case OMX_SEC_COLOR_FormatNV12Tiled:
+        case OMX_SEC_COLOR_FormatYVU420Planar:
+        case OMX_SEC_COLOR_FormatNV21Linear:
             if (width && height)
                 exynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2;
             break;
-        case OMX_SEC_COLOR_FormatNV12Tiled:
-            width = exynosOutputPort->portDefinition.format.video.nFrameWidth;
-            height = exynosOutputPort->portDefinition.format.video.nFrameHeight;
-            if (width && height) {
-                int YBufferSize = calc_plane(width, height);
-                int CBufferSize = calc_plane(width, height >> 1);
-                exynosOutputPort->portDefinition.nBufferSize = YBufferSize + CBufferSize;
-            }
-            break;
         default:
             if (width && height)
                 exynosOutputPort->portDefinition.nBufferSize = width * height * 2;
@@ -122,20 +102,21 @@ void Exynos_Free_CodecBuffers(
     EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
     CODEC_DEC_BUFFER               **ppCodecBuffer      = NULL;
 
-    OMX_U32 nPlaneCnt = 0;
+    OMX_U32 nBufferCnt = 0, nPlaneCnt = 0;
     int i, j;
 
     FunctionIn();
 
     if (nPortIndex == INPUT_PORT_INDEX) {
         ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
-        nPlaneCnt = MFC_INPUT_BUFFER_PLANE;
+        nBufferCnt = MFC_INPUT_BUFFER_NUM_MAX;
     } else {
         ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
-        nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE;
+        nBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX;
     }
+    nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt;
 
-    for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
+    for (i = 0; i < nBufferCnt; i++) {
         if (ppCodecBuffer[i] != NULL) {
             for (j = 0; j < nPlaneCnt; j++) {
                 if (ppCodecBuffer[i]->pVirAddr[j] != NULL)
@@ -154,7 +135,7 @@ OMX_ERRORTYPE Exynos_Allocate_CodecBuffers(
     OMX_COMPONENTTYPE   *pOMXComponent,
     OMX_U32              nPortIndex,
     OMX_U32              nBufferCnt,
-    OMX_U32              nPlaneSize[MFC_OUTPUT_BUFFER_PLANE])
+    OMX_U32              nPlaneSize[MAX_BUFFER_PLANE])
 {
     OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
     EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
@@ -167,19 +148,18 @@ OMX_ERRORTYPE Exynos_Allocate_CodecBuffers(
 
     FunctionIn();
 
-    if (pVideoDec->bDRMPlayerMode == OMX_TRUE)
-        eMemoryType = SECURE_MEMORY;
-
     if (nPortIndex == INPUT_PORT_INDEX) {
         ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
-        nPlaneCnt = MFC_INPUT_BUFFER_PLANE;
     } else {
         ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
-        nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE;
 #ifdef USE_CSC_HW
         eMemoryType = NORMAL_MEMORY;
 #endif
     }
+    nPlaneCnt = pExynosComponent->pExynosPort[nPortIndex].nPlaneCnt;
+
+    if (pVideoDec->bDRMPlayerMode == OMX_TRUE)
+        eMemoryType = SECURE_MEMORY;
 
     for (i = 0; i < nBufferCnt; i++) {
         ppCodecBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
@@ -234,6 +214,49 @@ OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosCompo
     return ret;
 }
 
+OMX_ERRORTYPE Exynos_ResetAllPortConfig(OMX_COMPONENTTYPE *pOMXComponent)
+{
+    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
+    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+    EXYNOS_OMX_BASEPORT           *pInputPort        = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
+    EXYNOS_OMX_BASEPORT           *pOutputPort       = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
+
+    /* Input port */
+    pInputPort->portDefinition.format.video.nFrameWidth             = DEFAULT_FRAME_WIDTH;
+    pInputPort->portDefinition.format.video.nFrameHeight            = DEFAULT_FRAME_HEIGHT;
+    pInputPort->portDefinition.format.video.nStride                 = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pInputPort->portDefinition.format.video.nSliceHeight            = 0;
+    pInputPort->portDefinition.format.video.pNativeRender           = 0;
+    pInputPort->portDefinition.format.video.bFlagErrorConcealment   = OMX_FALSE;
+    pInputPort->portDefinition.format.video.eColorFormat            = OMX_COLOR_FormatUnused;
+
+    pInputPort->portDefinition.nBufferSize  = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
+    pInputPort->portDefinition.bEnabled     = OMX_TRUE;
+
+    pInputPort->bufferProcessType   = BUFFER_SHARE;
+    pInputPort->portWayType         = WAY2_PORT;
+    pInputPort->nPlaneCnt           = MFC_DEFAULT_INPUT_BUFFER_PLANE;
+
+    /* Output port */
+    pOutputPort->portDefinition.format.video.nFrameWidth            = DEFAULT_FRAME_WIDTH;
+    pOutputPort->portDefinition.format.video.nFrameHeight           = DEFAULT_FRAME_HEIGHT;
+    pOutputPort->portDefinition.format.video.nStride                = 0; /*DEFAULT_FRAME_WIDTH;*/
+    pOutputPort->portDefinition.format.video.nSliceHeight           = 0;
+    pOutputPort->portDefinition.format.video.pNativeRender          = 0;
+    pOutputPort->portDefinition.format.video.bFlagErrorConcealment  = OMX_FALSE;
+    pOutputPort->portDefinition.format.video.eColorFormat           = OMX_COLOR_FormatYUV420Planar;
+
+    pOutputPort->portDefinition.nBufferSize  = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
+    pOutputPort->portDefinition.bEnabled     = OMX_TRUE;
+
+    pOutputPort->bufferProcessType  = BUFFER_COPY | BUFFER_ANBSHARE;
+    pOutputPort->bIsANBEnabled      = OMX_FALSE;
+    pOutputPort->portWayType        = WAY2_PORT;
+    pOutputPort->nPlaneCnt          = Exynos_OSAL_GetPlaneCount(OMX_COLOR_FormatYUV420Planar);
+
+    return ret;
+}
+
 OMX_ERRORTYPE Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData)
 {
     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
@@ -314,108 +337,150 @@ OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA
     EXYNOS_OMX_DATABUFFER         *outputUseBuffer  = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
     OMX_U32                        copySize         = 0;
     DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo      = NULL;
+    OMX_COLOR_FORMATTYPE           eColorFormat     = exynosOutputPort->portDefinition.format.video.eColorFormat;
 
     FunctionIn();
 
-    OMX_U32 width = 0, height = 0;
-    int imageSize = 0;
-    OMX_COLOR_FORMATTYPE colorFormat;
-
-    void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer;
+    void *pOutputBuf                = (void *)outputUseBuffer->bufferHeader->pBuffer;
     void *pSrcBuf[MAX_BUFFER_PLANE] = {NULL, };
     void *pYUVBuf[MAX_BUFFER_PLANE] = {NULL, };
 
-    CSC_ERRORCODE cscRet = CSC_ErrorNone;
-    CSC_METHOD csc_method = CSC_METHOD_SW;
+    ExynosVideoPlane planes[MAX_BUFFER_PLANE];
+    OMX_U32          nPlaneSize[MAX_BUFFER_PLANE] = {0, 0, 0};
+
+    OMX_U32 nFrameWidth = 0, nFrameHeight = 0;
+    OMX_U32 nImageWidth = 0, nImageHeight = 0, stride = 0;
+
+    CSC_MEMTYPE     csc_memType = CSC_MEMORY_USERPTR;
+    CSC_METHOD      csc_method  = CSC_METHOD_SW;
+    CSC_ERRORCODE   cscRet      = CSC_ErrorNone;
     unsigned int srcCacheable = 1, dstCacheable = 1;
 
-    pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo;
+    nFrameWidth  = exynosOutputPort->portDefinition.format.video.nStride;
+    nFrameHeight = exynosOutputPort->portDefinition.format.video.nSliceHeight;
 
-    width = pBufferInfo->imageWidth;
-    height = pBufferInfo->imageHeight;
-    imageSize = width * height;
-    colorFormat = pBufferInfo->ColorFormat;
+    pBufferInfo  = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo;
+    nImageWidth  = pBufferInfo->imageWidth;
+    nImageHeight = pBufferInfo->imageHeight;
 
     pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0];
     pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1];
     pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[2];
 
-    pYUVBuf[0]  = (unsigned char *)pOutputBuf;
-    pYUVBuf[1]  = (unsigned char *)pOutputBuf + imageSize;
-    pYUVBuf[2]  = (unsigned char *)pOutputBuf + imageSize + imageSize / 4;
-
-    csc_get_method(pVideoDec->csc_handle, &csc_method);
-    if (csc_method == CSC_METHOD_HW)
-        srcCacheable = 0;
+    Exynos_OSAL_GetPlaneSize(eColorFormat, nImageWidth, nImageHeight, nPlaneSize);
 
-#ifdef USE_DMA_BUF
-    if (csc_method == CSC_METHOD_HW) {
-        pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0];
-        pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1];
-        pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.fd[2];
-    }
-#endif
+    pYUVBuf[0]  = (unsigned char *)pOutputBuf;
+    pYUVBuf[1]  = (unsigned char *)pOutputBuf + nPlaneSize[0];
+    pYUVBuf[2]  = (unsigned char *)pOutputBuf + nPlaneSize[0] + nPlaneSize[1];
 
 #ifdef USE_ANB
     if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) {
-        ExynosVideoPlane planes[MAX_BUFFER_PLANE];
-        OMX_U32 stride;
-        Exynos_OSAL_LockANB(pOutputBuf, width, height, exynosOutputPort->portDefinition.format.video.eColorFormat, &stride, planes);
-        width = stride;
+        Exynos_OSAL_LockANBHandle(pOutputBuf, nImageWidth, nImageHeight, eColorFormat, &stride, planes);
+        nImageWidth = stride;
         outputUseBuffer->dataLen = sizeof(void *);
 
         pYUVBuf[0]  = (unsigned char *)planes[0].addr;
         pYUVBuf[1]  = (unsigned char *)planes[1].addr;
         pYUVBuf[2]  = (unsigned char *)planes[2].addr;
+    }
+#endif
+
+    if (pVideoDec->bDualDPBMode == OMX_TRUE) {
+        switch (eColorFormat) {
+        case OMX_COLOR_FormatYUV420SemiPlanar:
+        case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear:
+        case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled:
+        case OMX_COLOR_FormatYUV420Planar:
+        case (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar:
+            csc_set_method(pVideoDec->csc_handle, CSC_METHOD_SW);
+            csc_memType = CSC_MEMORY_MFC;
+            if (pVideoDec->csc_set_format == OMX_FALSE) {
+                csc_set_src_format(
+                    pVideoDec->csc_handle,                              /* handle */
+                    nFrameWidth,                                        /* width */
+                    nFrameHeight,                                       /* height */
+                    0,                                                  /* crop_left */
+                    0,                                                  /* crop_right */
+                    nImageWidth,                                        /* crop_width */
+                    nImageHeight,                                       /* crop_height */
+                    omx_2_hal_pixel_format(pBufferInfo->ColorFormat),   /* color_format */
+                    0);                                                 /* cacheable */
+                csc_set_dst_format(
+                    pVideoDec->csc_handle,                              /* handle */
+                    nImageWidth,                                        /* width */
+                    nImageHeight,                                       /* height */
+                    0,                                                  /* crop_left */
+                    0,                                                  /* crop_right */
+                    nImageWidth,                                        /* crop_width */
+                    nImageHeight,                                       /* crop_height */
+                    omx_2_hal_pixel_format(eColorFormat),               /* color_format */
+                    0);                                                 /* cacheable */
+                pVideoDec->csc_set_format = OMX_TRUE;
+            }
+            break;
+        default:
+            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unspported color format : %x. can't support this format", __FUNCTION__, eColorFormat);
+            ret = OMX_FALSE;
+            goto EXIT;
+            break;
+        }
+    } else {
+        csc_get_method(pVideoDec->csc_handle, &csc_method);
+        if (csc_method == CSC_METHOD_HW)
+            srcCacheable = 0;
+
 #ifdef USE_DMA_BUF
         if (csc_method == CSC_METHOD_HW) {
-            pYUVBuf[0]  = (unsigned char *)planes[0].fd;
-            pYUVBuf[1]  = (unsigned char *)planes[1].fd;
-            pYUVBuf[2]  = (unsigned char *)planes[2].fd;
+            csc_memType = CSC_MEMORY_DMABUF;
+
+            pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0];
+            pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1];
+            pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.fd[2];
+
+            if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) {
+                pYUVBuf[0]  = (unsigned char *)planes[0].fd;
+                pYUVBuf[1]  = (unsigned char *)planes[1].fd;
+                pYUVBuf[2]  = (unsigned char *)planes[2].fd;
+            } else {
+                pYUVBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf);
+                pYUVBuf[1] = NULL;
+                pYUVBuf[2] = NULL;
+            }
         }
 #endif
+        if (pVideoDec->csc_set_format == OMX_FALSE) {
+            csc_set_src_format(
+                pVideoDec->csc_handle,                              /* handle */
+                nImageWidth,                                        /* width */
+                nImageHeight,                                       /* height */
+                0,                                                  /* crop_left */
+                0,                                                  /* crop_right */
+                nImageWidth,                                        /* crop_width */
+                nImageHeight,                                       /* crop_height */
+                omx_2_hal_pixel_format(pBufferInfo->ColorFormat),   /* color_format */
+                srcCacheable);                                      /* cacheable */
+            csc_set_dst_format(
+                pVideoDec->csc_handle,                              /* handle */
+                nImageWidth,                                        /* width */
+                nImageHeight,                                       /* height */
+                0,                                                  /* crop_left */
+                0,                                                  /* crop_right */
+                nImageWidth,                                        /* crop_width */
+                nImageHeight,                                       /* crop_height */
+                omx_2_hal_pixel_format(eColorFormat),               /* color_format */
+                dstCacheable);                                      /* cacheable */
+            pVideoDec->csc_set_format = OMX_TRUE;
+        }
     }
-#endif
-#ifdef USE_DMA_BUF
-    if ((exynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
-        (csc_method == CSC_METHOD_HW)) {
-        pYUVBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf);
-        pYUVBuf[1] = NULL;
-        pYUVBuf[2] = NULL;
-    }
-#endif
 
-    if (pVideoDec->csc_set_format == OMX_FALSE) {
-        csc_set_src_format(
-            pVideoDec->csc_handle,  /* handle */
-            width,            /* width */
-            height,           /* height */
-            0,                /* crop_left */
-            0,                /* crop_right */
-            width,            /* crop_width */
-            height,           /* crop_height */
-            omx_2_hal_pixel_format(colorFormat), /* color_format */
-            srcCacheable);             /* cacheable */
-        csc_set_dst_format(
-            pVideoDec->csc_handle,  /* handle */
-            width,           /* width */
-            height,           /* height */
-            0,                /* crop_left */
-            0,                /* crop_right */
-            width,           /* crop_width */
-            height,           /* crop_height */
-            omx_2_hal_pixel_format(exynosOutputPort->portDefinition.format.video.eColorFormat), /* color_format */
-            dstCacheable);             /* cacheable */
-        pVideoDec->csc_set_format = OMX_TRUE;
-    }
     csc_set_src_buffer(
         pVideoDec->csc_handle,  /* handle */
         pSrcBuf,
-        CSC_MEMORY_DMABUF);    /* YUV Addr or FD */
+        csc_memType);           /* YUV Addr or FD */
     csc_set_dst_buffer(
         pVideoDec->csc_handle,  /* handle */
         pYUVBuf,
-        CSC_MEMORY_DMABUF);    /* YUV Addr or FD */
+        csc_memType);           /* YUV Addr or FD */
     cscRet = csc_convert(pVideoDec->csc_handle);
     if (cscRet != CSC_ErrorNone)
         ret = OMX_FALSE;
@@ -424,7 +489,7 @@ OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA
 
 #ifdef USE_ANB
     if (exynosOutputPort->bIsANBEnabled == OMX_TRUE) {
-        Exynos_OSAL_UnlockANB(pOutputBuf);
+        Exynos_OSAL_UnlockANBHandle(pOutputBuf);
     }
 #endif
 
@@ -469,7 +534,12 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_
                     goto EXIT;
                 }
 
+                srcInputData->buffer.singlePlaneBuffer.fd = srcInputData->buffer.singlePlaneBuffer.dataBuffer;
                 srcInputData->buffer.singlePlaneBuffer.dataBuffer = dataBuffer;
+            } else {
+                srcInputData->buffer.singlePlaneBuffer.fd =
+                    Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory,
+                                srcInputData->buffer.singlePlaneBuffer.dataBuffer);
             }
 
             /* reset dataBuffer */
@@ -512,9 +582,9 @@ OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_
 
         if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE");
-            srcInputData->dataLen = 0;
-            srcInputData->remainDataLen = 0;
             pExynosComponent->bSaveFlagEOS = OMX_TRUE;
+            if (srcInputData->dataLen != 0)
+                pExynosComponent->bBehaviorEOS = OMX_TRUE;
         }
 
         if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
@@ -574,16 +644,16 @@ OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_
                 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
                 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
             } else {
-                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "drop frame after seeking", pExynosComponent);
-                if (exynosOutputPort->bufferProcessType & BUFFER_SHARE)
-                    Exynos_OMX_FillThisBuffer(pOMXComponent, outputUseBuffer->bufferHeader);
-
                 if (pExynosComponent->checkTimeStamp.startTimeStamp < dstOutputData->timeStamp) {
                     pExynosComponent->checkTimeStamp.startTimeStamp = -19761123;
                     pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
                     pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
                     pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
                 } else {
+                    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "drop frame after seeking", pExynosComponent);
+                    if (exynosOutputPort->bufferProcessType & BUFFER_SHARE)
+                        Exynos_OMX_FillThisBuffer(pOMXComponent, outputUseBuffer->bufferHeader);
+
                     ret = OMX_TRUE;
                     goto EXIT;
                 }
@@ -595,16 +665,6 @@ OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_
         }
 
         if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
-            OMX_U32 width = 0, height = 0;
-            int imageSize = 0;
-            void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer;
-
-            pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo;
-
-            width = pBufferInfo->imageWidth;
-            height = pBufferInfo->imageHeight;
-            imageSize = width * height;
-
             if ((dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) &&
                 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
                 copySize = dstOutputData->remainDataLen;
@@ -652,6 +712,8 @@ OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_
                 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
                 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)))
                 Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
+            else
+                Exynos_OMX_FillThisBuffer(pOMXComponent, outputUseBuffer->bufferHeader);
         }
     } else {
         ret = OMX_FALSE;
@@ -687,7 +749,8 @@ OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent)
             Exynos_OSAL_SleepMillisec(0);
 
             if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort)) ||
-                ((exynosOutputPort->exceptionFlag == NEED_PORT_DISABLE) && (ret == OMX_ErrorInputDataDecodeYet)))
+                ((exynosOutputPort->exceptionFlag == NEED_PORT_DISABLE) && (ret == OMX_ErrorInputDataDecodeYet)) ||
+                (exynosOutputPort->exceptionFlag == INVALID_STATE))
                 break;
             if (exynosInputPort->portState != OMX_StateIdle)
                 break;
@@ -862,6 +925,11 @@ OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent)
                                 break;
                             }
                         }
+
+                        OMX_PTR pBufferHandle = dstInputData.bufferHeader->pBuffer;
+                        if (exynosOutputPort->bStoreMetaData == OMX_TRUE) {
+                            Exynos_OSAL_GetInfoFromMetaData(dstInputData.bufferHeader->pBuffer, &pBufferHandle);
+                        }
                         Exynos_ResetDataBuffer(dstInputUseBuffer);
                     }
                 }
@@ -1145,6 +1213,9 @@ OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent)
     Exynos_OSAL_ThreadTerminate(pVideoDec->hDstOutputThread);
     pVideoDec->hDstOutputThread = NULL;
 
+    pExynosComponent->checkTimeStamp.needSetStartTimeStamp      = OMX_FALSE;
+    pExynosComponent->checkTimeStamp.needCheckStartTimeStamp    = OMX_FALSE;
+
 EXIT:
     FunctionOut();
 
@@ -1197,10 +1268,14 @@ OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hCompone
 
     Exynos_OSAL_Memset(pVideoDec, 0, sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
     pVideoDec->bReconfigDPB = OMX_FALSE;
-    pVideoDec->nSavedDPBCnt = 0;
+    pVideoDec->bDTSMode     = OMX_FALSE;
+    pVideoDec->bQosChanged  = OMX_FALSE;
+    pVideoDec->nQosRatio    = 0;
+    pVideoDec->bDualDPBMode = OMX_FALSE;
     pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec;
 
     pExynosComponent->bSaveFlagEOS = OMX_FALSE;
+    pExynosComponent->bBehaviorEOS = OMX_FALSE;
     pExynosComponent->bMultiThreadProcess = OMX_TRUE;
 
     /* Input port */