summaryrefslogtreecommitdiff
path: root/omx
diff options
context:
space:
mode:
authorBenny Wong <Benny.Wong@motorola.com>2009-09-30 17:50:08 -0500
committerJames Dong <jdong@google.com>2009-09-30 18:40:08 -0700
commiteced958917cca059f5e7222a83a44adc4e259c67 (patch)
tree03ac51bae3e2e5891af204e65b9a985748f05330 /omx
parent1348a0db59d75e00b3e0f33678d06f6671a6d4d6 (diff)
downloadomap3-eced958917cca059f5e7222a83a44adc4e259c67.tar.gz
To get GetState to block for pending state transitions to complete for aac encoder
Originally from: https://partner.source.android.com/g/#change,1210
Diffstat (limited to 'omx')
-rw-r--r--omx/audio/src/openmax_il/aac_enc/inc/OMX_AacEnc_Utils.h9
-rw-r--r--omx/audio/src/openmax_il/aac_enc/src/OMX_AacEnc_Utils.c87
-rw-r--r--omx/audio/src/openmax_il/aac_enc/src/OMX_AacEncoder.c187
3 files changed, 219 insertions, 64 deletions
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);