diff options
author | James Dong <jdong@google.com> | 2010-02-14 12:50:17 -0800 |
---|---|---|
committer | James Dong <jdong@google.com> | 2010-02-16 16:34:14 -0800 |
commit | 81080e8c6e5fbb1d3bb01d707d832a2f348c7268 (patch) | |
tree | d2eec15e909a29c76272121047e4df438e3cbf2e | |
parent | a5d693234054ad2f2031962632044f9545914983 (diff) | |
download | omap3-81080e8c6e5fbb1d3bb01d707d832a2f348c7268.tar.gz |
Fixed three issues
1. don't return INPUT buffers (OUTPUT part was fixed last week) back to omx client without
making sure flush is completed while handling do flush request from omx client
2. don't send premature flush completion notification from omx component to omx client.
We need to check whether all pending buffers (seaprately on INPUT and OUTPUT buffers)
before the flush completion notification/event is sent out to omx client.
3. counter mis-calculation for the number of outstanding input buffers hold by the dsp.
bug - 2442379
3 files changed, 77 insertions, 7 deletions
diff --git a/omx/video/src/openmax_il/video_decode/inc/OMX_VideoDec_Utils.h b/omx/video/src/openmax_il/video_decode/inc/OMX_VideoDec_Utils.h index dd511f4..8a538d8 100644 --- a/omx/video/src/openmax_il/video_decode/inc/OMX_VideoDec_Utils.h +++ b/omx/video/src/openmax_il/video_decode/inc/OMX_VideoDec_Utils.h @@ -973,6 +973,10 @@ typedef struct VIDDEC_COMPONENT_PRIVATE pthread_mutex_t mutexOutputBFromApp; pthread_mutex_t mutexInputBFromDSP; pthread_mutex_t mutexOutputBFromDSP; + VIDDEC_MUTEX inputFlushCompletionMutex; + VIDDEC_MUTEX outputFlushCompletionMutex; + OMX_BOOL bIsInputFlushPending; + OMX_BOOL bIsOutputFlushPending; VIDDEC_MUTEX sDynConfigMutex; VIDDEC_SEMAPHORE sInSemaphore; VIDDEC_SEMAPHORE sOutSemaphore; diff --git a/omx/video/src/openmax_il/video_decode/src/OMX_VideoDec_Utils.c b/omx/video/src/openmax_il/video_decode/src/OMX_VideoDec_Utils.c index 97844e1..611bb2c 100644 --- a/omx/video/src/openmax_il/video_decode/src/OMX_VideoDec_Utils.c +++ b/omx/video/src/openmax_il/video_decode/src/OMX_VideoDec_Utils.c @@ -1869,9 +1869,21 @@ OMX_ERRORTYPE VIDDEC_EmptyBufferDone(VIDDEC_COMPONENT_PRIVATE* pComponentPrivate // No buffer flag EOS event needs to be sent for INPUT port - return pComponentPrivate->cbInfo.EmptyBufferDone(pComponentPrivate->pHandle, + OMX_ERRORTYPE ret = pComponentPrivate->cbInfo.EmptyBufferDone(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, pBufferHeader); + + VIDDEC_PTHREAD_MUTEX_LOCK(pComponentPrivate->inputFlushCompletionMutex); + OMX_U32 nCountInputBFromDsp = 0; + pthread_mutex_lock(&pComponentPrivate->mutexInputBFromDSP); + nCountInputBFromDsp = pComponentPrivate->nCountInputBFromDsp; + pthread_mutex_unlock(&pComponentPrivate->mutexInputBFromDSP); + if (pComponentPrivate->bIsInputFlushPending && nCountInputBFromDsp == 0) { + VIDDEC_PTHREAD_MUTEX_SIGNAL(pComponentPrivate->inputFlushCompletionMutex); + } + VIDDEC_PTHREAD_MUTEX_UNLOCK(pComponentPrivate->inputFlushCompletionMutex); + + return ret; } OMX_ERRORTYPE VIDDEC_FillBufferDone(VIDDEC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BUFFERHEADERTYPE* pBufferHeader) @@ -1890,9 +1902,21 @@ OMX_ERRORTYPE VIDDEC_FillBufferDone(VIDDEC_COMPONENT_PRIVATE* pComponentPrivate, NULL); } - return pComponentPrivate->cbInfo.FillBufferDone(pComponentPrivate->pHandle, + OMX_ERRORTYPE ret = pComponentPrivate->cbInfo.FillBufferDone(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, pBufferHeader); + + VIDDEC_PTHREAD_MUTEX_LOCK(pComponentPrivate->outputFlushCompletionMutex); + OMX_U32 nCountOutputBFromDsp = 0; + pthread_mutex_lock(&pComponentPrivate->mutexOutputBFromDSP); + nCountOutputBFromDsp = pComponentPrivate->nCountOutputBFromDsp; + pthread_mutex_unlock(&pComponentPrivate->mutexOutputBFromDSP); + if (pComponentPrivate->bIsOutputFlushPending && nCountOutputBFromDsp == 0) { + VIDDEC_PTHREAD_MUTEX_SIGNAL(pComponentPrivate->outputFlushCompletionMutex); + } + VIDDEC_PTHREAD_MUTEX_UNLOCK(pComponentPrivate->outputFlushCompletionMutex); + + return ret; } /* ========================================================================== */ /** @@ -2230,8 +2254,18 @@ OMX_ERRORTYPE VIDDEC_HandleCommandFlush(VIDDEC_COMPONENT_PRIVATE *pComponentPriv VIDDEC_CircBuf_Flush(pComponentPrivate, VIDDEC_CBUFFER_TIMESTAMP, VIDDEC_INPUT_PORT); OMX_VidDec_Return(pComponentPrivate); OMX_VidDec_Return(pComponentPrivate); - VIDDEC_ReturnBuffers(pComponentPrivate, VIDDEC_INPUT_PORT, OMX_TRUE); if(bPass) { + VIDDEC_PTHREAD_MUTEX_LOCK(pComponentPrivate->inputFlushCompletionMutex); + pComponentPrivate->bIsInputFlushPending = OMX_TRUE; + OMX_U32 nCountInputBFromDsp = 0; + pthread_mutex_lock(&pComponentPrivate->mutexInputBFromDSP); + nCountInputBFromDsp = pComponentPrivate->nCountInputBFromDsp; + pthread_mutex_unlock(&pComponentPrivate->mutexInputBFromDSP); + if (nCountInputBFromDsp > 0) { + VIDDEC_PTHREAD_MUTEX_WAIT(pComponentPrivate->inputFlushCompletionMutex); + } + pComponentPrivate->bIsInputFlushPending = OMX_FALSE; + VIDDEC_PTHREAD_MUTEX_UNLOCK(pComponentPrivate->inputFlushCompletionMutex); pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -2266,8 +2300,18 @@ OMX_ERRORTYPE VIDDEC_HandleCommandFlush(VIDDEC_COMPONENT_PRIVATE *pComponentPriv } OMX_VidDec_Return(pComponentPrivate); OMX_VidDec_Return(pComponentPrivate); - // VIDDEC_ReturnBuffers(pComponentPrivate, VIDDEC_OUTPUT_PORT, OMX_TRUE); if(bPass) { + VIDDEC_PTHREAD_MUTEX_LOCK(pComponentPrivate->outputFlushCompletionMutex); + pComponentPrivate->bIsOutputFlushPending = OMX_TRUE; + OMX_U32 nCountOutputBFromDsp = 0; + pthread_mutex_lock(&pComponentPrivate->mutexOutputBFromDSP); + nCountOutputBFromDsp = pComponentPrivate->nCountOutputBFromDsp; + pthread_mutex_unlock(&pComponentPrivate->mutexOutputBFromDSP); + if (nCountOutputBFromDsp > 0) { + VIDDEC_PTHREAD_MUTEX_WAIT(pComponentPrivate->outputFlushCompletionMutex); + } + pComponentPrivate->bIsOutputFlushPending = OMX_FALSE; + VIDDEC_PTHREAD_MUTEX_UNLOCK(pComponentPrivate->outputFlushCompletionMutex); pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -3816,12 +3860,12 @@ OMX_ERRORTYPE VIDDEC_HandleFreeOutputBufferFromApp(VIDDEC_COMPONENT_PRIVATE *pCo eError = OMX_ErrorHardware; goto EXIT; } + eError = DecrementCount (&(pComponentPrivate->nCountOutputBFromApp), &(pComponentPrivate->mutexOutputBFromApp)); if (eError != OMX_ErrorNone) { return eError; } OMX_PRBUFFER1(pComponentPrivate->dbg, "pBuffHead 0x%p eExecuteToIdle 0x%x\n", pBuffHead, pComponentPrivate->eExecuteToIdle); - if(pBuffHead->pOutputPortPrivate != NULL) { pBufferPrivate = (VIDDEC_BUFFER_PRIVATE* )pBuffHead->pOutputPortPrivate; if(pComponentPrivate->eLCMLState != VidDec_LCML_State_Unload && @@ -6706,7 +6750,7 @@ OMX_ERRORTYPE VIDDEC_HandleFreeDataBuf( VIDDEC_COMPONENT_PRIVATE *pComponentPriv eError = OMX_ErrorHardware; goto EXIT; } - eError = IncrementCount (&(pComponentPrivate->nCountInputBFromDsp), &(pComponentPrivate->mutexInputBFromDSP)); + eError = DecrementCount (&(pComponentPrivate->nCountInputBFromDsp), &(pComponentPrivate->mutexInputBFromDSP)); if (eError != OMX_ErrorNone) { return eError; } diff --git a/omx/video/src/openmax_il/video_decode/src/OMX_VideoDecoder.c b/omx/video/src/openmax_il/video_decode/src/OMX_VideoDecoder.c index 19dd214..d4861d6 100644 --- a/omx/video/src/openmax_il/video_decode/src/OMX_VideoDecoder.c +++ b/omx/video/src/openmax_il/video_decode/src/OMX_VideoDecoder.c @@ -340,6 +340,10 @@ OMX_ERRORTYPE OMX_ComponentInit (OMX_HANDLETYPE hComponent) eError = OMX_ErrorUndefined; return eError; } + VIDDEC_PTHREAD_MUTEX_INIT(pComponentPrivate->outputFlushCompletionMutex); + pComponentPrivate->bIsOutputFlushPending = OMX_FALSE; + VIDDEC_PTHREAD_MUTEX_INIT(pComponentPrivate->inputFlushCompletionMutex); + pComponentPrivate->bIsInputFlushPending = OMX_FALSE; OMX_MALLOC_STRUCT(pComponentPrivate->pPortParamType, OMX_PORT_PARAM_TYPE,pComponentPrivate->nMemUsage[VIDDDEC_Enum_MemLevel0]); #ifdef __STD_COMPONENT__ OMX_MALLOC_STRUCT(pComponentPrivate->pPortParamTypeAudio, OMX_PORT_PARAM_TYPE,pComponentPrivate->nMemUsage[VIDDDEC_Enum_MemLevel0]); @@ -2369,6 +2373,14 @@ static OMX_ERRORTYPE VIDDEC_EmptyThisBuffer (OMX_HANDLETYPE pComponent, OMX_PRBUFFER1(pComponentPrivate->dbg, "+++Entering pHandle 0x%p pBuffer 0x%p Index %lu state %x nflags %x isfirst %x\n",pComponent, pBuffHead, pBuffHead->nInputPortIndex,pComponentPrivate->eState,pBuffHead->nFlags,pComponentPrivate->bFirstHeader); + OMX_BOOL bIsInputFlushPending = OMX_FALSE; + VIDDEC_PTHREAD_MUTEX_LOCK(pComponentPrivate->inputFlushCompletionMutex); + bIsInputFlushPending = pComponentPrivate->bIsInputFlushPending; + VIDDEC_PTHREAD_MUTEX_UNLOCK(pComponentPrivate->inputFlushCompletionMutex); + if (bIsInputFlushPending) { + LOGE("Unable to process any OMX_EmptyThisBuffer requsts with input flush pending"); + return OMX_ErrorIncorrectStateOperation; + } #ifdef __PERF_INSTRUMENTATION__ PERF_ReceivedFrame(pComponentPrivate->pPERF, pBuffHead->pBuffer, @@ -2449,13 +2461,21 @@ static OMX_ERRORTYPE VIDDEC_FillThisBuffer (OMX_HANDLETYPE pComponent, VIDDEC_BUFFER_PRIVATE* pBufferPrivate = NULL; int ret = 0; OMX_CONF_CHECK_CMD(pComponent, pBuffHead, OMX_TRUE); - pHandle = (OMX_COMPONENTTYPE *)pComponent; pComponentPrivate = (VIDDEC_COMPONENT_PRIVATE *)pHandle->pComponentPrivate; OMX_PRBUFFER1(pComponentPrivate->dbg, "+++Entering pHandle 0x%p pBuffer 0x%p Index %lu\n",pComponent, pBuffHead, pBuffHead->nOutputPortIndex); + OMX_BOOL bIsOutputFlushPending = OMX_FALSE; + VIDDEC_PTHREAD_MUTEX_LOCK(pComponentPrivate->outputFlushCompletionMutex); + bIsOutputFlushPending = pComponentPrivate->bIsOutputFlushPending; + VIDDEC_PTHREAD_MUTEX_UNLOCK(pComponentPrivate->outputFlushCompletionMutex); + if (bIsOutputFlushPending) { + LOGE("Unable to process any OMX_FillThisBuffer requsts with flush pending"); + return OMX_ErrorIncorrectStateOperation; + } + #ifdef __PERF_INSTRUMENTATION__ PERF_ReceivedFrame(pComponentPrivate->pPERF, pBuffHead->pBuffer, @@ -2817,6 +2837,8 @@ static OMX_ERRORTYPE VIDDEC_ComponentDeInit(OMX_HANDLETYPE hComponent) VIDDEC_PTHREAD_MUTEX_DESTROY(pComponentPrivate->sMutex); VIDDEC_PTHREAD_SEMAPHORE_DESTROY(pComponentPrivate->sInSemaphore); VIDDEC_PTHREAD_SEMAPHORE_DESTROY(pComponentPrivate->sOutSemaphore); + VIDDEC_PTHREAD_MUTEX_DESTROY(pComponentPrivate->inputFlushCompletionMutex); + VIDDEC_PTHREAD_MUTEX_DESTROY(pComponentPrivate->outputFlushCompletionMutex); #endif pthread_mutex_destroy(&(pComponentPrivate->mutexInputBFromApp)); pthread_mutex_destroy(&(pComponentPrivate->mutexOutputBFromApp)); |