From 1348a0db59d75e00b3e0f33678d06f6671a6d4d6 Mon Sep 17 00:00:00 2001 From: Benny Wong Date: Wed, 30 Sep 2009 13:16:06 -0500 Subject: To get GetState to block for pending state transitions to complete for video decode Originally from: https://partner.source.android.com/g/#change,1201 --- .../video_decode/inc/OMX_VideoDec_Utils.h | 8 ++ .../video_decode/src/OMX_VideoDec_Utils.c | 122 ++++++++++++++++++++- .../openmax_il/video_decode/src/OMX_VideoDecoder.c | 89 +++++++++++---- 3 files changed, 197 insertions(+), 22 deletions(-) (limited to 'omx') 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 bb25608..e507255 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 @@ -989,6 +989,11 @@ typedef struct VIDDEC_COMPONENT_PRIVATE * */ OMX_BOOL bCopiedCCDBuffer; + /* Reference count for pending state change requests */ + OMX_U32 nPendingStateChangeRequests; + pthread_mutex_t mutexStateChangeRequest; + pthread_cond_t StateChangeCondition; + } VIDDEC_COMPONENT_PRIVATE; /*****************macro definitions*********************/ @@ -1268,5 +1273,8 @@ OMX_ERRORTYPE VIDDEC_ParseVideo_MPEG2( OMX_S32* nWidth, OMX_S32* nHeight, OMX_BU OMX_U32 VIDDEC_GetBits(OMX_U32* nPosition, OMX_U8 nBits, OMX_U8* pBuffer, OMX_BOOL bIcreasePosition); OMX_S32 VIDDEC_UVLC_dec(OMX_U32 *nPosition, OMX_U8* pBuffer); +OMX_ERRORTYPE AddStateTransition(VIDDEC_COMPONENT_PRIVATE* pComponentPrivate); +OMX_ERRORTYPE RemoveStateTransition(VIDDEC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BOOL bEnableSignal); + #endif #endif 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 da20bdc..eba38c4 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 @@ -968,6 +968,14 @@ OMX_ERRORTYPE VIDDEC_Load_Defaults (VIDDEC_COMPONENT_PRIVATE* pComponentPrivate, #endif + pComponentPrivate->nPendingStateChangeRequests = 0; + if(pthread_mutex_init(&pComponentPrivate->mutexStateChangeRequest, NULL)) { + return OMX_ErrorUndefined; + } + if(pthread_cond_init (&pComponentPrivate->StateChangeCondition, NULL)) { + return OMX_ErrorUndefined; + } + /* Set pMpeg4 defaults */ OMX_CONF_INIT_STRUCT (pComponentPrivate->pMpeg4, OMX_VIDEO_PARAM_MPEG4TYPE, pComponentPrivate->dbg); pComponentPrivate->pMpeg4->nPortIndex = VIDDEC_DEFAULT_MPEG4_PORTINDEX; @@ -2645,6 +2653,12 @@ OMX_ERRORTYPE VIDDEC_HandleCommand (OMX_HANDLETYPE phandle, OMX_U32 nParam1) pComponentPrivate->eState = OMX_StateIdle; pComponentPrivate->bIsPaused = 0; + + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -2732,6 +2746,11 @@ OMX_ERRORTYPE VIDDEC_HandleCommand (OMX_HANDLETYPE phandle, OMX_U32 nParam1) pComponentPrivate->bIsStopping = OMX_FALSE; pComponentPrivate->eState = OMX_StateIdle; + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -3077,6 +3096,11 @@ OMX_ERRORTYPE VIDDEC_HandleCommand (OMX_HANDLETYPE phandle, OMX_U32 nParam1) pComponentPrivate->bIsPaused = 0; pComponentPrivate->iEndofInputSent = 0; pComponentPrivate->eState = OMX_StateExecuting; + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -3218,6 +3242,12 @@ OMX_ERRORTYPE VIDDEC_HandleCommand (OMX_HANDLETYPE phandle, OMX_U32 nParam1) eError = OMX_ErrorNone; pComponentPrivate->bIsPaused = 0; pComponentPrivate->eState = OMX_StateLoaded; + + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -3235,7 +3265,13 @@ OMX_ERRORTYPE VIDDEC_HandleCommand (OMX_HANDLETYPE phandle, OMX_U32 nParam1) eError = OMX_ErrorNone; pComponentPrivate->bIsPaused = 0; pComponentPrivate->eState = OMX_StateLoaded; - pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, + + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + + pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, OMX_EventCmdComplete, OMX_CommandStateSet, @@ -3259,6 +3295,12 @@ OMX_ERRORTYPE VIDDEC_HandleCommand (OMX_HANDLETYPE phandle, OMX_U32 nParam1) eError = OMX_ErrorNone; pComponentPrivate->bIsPaused = 0; pComponentPrivate->eState = OMX_StateLoaded; + + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -3282,6 +3324,12 @@ OMX_ERRORTYPE VIDDEC_HandleCommand (OMX_HANDLETYPE phandle, OMX_U32 nParam1) eError = OMX_ErrorNone; pComponentPrivate->bIsPaused = 0; pComponentPrivate->eState = OMX_StateLoaded; + + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -3319,6 +3367,12 @@ OMX_ERRORTYPE VIDDEC_HandleCommand (OMX_HANDLETYPE phandle, OMX_U32 nParam1) } pComponentPrivate->eState = OMX_StateLoaded; pComponentPrivate->bIsPaused = 0; + + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -3335,6 +3389,13 @@ OMX_ERRORTYPE VIDDEC_HandleCommand (OMX_HANDLETYPE phandle, OMX_U32 nParam1) else if (pComponentPrivate->eState == OMX_StateWaitForResources) { pComponentPrivate->eState = OMX_StateLoaded; pComponentPrivate->bIsPaused = 0; + + + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -3412,6 +3473,13 @@ OMX_ERRORTYPE VIDDEC_HandleCommand (OMX_HANDLETYPE phandle, OMX_U32 nParam1) eError = OMX_ErrorNone; pComponentPrivate->bIsPaused = 1; pComponentPrivate->eState = OMX_StatePause; + + + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -3451,6 +3519,12 @@ OMX_ERRORTYPE VIDDEC_HandleCommand (OMX_HANDLETYPE phandle, OMX_U32 nParam1) eError = OMX_ErrorNone; pComponentPrivate->bIsPaused = 1; pComponentPrivate->eState = OMX_StatePause; + + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->cbInfo.EventHandler(pComponentPrivate->pHandle, pComponentPrivate->pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -8986,7 +9060,7 @@ OMX_ERRORTYPE VIDDEC_Set_Debocking(VIDDEC_COMPONENT_PRIVATE* pComponentPrivate) VIDDEC_PTHREAD_MUTEX_WAIT(pComponentPrivate->sMutex); VIDDEC_PTHREAD_MUTEX_UNLOCK(pComponentPrivate->sMutex); /*This flag is set to TRUE in the LCML callback from EMMCodecControlAlgCtrl - * this is not the case were we need it*/ + * this is not the case were we need it*/ pComponentPrivate->bTransPause = OMX_FALSE; } @@ -8999,8 +9073,50 @@ OMX_ERRORTYPE VIDDEC_Set_Debocking(VIDDEC_COMPONENT_PRIVATE* pComponentPrivate) OMX_PRDSP4(pComponentPrivate->dbg, "Codec AlgCtrl 0x%x\n",eError); goto EXIT; } - + EXIT: return eError; } + +OMX_ERRORTYPE AddStateTransition(VIDDEC_COMPONENT_PRIVATE* pComponentPrivate) { + + OMX_ERRORTYPE eError = OMX_ErrorNone; + + if(pthread_mutex_lock(&pComponentPrivate->mutexStateChangeRequest)) { + return OMX_ErrorUndefined; + } + + /* Increment state change request reference count */ + pComponentPrivate->nPendingStateChangeRequests++; + + if(pthread_mutex_unlock(&pComponentPrivate->mutexStateChangeRequest)) { + return OMX_ErrorUndefined; + } + + return eError; +} + +OMX_ERRORTYPE RemoveStateTransition(VIDDEC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BOOL bEnableSignal) { + OMX_ERRORTYPE eError = OMX_ErrorNone; + + /* Decrement state change request reference count*/ + if(pthread_mutex_lock(&pComponentPrivate->mutexStateChangeRequest)) { + return OMX_ErrorUndefined; + } + + pComponentPrivate->nPendingStateChangeRequests--; + + /* If there are no more pending requests, signal the thread waiting on this*/ + if(!pComponentPrivate->nPendingStateChangeRequests && bEnableSignal) { + pthread_cond_signal(&(pComponentPrivate->StateChangeCondition)); + } + + if(pthread_mutex_unlock(&pComponentPrivate->mutexStateChangeRequest)) { + return OMX_ErrorUndefined; + } + + 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 358418f..22f4a4d 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 @@ -614,17 +614,27 @@ static OMX_ERRORTYPE VIDDEC_SendCommand (OMX_HANDLETYPE hComponent, switch (Cmd) { case OMX_CommandStateSet: + + /* Add a pending transition */ + if(AddStateTransition(pComponentPrivate) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->eIdleToLoad = nParam1; pComponentPrivate->eExecuteToIdle = nParam1; nRet = write(pComponentPrivate->cmdPipe[VIDDEC_PIPE_WRITE], &Cmd, sizeof(Cmd)); if (nRet == -1) { - eError = OMX_ErrorUndefined; - goto EXIT; + if(RemoveStateTransition(pComponentPrivate, OMX_FALSE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + return OMX_ErrorUndefined; } nRet = write(pComponentPrivate->cmdDataPipe[VIDDEC_PIPE_WRITE], &nParam1, sizeof(nParam1)); if (nRet == -1) { - eError = OMX_ErrorUndefined; - goto EXIT; + if(RemoveStateTransition(pComponentPrivate, OMX_FALSE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + return OMX_ErrorUndefined; } break; case OMX_CommandPortDisable: @@ -2171,30 +2181,67 @@ EXIT: **/ /*----------------------------------------------------------------------------*/ -static OMX_ERRORTYPE VIDDEC_GetState (OMX_HANDLETYPE pComponent, +static OMX_ERRORTYPE VIDDEC_GetState (OMX_HANDLETYPE hComponent, OMX_STATETYPE* pState) { - OMX_ERRORTYPE eError = OMX_ErrorUndefined; + OMX_ERRORTYPE eError = OMX_ErrorNone; OMX_COMPONENTTYPE* pHandle = NULL; + VIDDEC_COMPONENT_PRIVATE* pComponentPrivate = NULL; + struct timespec abs_time = {0,0}; + int nPendingStateChangeRequests = 0; + int ret = 0; + /* Set to sufficiently high value */ + int mutex_timeout = 3; - OMX_CONF_CHECK_CMD(pComponent, OMX_TRUE, OMX_TRUE); + if(hComponent == NULL || pState == NULL) { + return OMX_ErrorBadParameter; + } - pHandle = (OMX_COMPONENTTYPE*)pComponent; + pHandle = (OMX_COMPONENTTYPE*)hComponent; + pComponentPrivate = (VIDDEC_COMPONENT_PRIVATE*)pHandle->pComponentPrivate; - if (pState == NULL) { - eError = OMX_ErrorBadParameter; - goto EXIT; - } /* Retrieve current state */ if (pHandle && pHandle->pComponentPrivate) { - *pState = ((VIDDEC_COMPONENT_PRIVATE*)pHandle->pComponentPrivate)->eState; - eError = OMX_ErrorNone; - } - else { - *pState = OMX_StateLoaded; + /* Check for any pending state transition requests */ + if(pthread_mutex_lock(&pComponentPrivate->mutexStateChangeRequest)) { + return OMX_ErrorUndefined; + } + nPendingStateChangeRequests = pComponentPrivate->nPendingStateChangeRequests; + if(!nPendingStateChangeRequests) { + if(pthread_mutex_unlock(&pComponentPrivate->mutexStateChangeRequest)) { + return OMX_ErrorUndefined; + } + + /* No pending state transitions */ + *pState = ((VIDDEC_COMPONENT_PRIVATE*)pHandle->pComponentPrivate)->eState; + eError = OMX_ErrorNone; + } + else { + /* Wait for component to complete state transition */ + clock_gettime(CLOCK_REALTIME, &abs_time); + abs_time.tv_sec += mutex_timeout; + abs_time.tv_nsec = 0; + ret = pthread_cond_timedwait(&(pComponentPrivate->StateChangeCondition), &(pComponentPrivate->mutexStateChangeRequest), &abs_time); + if (!ret) { + /* Component has completed state transitions*/ + *pState = ((VIDDEC_COMPONENT_PRIVATE*)pHandle->pComponentPrivate)->eState; + if(pthread_mutex_unlock(&pComponentPrivate->mutexStateChangeRequest)) { + return OMX_ErrorUndefined; + } + eError = OMX_ErrorNone; + } + else if(ret == ETIMEDOUT) { + /* Unlock mutex in case of timeout */ + pthread_mutex_unlock(&pComponentPrivate->mutexStateChangeRequest); + return OMX_ErrorTimeout; + } + } + } + else { + eError = OMX_ErrorInvalidComponent; + *pState = OMX_StateInvalid; } - pHandle = NULL; -EXIT: + return eError; } @@ -2670,6 +2717,10 @@ static OMX_ERRORTYPE VIDDEC_ComponentDeInit(OMX_HANDLETYPE hComponent) VIDDEC_PTHREAD_SEMAPHORE_DESTROY(pComponentPrivate->sInSemaphore); VIDDEC_PTHREAD_SEMAPHORE_DESTROY(pComponentPrivate->sOutSemaphore); #endif + + pthread_mutex_destroy(&pComponentPrivate->mutexStateChangeRequest); + pthread_cond_destroy(&pComponentPrivate->StateChangeCondition); + if(pComponentPrivate->pUalgParams != NULL){ OMX_U8* pTemp = NULL; pTemp = (OMX_U8*)(pComponentPrivate->pUalgParams); -- cgit v1.2.3