From 233728c3cba5b5916244919eb44d0a33e79cd5b4 Mon Sep 17 00:00:00 2001 From: SeungBeom Kim Date: Mon, 30 Mar 2015 17:30:43 +0200 Subject: [PATCH] video_dec: Add Dynamic resolution support for MPEG4 and VP8. Backported-from: hardware/samsung_slsi/exynos5 Change-Id: I4581c613a07fa13925376fcca384ba8ccec008db Signed-off-by: Andreas Schneider --- .../video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c | 261 +++++++++++++----- component/video/dec/vp8/Exynos_OMX_Vp8dec.c | 261 +++++++++++++----- 2 files changed, 390 insertions(+), 132 deletions(-) diff --git a/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c b/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c index f582d24..06d55a4 100644 --- a/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c +++ b/component/video/dec/mpeg4/Exynos_OMX_Mpeg4dec.c @@ -703,6 +703,61 @@ EXIT: return ret; } +OMX_ERRORTYPE Mpeg4CodecReconfigAllBuffers( + 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_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + ExynosVideoDecBufferOps *pBufferOps = NULL; + + FunctionIn(); + + if ((nPortIndex == INPUT_PORT_INDEX) && + (pMpeg4Dec->bSourceStart == OMX_TRUE)) { + ret = OMX_ErrorNotImplemented; + goto EXIT; + } else if ((nPortIndex == OUTPUT_PORT_INDEX) && + (pMpeg4Dec->bDestinationStart == OMX_TRUE)) { + pBufferOps = pMpeg4Dec->hMFCMpeg4Handle.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); + } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) { + /**********************************/ + /* Codec Buffer Unregister */ + /**********************************/ + pBufferOps->Clear_RegisteredBuffer(hMFCHandle); + pBufferOps->Cleanup_Buffer(hMFCHandle); + } + /******************************************************/ + /* V4L2 Destnation Setup for DPB Buffer Number Change */ + /******************************************************/ + Mpeg4CodecDstSetup(pOMXComponent); + pVideoDec->bReconfigDPB = OMX_FALSE; + + Exynos_ResolutionUpdate(pOMXComponent); + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + +EXIT: + FunctionOut(); + + return ret; +} + OMX_ERRORTYPE Mpeg4CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) { OMX_ERRORTYPE ret = OMX_ErrorNone; @@ -756,6 +811,131 @@ EXIT: return ret; } +OMX_ERRORTYPE Mpeg4CodecCheckResolutionChange(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_MPEG4DEC_HANDLE *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + ExynosVideoDecOps *pDecOps = pMpeg4Dec->hMFCMpeg4Handle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps; + + OMX_CONFIG_RECTTYPE *pCropRectangle = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = NULL; + + FunctionIn(); + /* get geometry for output */ + Exynos_OSAL_Memset(&pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry)); + if (pOutbufOps->Get_Geometry(hMFCHandle, &pMpeg4Dec->hMFCMpeg4Handle.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 */ + pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle); + if (pVideoDec->bThumbnailMode == OMX_FALSE) + pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum += EXTRA_DPB_NUM; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "H264CodecSetup nOutbufs: %d", pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum); + + pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_TRUE; + + if (pVideoDec->bReconfigDPB != OMX_TRUE) { + pCropRectangle = &(pOutputPort->cropRectangle); + pInputPortDefinition = &(pInputPort->portDefinition); + pOutputPortDefinition = &(pOutputPort->portDefinition); + } else { + pCropRectangle = &(pOutputPort->newCropRectangle); + pInputPortDefinition = &(pInputPort->newPortDefinition); + pOutputPortDefinition = &(pOutputPort->newPortDefinition); + } + + pCropRectangle->nTop = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nTop; + pCropRectangle->nLeft = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nLeft; + pCropRectangle->nWidth = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nWidth; + pCropRectangle->nHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nHeight; + + if (pOutputPort->bufferProcessType & BUFFER_COPY) { + if ((pVideoDec->bReconfigDPB) || + (pInputPort->portDefinition.format.video.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) || + (pInputPort->portDefinition.format.video.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight)) { + pInputPortDefinition->format.video.nFrameWidth = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth; + pInputPortDefinition->format.video.nFrameHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight; + pInputPortDefinition->format.video.nStride = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pInputPortDefinition->format.video.nSliceHeight = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); + pOutputPortDefinition->nBufferCountActual = pOutputPort->portDefinition.nBufferCountActual; + pOutputPortDefinition->nBufferCountMin = pOutputPort->portDefinition.nBufferCountMin; + if (pVideoDec->bReconfigDPB != OMX_TRUE) + Exynos_UpdateFrameSize(pOMXComponent); + pOutputPort->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 (pOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((pVideoDec->bReconfigDPB) || + (pInputPort->portDefinition.format.video.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) || + (pInputPort->portDefinition.format.video.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight) || + (pOutputPort->portDefinition.nBufferCountActual != pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum)) { + pInputPortDefinition->format.video.nFrameWidth = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth; + pInputPortDefinition->format.video.nFrameHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight; + pInputPortDefinition->format.video.nStride = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pInputPortDefinition->format.video.nSliceHeight = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); + pOutputPortDefinition->nBufferCountActual = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum; + pOutputPortDefinition->nBufferCountMin = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum; + if (pVideoDec->bReconfigDPB != OMX_TRUE) + Exynos_UpdateFrameSize(pOMXComponent); + pOutputPort->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 ((pVideoDec->bReconfigDPB == OMX_TRUE) || + (pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nWidth) || + (pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.cropRect.nHeight)) { + /* Check Crop */ + pInputPortDefinition->format.video.nFrameWidth = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth; + pInputPortDefinition->format.video.nFrameHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight; + pInputPortDefinition->format.video.nStride = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pInputPortDefinition->format.video.nSliceHeight = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); + if (pVideoDec->bReconfigDPB != OMX_TRUE) + 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 Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) { OMX_ERRORTYPE ret = OMX_ErrorNone; @@ -904,72 +1084,7 @@ OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DA goto EXIT; } - /* get geometry for output */ - Exynos_OSAL_Memset(&pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry)); - if (pOutbufOps->Get_Geometry(hMFCHandle, &pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info"); - Mpeg4CodecStop(pOMXComponent, INPUT_PORT_INDEX); - pInbufOps->Cleanup_Buffer(hMFCHandle); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - - /* get dpb count */ - pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle); - if (pVideoDec->bThumbnailMode == OMX_FALSE) { - pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum += EXTRA_DPB_NUM; - } - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Mpeg4CodecSetup nOutbufs: %d", pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum); - - pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_TRUE; - - if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { - if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) || - (pExynosInputPort->portDefinition.format.video.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight)) { - pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE; - - pExynosInputPort->portDefinition.format.video.nFrameWidth = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth; - pExynosInputPort->portDefinition.format.video.nFrameHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight; - pExynosInputPort->portDefinition.format.video.nStride = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); - pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pMpeg4Dec->hMFCMpeg4Handle.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 (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { - if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) || - (pExynosInputPort->portDefinition.format.video.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight) || - (pExynosOutputPort->portDefinition.nBufferCountActual != pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum)) { - pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE; - - pExynosInputPort->portDefinition.format.video.nFrameWidth = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth; - pExynosInputPort->portDefinition.format.video.nFrameHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight; - pExynosInputPort->portDefinition.format.video.nStride = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); - pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); - - pExynosOutputPort->portDefinition.nBufferCountActual = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum; - pExynosOutputPort->portDefinition.nBufferCountMin = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum; - - 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); - } - } + Mpeg4CodecCheckResolutionChange(pOMXComponent); Exynos_OSAL_SleepMillisec(0); ret = OMX_ErrorInputDataDecodeYet; Mpeg4CodecStop(pOMXComponent, INPUT_PORT_INDEX); @@ -2058,6 +2173,19 @@ OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OM } } + if ((pVideoDec->bThumbnailMode == OMX_FALSE) && + (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL)) { + if (pVideoDec->bReconfigDPB != OMX_TRUE) { + pExynosOutputPort->exceptionFlag = NEED_PORT_FLUSH; + pVideoDec->bReconfigDPB = OMX_TRUE; + Mpeg4CodecCheckResolutionChange(pOMXComponent); + pVideoDec->csc_set_format = OMX_FALSE; + } + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "VIDEO_FRAME_STATUS_CHANGE_RESOL"); + ret = OMX_ErrorNone; + goto EXIT; + } + pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp++; pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP; @@ -2532,6 +2660,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData; pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData; + pVideoDec->exynos_codec_reconfigAllBuffers = &Mpeg4CodecReconfigAllBuffers; pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open(); if (pVideoDec->hSharedMemory == NULL) { diff --git a/component/video/dec/vp8/Exynos_OMX_Vp8dec.c b/component/video/dec/vp8/Exynos_OMX_Vp8dec.c index 4bf0975..4f225d7 100644 --- a/component/video/dec/vp8/Exynos_OMX_Vp8dec.c +++ b/component/video/dec/vp8/Exynos_OMX_Vp8dec.c @@ -518,6 +518,61 @@ EXIT: return ret; } +OMX_ERRORTYPE VP8CodecReconfigAllBuffers( + 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_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; + ExynosVideoDecBufferOps *pBufferOps = NULL; + + FunctionIn(); + + if ((nPortIndex == INPUT_PORT_INDEX) && + (pVp8Dec->bSourceStart == OMX_TRUE)) { + ret = OMX_ErrorNotImplemented; + goto EXIT; + } else if ((nPortIndex == OUTPUT_PORT_INDEX) && + (pVp8Dec->bDestinationStart == OMX_TRUE)) { + pBufferOps = pVp8Dec->hMFCVp8Handle.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); + } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) { + /**********************************/ + /* Codec Buffer Unregister */ + /**********************************/ + pBufferOps->Clear_RegisteredBuffer(hMFCHandle); + pBufferOps->Cleanup_Buffer(hMFCHandle); + } + /******************************************************/ + /* V4L2 Destnation Setup for DPB Buffer Number Change */ + /******************************************************/ + VP8CodecDstSetup(pOMXComponent); + pVideoDec->bReconfigDPB = OMX_FALSE; + + Exynos_ResolutionUpdate(pOMXComponent); + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + +EXIT: + FunctionOut(); + + return ret; +} + OMX_ERRORTYPE VP8CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) { OMX_ERRORTYPE ret = OMX_ErrorNone; @@ -571,6 +626,131 @@ EXIT: return ret; } +OMX_ERRORTYPE VP8CodecCheckResolutionChange(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_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle; + void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; + EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; + EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; + ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; + ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; + + OMX_CONFIG_RECTTYPE *pCropRectangle = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = NULL; + + FunctionIn(); + /* get geometry for output */ + Exynos_OSAL_Memset(&pVp8Dec->hMFCVp8Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry)); + if (pOutbufOps->Get_Geometry(hMFCHandle, &pVp8Dec->hMFCVp8Handle.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 */ + pVp8Dec->hMFCVp8Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle); + if (pVideoDec->bThumbnailMode == OMX_FALSE) + pVp8Dec->hMFCVp8Handle.maxDPBNum += EXTRA_DPB_NUM; + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Vp8CodecSetup nOutbufs: %d", pVp8Dec->hMFCVp8Handle.maxDPBNum); + + pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_TRUE; + + if (pVideoDec->bReconfigDPB != OMX_TRUE) { + pCropRectangle = &(pOutputPort->cropRectangle); + pInputPortDefinition = &(pInputPort->portDefinition); + pOutputPortDefinition = &(pOutputPort->portDefinition); + } else { + pCropRectangle = &(pOutputPort->newCropRectangle); + pInputPortDefinition = &(pInputPort->newPortDefinition); + pOutputPortDefinition = &(pOutputPort->newPortDefinition); + } + + pCropRectangle->nTop = pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nTop; + pCropRectangle->nLeft = pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nLeft; + pCropRectangle->nWidth = pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nWidth; + pCropRectangle->nHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nHeight; + + if (pOutputPort->bufferProcessType & BUFFER_COPY) { + if ((pVideoDec->bReconfigDPB) || + (pInputPort->portDefinition.format.video.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) || + (pInputPort->portDefinition.format.video.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight)) { + pInputPortDefinition->format.video.nFrameWidth = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth; + pInputPortDefinition->format.video.nFrameHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight; + pInputPortDefinition->format.video.nStride = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pInputPortDefinition->format.video.nSliceHeight = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); + pOutputPortDefinition->nBufferCountActual = pOutputPort->portDefinition.nBufferCountActual; + pOutputPortDefinition->nBufferCountMin = pOutputPort->portDefinition.nBufferCountMin; + if (pVideoDec->bReconfigDPB != OMX_TRUE) + Exynos_UpdateFrameSize(pOMXComponent); + pOutputPort->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 (pOutputPort->bufferProcessType & BUFFER_SHARE) { + if ((pVideoDec->bReconfigDPB) || + (pInputPort->portDefinition.format.video.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) || + (pInputPort->portDefinition.format.video.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight) || + (pOutputPort->portDefinition.nBufferCountActual != pVp8Dec->hMFCVp8Handle.maxDPBNum)) { + pInputPortDefinition->format.video.nFrameWidth = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth; + pInputPortDefinition->format.video.nFrameHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight; + pInputPortDefinition->format.video.nStride = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pInputPortDefinition->format.video.nSliceHeight = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); + pOutputPortDefinition->nBufferCountActual = pVp8Dec->hMFCVp8Handle.maxDPBNum; + pOutputPortDefinition->nBufferCountMin = pVp8Dec->hMFCVp8Handle.maxDPBNum; + if (pVideoDec->bReconfigDPB != OMX_TRUE) + Exynos_UpdateFrameSize(pOMXComponent); + pOutputPort->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 ((pVideoDec->bReconfigDPB == OMX_TRUE) || + (pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nWidth) || + (pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.cropRect.nHeight)) { + /* Check Crop */ + pInputPortDefinition->format.video.nFrameWidth = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth; + pInputPortDefinition->format.video.nFrameHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight; + pInputPortDefinition->format.video.nStride = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); + pInputPortDefinition->format.video.nSliceHeight = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); + if (pVideoDec->bReconfigDPB != OMX_TRUE) + 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 VP8CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) { OMX_ERRORTYPE ret = OMX_ErrorNone; @@ -715,72 +895,7 @@ OMX_ERRORTYPE VP8CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA goto EXIT; } - /* get geometry for output */ - Exynos_OSAL_Memset(&pVp8Dec->hMFCVp8Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry)); - if (pOutbufOps->Get_Geometry(hMFCHandle, &pVp8Dec->hMFCVp8Handle.codecOutbufConf) != VIDEO_ERROR_NONE) { - Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info"); - VP8CodecStop(pOMXComponent, INPUT_PORT_INDEX); - pInbufOps->Cleanup_Buffer(hMFCHandle); - ret = OMX_ErrorInsufficientResources; - goto EXIT; - } - - /* get dpb count */ - pVp8Dec->hMFCVp8Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle); - if (pVideoDec->bThumbnailMode == OMX_FALSE) { - pVp8Dec->hMFCVp8Handle.maxDPBNum += EXTRA_DPB_NUM; - } - Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Vp8CodecSetup nOutbufs: %d", pVp8Dec->hMFCVp8Handle.maxDPBNum); - - pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_TRUE; - - if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) { - if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) || - (pExynosInputPort->portDefinition.format.video.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight)) { - pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE; - - pExynosInputPort->portDefinition.format.video.nFrameWidth = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth; - pExynosInputPort->portDefinition.format.video.nFrameHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight; - pExynosInputPort->portDefinition.format.video.nStride = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); - pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pVp8Dec->hMFCVp8Handle.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 (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) { - if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) || - (pExynosInputPort->portDefinition.format.video.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight) || - (pExynosOutputPort->portDefinition.nBufferCountActual != pVp8Dec->hMFCVp8Handle.maxDPBNum)) { - pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE; - - pExynosInputPort->portDefinition.format.video.nFrameWidth = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth; - pExynosInputPort->portDefinition.format.video.nFrameHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight; - pExynosInputPort->portDefinition.format.video.nStride = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); - pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); - - pExynosOutputPort->portDefinition.nBufferCountActual = pVp8Dec->hMFCVp8Handle.maxDPBNum; - pExynosOutputPort->portDefinition.nBufferCountMin = pVp8Dec->hMFCVp8Handle.maxDPBNum; - - 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); - } - } + VP8CodecCheckResolutionChange(pOMXComponent); Exynos_OSAL_SleepMillisec(0); ret = OMX_ErrorInputDataDecodeYet; VP8CodecStop(pOMXComponent, INPUT_PORT_INDEX); @@ -1649,6 +1764,19 @@ OMX_ERRORTYPE Exynos_VP8Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_ } } + if ((pVideoDec->bThumbnailMode == OMX_FALSE) && + (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL)) { + if (pVideoDec->bReconfigDPB != OMX_TRUE) { + pExynosOutputPort->exceptionFlag = NEED_PORT_FLUSH; + pVideoDec->bReconfigDPB = OMX_TRUE; + VP8CodecCheckResolutionChange(pOMXComponent); + pVideoDec->csc_set_format = OMX_FALSE; + } + Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "VIDEO_FRAME_STATUS_CHANGE_RESOL"); + ret = OMX_ErrorNone; + goto EXIT; + } + pVp8Dec->hMFCVp8Handle.outputIndexTimestamp++; pVp8Dec->hMFCVp8Handle.outputIndexTimestamp %= MAX_TIMESTAMP; @@ -2090,6 +2218,7 @@ OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( pVideoDec->exynos_checkInputFrame = &Check_VP8_Frame; pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData; pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData; + pVideoDec->exynos_codec_reconfigAllBuffers = &VP8CodecReconfigAllBuffers; pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open(); if (pVideoDec->hSharedMemory == NULL) { -- 2.20.1