summaryrefslogtreecommitdiff
path: root/omx
diff options
context:
space:
mode:
authorBenny Wong <Benny.Wong@motorola.com>2009-09-30 13:16:06 -0500
committerJames Dong <jdong@google.com>2009-09-30 12:05:37 -0700
commit1348a0db59d75e00b3e0f33678d06f6671a6d4d6 (patch)
tree45970621c815ff56b8432cd1947e0d39db562a5c /omx
parent0c1fc978146aeb80d968d0b27abe70bf84c62ed4 (diff)
downloadomap3-1348a0db59d75e00b3e0f33678d06f6671a6d4d6.tar.gz
To get GetState to block for pending state transitions to complete for video decode
Originally from: https://partner.source.android.com/g/#change,1201
Diffstat (limited to 'omx')
-rw-r--r--omx/video/src/openmax_il/video_decode/inc/OMX_VideoDec_Utils.h8
-rw-r--r--omx/video/src/openmax_il/video_decode/src/OMX_VideoDec_Utils.c122
-rw-r--r--omx/video/src/openmax_il/video_decode/src/OMX_VideoDecoder.c89
3 files changed, 197 insertions, 22 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 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);