From eced958917cca059f5e7222a83a44adc4e259c67 Mon Sep 17 00:00:00 2001 From: Benny Wong Date: Wed, 30 Sep 2009 17:50:08 -0500 Subject: To get GetState to block for pending state transitions to complete for aac encoder Originally from: https://partner.source.android.com/g/#change,1210 --- .../src/openmax_il/aac_enc/inc/OMX_AacEnc_Utils.h | 9 + .../src/openmax_il/aac_enc/src/OMX_AacEnc_Utils.c | 87 +++++++++- .../src/openmax_il/aac_enc/src/OMX_AacEncoder.c | 187 ++++++++++++++------- 3 files changed, 219 insertions(+), 64 deletions(-) (limited to 'omx') diff --git a/omx/audio/src/openmax_il/aac_enc/inc/OMX_AacEnc_Utils.h b/omx/audio/src/openmax_il/aac_enc/inc/OMX_AacEnc_Utils.h index c4ac3cc..aa159ff 100644 --- a/omx/audio/src/openmax_il/aac_enc/inc/OMX_AacEnc_Utils.h +++ b/omx/audio/src/openmax_il/aac_enc/inc/OMX_AacEnc_Utils.h @@ -622,6 +622,11 @@ pthread_mutex_t InLoaded_mutex; struct OMX_TI_Debug dbg; + /* Reference count for pending state change requests */ + OMX_U32 nPendingStateChangeRequests; + pthread_mutex_t mutexStateChangeRequest; + pthread_cond_t StateChangeCondition; + } AACENC_COMPONENT_PRIVATE; OMX_ERRORTYPE AACENCGetCorresponding_LCMLHeader(AACENC_COMPONENT_PRIVATE *pComponentPrivate, OMX_U8 *pBuffer, @@ -688,6 +693,10 @@ OMX_ERRORTYPE AACENC_StopComponentThread(OMX_HANDLETYPE pHandle); OMX_ERRORTYPE AACENC_FreeCompResources(OMX_HANDLETYPE pComponent); +OMX_ERRORTYPE AddStateTransition(AACENC_COMPONENT_PRIVATE* pComponentPrivate); +OMX_ERRORTYPE RemoveStateTransition(AACENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BOOL bEnableSignal); + + #endif diff --git a/omx/audio/src/openmax_il/aac_enc/src/OMX_AacEnc_Utils.c b/omx/audio/src/openmax_il/aac_enc/src/OMX_AacEnc_Utils.c index a8e1224..fdb89ad 100644 --- a/omx/audio/src/openmax_il/aac_enc/src/OMX_AacEnc_Utils.c +++ b/omx/audio/src/openmax_il/aac_enc/src/OMX_AacEnc_Utils.c @@ -933,6 +933,12 @@ OMX_U32 AACENCHandleCommand(AACENC_COMPONENT_PRIVATE *pComponentPrivate) OMX_ERROR2(pComponentPrivate->dbg, "%d :: AACENC: OMX_ErrorInsufficientResources\n", __LINE__); } pComponentPrivate->curState = OMX_StateIdle; + + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->cbInfo.EventHandler(pHandle, pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -941,6 +947,12 @@ OMX_U32 AACENCHandleCommand(AACENC_COMPONENT_PRIVATE *pComponentPrivate) NULL); #else pComponentPrivate->curState = OMX_StateIdle; + + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->cbInfo.EventHandler( pHandle, pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -1019,6 +1031,12 @@ OMX_U32 AACENCHandleCommand(AACENC_COMPONENT_PRIVATE *pComponentPrivate) rm_error = RMProxy_NewSendCommand(pHandle, RMProxy_StateSet, OMX_AAC_Encoder_COMPONENT, OMX_StateIdle, 3456, NULL); #endif + + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->cbInfo.EventHandler(pHandle, pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -1186,12 +1204,16 @@ OMX_U32 AACENCHandleCommand(AACENC_COMPONENT_PRIVATE *pComponentPrivate) #endif -pComponentPrivate->curState = OMX_StateExecuting; /* --- Transition to Executing --- */ - + pComponentPrivate->curState = OMX_StateExecuting; + #ifdef __PERF_INSTRUMENTATION__ PERF_Boundary(pComponentPrivate->pPERFcomp,PERF_BoundaryStart | PERF_BoundarySteadyState); #endif + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } /*Send state change notificaiton to Application */ @@ -1221,6 +1243,11 @@ pComponentPrivate->curState = OMX_StateExecuting; /* --- Transition to Executing PERF_Boundary(pComponentPrivate->pPERFcomp,PERF_BoundaryComplete | PERF_BoundaryCleanup); #endif + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate->cbInfo.EventHandler(pHandle, pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -2547,6 +2574,12 @@ pHandle = pComponentPrivate_CC->pHandle; #endif if (pComponentPrivate_CC->bPreempted == 0) { + + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate_CC, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate_CC->cbInfo.EventHandler(pComponentPrivate_CC->pHandle, pComponentPrivate_CC->pHandle->pApplicationPrivate, OMX_EventCmdComplete, @@ -2668,6 +2701,12 @@ pHandle = pComponentPrivate_CC->pHandle; } OMX_PRSTATE2(pComponentPrivate_CC->dbg, "%d :: AACENC: Codec has been Stopped here\n",__LINE__); pComponentPrivate_CC->curState = OMX_StateIdle; + + /* Decrement reference count with signal enabled */ + if(RemoveStateTransition(pComponentPrivate_CC, OMX_TRUE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + pComponentPrivate_CC->cbInfo.EventHandler(pHandle, pHandle->pApplicationPrivate, OMX_EventCmdComplete, OMX_CommandStateSet,OMX_StateIdle, NULL); #else @@ -3062,6 +3101,12 @@ OMX_ERRORTYPE AACENC_TransitionToPause(AACENC_COMPONENT_PRIVATE *pComponentPriva if (pComponentPrivate->nOutStandingFillDones <= 0 && pComponentPrivate->nOutStandingEmptyDones <= 0) { pComponentPrivate->curState = 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, @@ -3406,3 +3451,41 @@ int myfree(void *dp, int line, char *s){ } */ + +OMX_ERRORTYPE AddStateTransition(AACENC_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(AACENC_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/audio/src/openmax_il/aac_enc/src/OMX_AacEncoder.c b/omx/audio/src/openmax_il/aac_enc/src/OMX_AacEncoder.c index 8962cb2..c3f9e11 100644 --- a/omx/audio/src/openmax_il/aac_enc/src/OMX_AacEncoder.c +++ b/omx/audio/src/openmax_il/aac_enc/src/OMX_AacEncoder.c @@ -465,6 +465,16 @@ OMX_ERRORTYPE OMX_ComponentInit (OMX_HANDLETYPE hComp) PERF_FOURCC('A','A','E','T')); #endif + if(pthread_mutex_init(&pComponentPrivate->mutexStateChangeRequest, NULL)) { + return OMX_ErrorUndefined; + } + + if(pthread_cond_init (&pComponentPrivate->StateChangeCondition, NULL)) { + return OMX_ErrorUndefined; + } + + pComponentPrivate->nPendingStateChangeRequests = 0; + EXIT: OMX_PRINT1(pComponentPrivate->dbg, "%d :: AACENC: Exiting OMX_ComponentInit\n", __LINE__); return eError; @@ -627,68 +637,75 @@ static OMX_ERRORTYPE SendCommand (OMX_HANDLETYPE phandle, switch(Cmd) { case OMX_CommandStateSet: + if (nParam == OMX_StateLoaded) { pCompPrivate->bLoadedCommandPending = OMX_TRUE; } - OMX_PRINT1(pCompPrivate->dbg, "%d :: AACENC: Inside SendCommand\n",__LINE__); - OMX_PRSTATE1(pCompPrivate->dbg, "%d :: AACENC: pCompPrivate->curState = %d\n",__LINE__,pCompPrivate->curState); - if(pCompPrivate->curState == OMX_StateLoaded) + OMX_PRINT1(pCompPrivate->dbg, "%d :: AACENC: Inside SendCommand\n",__LINE__); + OMX_PRSTATE1(pCompPrivate->dbg, "%d :: AACENC: pCompPrivate->curState = %d\n",__LINE__,pCompPrivate->curState); + if(pCompPrivate->curState == OMX_StateLoaded) + { + if((nParam == OMX_StateExecuting) || (nParam == OMX_StatePause)) { - if((nParam == OMX_StateExecuting) || (nParam == OMX_StatePause)) - { - pCompPrivate->cbInfo.EventHandler(pHandle, - pHandle->pApplicationPrivate, - OMX_EventError, - OMX_ErrorIncorrectStateTransition, - OMX_TI_ErrorMinor, - NULL); - goto EXIT; - } + pCompPrivate->cbInfo.EventHandler(pHandle, + pHandle->pApplicationPrivate, + OMX_EventError, + OMX_ErrorIncorrectStateTransition, + OMX_TI_ErrorMinor, + NULL); + goto EXIT; + } - if(nParam == OMX_StateInvalid) - { - OMX_PRINT1(pCompPrivate->dbg, "%d :: AACENC: Inside SendCommand\n",__LINE__); - OMX_PRSTATE2(pCompPrivate->dbg, "AACENC: State changed to OMX_StateInvalid Line %d\n",__LINE__); - pCompPrivate->curState = OMX_StateInvalid; - pCompPrivate->cbInfo.EventHandler(pHandle, - pHandle->pApplicationPrivate, - OMX_EventError, - OMX_ErrorInvalidState, - OMX_TI_ErrorMinor, - NULL); - goto EXIT; - } + if(nParam == OMX_StateInvalid) + { + OMX_PRINT1(pCompPrivate->dbg, "%d :: AACENC: Inside SendCommand\n",__LINE__); + OMX_PRSTATE2(pCompPrivate->dbg, "AACENC: State changed to OMX_StateInvalid Line %d\n",__LINE__); + pCompPrivate->curState = OMX_StateInvalid; + pCompPrivate->cbInfo.EventHandler(pHandle, + pHandle->pApplicationPrivate, + OMX_EventError, + OMX_ErrorInvalidState, + OMX_TI_ErrorMinor, + NULL); + goto EXIT; } - break; + } + + /* Add a pending transition */ + if(AddStateTransition(pCompPrivate) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + + break; case OMX_CommandFlush: OMX_PRINT1(pCompPrivate->dbg, "%d :: IAACENC: nside SendCommand\n",__LINE__); - if(nParam > 1 && nParam != -1) + if(nParam > 1 && nParam != -1) { eError = OMX_ErrorBadPortIndex; goto EXIT; } break; - + case OMX_CommandPortDisable: OMX_PRDSP2(pCompPrivate->dbg, "%d :: AACENC: Inside SendCommand OMX_CommandPortDisable\n",__LINE__); break; - + case OMX_CommandPortEnable: OMX_PRDSP2(pCompPrivate->dbg, "%d :: AACENC: Inside SendCommand OMX_CommandPortEnable\n",__LINE__); break; - + case OMX_CommandMarkBuffer: OMX_PRDSP2(pCompPrivate->dbg, "%d :: AACENC: Inside SendCommand OMX_CommandMarkBuffer\n",__LINE__); - if (nParam > 0) + if (nParam > 0) { eError = OMX_ErrorBadPortIndex; goto EXIT; } break; - + default: OMX_ERROR4(pCompPrivate->dbg, "%d :: Error: Command Received Default error\n",__LINE__); pCompPrivate->cbInfo.EventHandler(pHandle, pHandle->pApplicationPrivate, @@ -706,28 +723,33 @@ static OMX_ERRORTYPE SendCommand (OMX_HANDLETYPE phandle, OMX_PRCOMM2(pCompPrivate->dbg, "%d :: AACENC: pCompPrivate->cmdPipe[1] = %d \n",__LINE__,pCompPrivate->cmdPipe[1]); OMX_PRCOMM2(pCompPrivate->dbg, "%d :: AACENC: &Cmd = %p \n",__LINE__,&Cmd); - if (nRet == -1) + if (nRet == -1) { OMX_PRINT1(pCompPrivate->dbg, "%d :: AACENC: Inside SendCommand\n",__LINE__); eError = OMX_ErrorInsufficientResources; goto EXIT; } - if (Cmd == OMX_CommandMarkBuffer) + if (Cmd == OMX_CommandMarkBuffer) { nRet = write(pCompPrivate->cmdDataPipe[1], &pCmdData, sizeof(OMX_PTR)); - } - else + } + else { nRet = write(pCompPrivate->cmdDataPipe[1], &nParam, sizeof(OMX_U32)); } - - if (nRet == -1) - { - eError = OMX_ErrorInsufficientResources; - goto EXIT; + + if (nRet == -1) { + OMX_ERROR4(pCompPrivate->dbg, "%d :: OMX_ErrorInsufficientResources from SendCommand",__LINE__); + if(Cmd == OMX_CommandStateSet) { + if(RemoveStateTransition(pCompPrivate, OMX_FALSE) != OMX_ErrorNone) { + return OMX_ErrorUndefined; + } + } + return OMX_ErrorInsufficientResources; } - + + EXIT: OMX_PRINT1(pCompPrivate->dbg, "%d :: AACENC: Exiting SendCommand()\n", __LINE__); return eError; @@ -1365,30 +1387,68 @@ EXIT: **/ /*-------------------------------------------------------------------*/ -static OMX_ERRORTYPE GetState (OMX_HANDLETYPE pComponent, OMX_STATETYPE* pState) +static OMX_ERRORTYPE GetState (OMX_HANDLETYPE hComponent, OMX_STATETYPE* pState) { - OMX_ERRORTYPE eError = OMX_ErrorUndefined; - OMX_CONF_CHECK_CMD(pComponent,1,1); - OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *)pComponent; - AACENC_COMPONENT_PRIVATE *pComponentPrivate = (AACENC_COMPONENT_PRIVATE *)pHandle->pComponentPrivate; - OMX_PRINT1 (pComponentPrivate->dbg, "%d :: AACENC: Entering GetState\n", __LINE__); - if (!pState) - { - eError = OMX_ErrorBadParameter; - OMX_ERROR4 (pComponentPrivate->dbg, "%d :: Error: About to return OMX_ErrorBadParameter \n",__LINE__); - goto EXIT; + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_COMPONENTTYPE* pHandle = NULL; + AACENC_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; + + if(hComponent == NULL || pState == NULL) { + return OMX_ErrorBadParameter; } - if (pHandle && pComponentPrivate) - { - *pState = pComponentPrivate->curState; - } - else - { - *pState = OMX_StateLoaded; + pHandle = (OMX_COMPONENTTYPE*)hComponent; + pComponentPrivate = (AACENC_COMPONENT_PRIVATE*)pHandle->pComponentPrivate; + + /* Retrieve current state */ + if (pHandle && pHandle->pComponentPrivate) { + /* 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 = ((AACENC_COMPONENT_PRIVATE*)pHandle->pComponentPrivate)->curState; + 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 = ((AACENC_COMPONENT_PRIVATE*)pHandle->pComponentPrivate)->curState; + 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; } - eError = OMX_ErrorNone; + + return eError; EXIT: OMX_PRINT1 (pComponentPrivate->dbg, "%d :: AACENC: Exiting GetState\n", __LINE__); @@ -1682,6 +1742,9 @@ static OMX_ERRORTYPE ComponentDeInit(OMX_HANDLETYPE pHandle) OMX_PRBUFFER2(dbg, "%d :: AACENC: After AACENC_FreeCompResources\n",__LINE__); OMX_PRBUFFER2(dbg, "%d :: AACENC: [FREE] %p\n",__LINE__,pComponentPrivate); + pthread_mutex_destroy(&pComponentPrivate->mutexStateChangeRequest); + pthread_cond_destroy(&pComponentPrivate->StateChangeCondition); + if (pComponentPrivate->sDeviceString != NULL) { OMX_MEMFREE_STRUCT(pComponentPrivate->sDeviceString); -- cgit v1.2.3