summaryrefslogtreecommitdiff
path: root/omx
diff options
context:
space:
mode:
authorBenny Wong <Benny.Wong@motorola.com>2009-09-30 08:21:56 -0500
committerJames Dong <jdong@google.com>2009-09-30 11:17:03 -0700
commit0c1fc978146aeb80d968d0b27abe70bf84c62ed4 (patch)
treeab2212892fab0595abe9abe6bc8e39a4028cdb5e /omx
parenta900245aa2a3e0ca1419032ae076264203776199 (diff)
downloadomap3-0c1fc978146aeb80d968d0b27abe70bf84c62ed4.tar.gz
To get GetState to block for pending state transitions to complete for video encode
Originally from: https://partner.source.android.com/g/#change,1200
Diffstat (limited to 'omx')
-rw-r--r--omx/video/src/openmax_il/video_encode/inc/OMX_VideoEnc_Utils.h31
-rw-r--r--omx/video/src/openmax_il/video_encode/src/OMX_VideoEnc_Utils.c105
-rw-r--r--omx/video/src/openmax_il/video_encode/src/OMX_VideoEncoder.c96
3 files changed, 191 insertions, 41 deletions
diff --git a/omx/video/src/openmax_il/video_encode/inc/OMX_VideoEnc_Utils.h b/omx/video/src/openmax_il/video_encode/inc/OMX_VideoEnc_Utils.h
index 9788089..a4f3b9d 100644
--- a/omx/video/src/openmax_il/video_encode/inc/OMX_VideoEnc_Utils.h
+++ b/omx/video/src/openmax_il/video_encode/inc/OMX_VideoEnc_Utils.h
@@ -653,20 +653,26 @@ typedef struct VIDENC_COMPONENT_PRIVATE
OMX_Event InIdle_event;
OMX_U8 InIdle_goingtoloaded;
#endif
- unsigned int nEncodingPreset;
- VIDENC_AVC_NAL_FORMAT AVCNALFormat;
- OMX_BOOL bMVDataEnable;
- OMX_BOOL bResyncDataEnable;
- IH264VENC_Intra4x4Params intra4x4EnableIdc;
- OMX_U32 maxMVperMB;
- #ifdef RESOURCE_MANAGER_ENABLED
- RMPROXY_CALLBACKTYPE cRMCallBack;
- #endif
- OMX_BOOL bPreempted;
- OMX_VIDEO_CODINGTYPE compressionFormats[3];
+ unsigned int nEncodingPreset;
+ VIDENC_AVC_NAL_FORMAT AVCNALFormat;
+ OMX_BOOL bMVDataEnable;
+ OMX_BOOL bResyncDataEnable;
+ IH264VENC_Intra4x4Params intra4x4EnableIdc;
+ OMX_U32 maxMVperMB;
+#ifdef RESOURCE_MANAGER_ENABLED
+ RMPROXY_CALLBACKTYPE cRMCallBack;
+#endif
+ OMX_BOOL bPreempted;
+ OMX_VIDEO_CODINGTYPE compressionFormats[3];
OMX_COLOR_FORMATTYPE colorFormats[3];
struct OMX_TI_Debug dbg;
PV_OMXComponentCapabilityFlagsType* pCapabilityFlags;
+
+ /* Reference count for pending state change requests */
+ OMX_U32 nPendingStateChangeRequests;
+ pthread_mutex_t mutexStateChangeRequest;
+ pthread_cond_t StateChangeCondition;
+
} VIDENC_COMPONENT_PRIVATE;
typedef OMX_ERRORTYPE (*fpo)(OMX_HANDLETYPE);
@@ -731,4 +737,7 @@ void OMX_VIDENC_ResourceManagerCallBack(RMPROXY_COMMANDDATATYPE cbData);
OMX_U32 GetMaxAVCBufferSize(OMX_U32 width, OMX_U32 height);
+OMX_ERRORTYPE AddStateTransition(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
+OMX_ERRORTYPE RemoveStateTransition(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BOOL bEnableSignal);
+
#endif
diff --git a/omx/video/src/openmax_il/video_encode/src/OMX_VideoEnc_Utils.c b/omx/video/src/openmax_il/video_encode/src/OMX_VideoEnc_Utils.c
index 391a724..4982cf4 100644
--- a/omx/video/src/openmax_il/video_encode/src/OMX_VideoEnc_Utils.c
+++ b/omx/video/src/openmax_il/video_encode/src/OMX_VideoEnc_Utils.c
@@ -1504,21 +1504,27 @@ OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetIdle(VIDENC_COMPONENT_PRIVATE* pCo
}
if (eError != OMX_ErrorNone)
{
- OMX_VIDENC_EVENT_HANDLER(pComponentPrivate,
+ OMX_VIDENC_EVENT_HANDLER(pComponentPrivate,
OMX_EventError,
OMX_ErrorHardware,
OMX_TI_ErrorSevere,
NULL);
}
- if (eError == OMX_ErrorNone)
- {
- pComponentPrivate->eState = OMX_StateIdle;
+ if (eError == OMX_ErrorNone) {
+
+ pComponentPrivate->eState = OMX_StateIdle;
#ifdef __PERF_INSTRUMENTATION__
PERF_Boundary(pComponentPrivate->pPERFcomp,
PERF_BoundaryComplete | PERF_BoundarySetup);
#endif
- OMX_VIDENC_EVENT_HANDLER(pComponentPrivate,
+
+ /* Decrement reference count with signal enabled */
+ if(RemoveStateTransition(pComponentPrivate, 1) != OMX_ErrorNone) {
+ return OMX_ErrorUndefined;
+ }
+
+ OMX_VIDENC_EVENT_HANDLER(pComponentPrivate,
OMX_EventCmdComplete,
OMX_CommandStateSet,
OMX_StateIdle,
@@ -1539,6 +1545,12 @@ OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetIdle(VIDENC_COMPONENT_PRIVATE* pCo
PERF_Boundary(pComponentPrivate->pPERFcomp,
PERF_BoundaryComplete | PERF_BoundarySetup);
#endif
+
+ /* Decrement reference count with signal enabled */
+ if(RemoveStateTransition(pComponentPrivate, 1) != OMX_ErrorNone) {
+ return OMX_ErrorUndefined;
+ }
+
OMX_VIDENC_EVENT_HANDLER(pComponentPrivate,
OMX_EventCmdComplete,
OMX_CommandStateSet,
@@ -1741,17 +1753,24 @@ OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetIdle(VIDENC_COMPONENT_PRIVATE* pCo
#endif
OMX_PRBUFFER2(pComponentPrivate->dbg, "Flushing Pipes!\n");
- eError = OMX_VIDENC_EmptyDataPipes (pComponentPrivate);
+ eError = OMX_VIDENC_EmptyDataPipes (pComponentPrivate);
OMX_DBG_BAIL_IF_ERROR(eError, pComponentPrivate->dbg, OMX_PRBUFFER3,
"Flushing pipes failed (%x).\n", eError);
- pComponentPrivate->eState = OMX_StateIdle;
- OMX_VIDENC_EVENT_HANDLER(pComponentPrivate,
+ pComponentPrivate->eState = OMX_StateIdle;
+
+ /* Decrement reference count with signal enabled */
+ if(RemoveStateTransition(pComponentPrivate, 1) != OMX_ErrorNone) {
+ return OMX_ErrorUndefined;
+ }
+
+ OMX_VIDENC_EVENT_HANDLER(pComponentPrivate,
OMX_EventCmdComplete,
OMX_CommandStateSet,
OMX_StateIdle,
NULL);
- break;
+ break;
+
default:
OMX_VIDENC_EVENT_HANDLER(pComponentPrivate,
OMX_EventError,
@@ -1864,6 +1883,12 @@ OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetExecuting(VIDENC_COMPONENT_PRIVATE
PERF_Boundary(pComponentPrivate->pPERFcomp,
PERF_BoundaryStart | PERF_BoundarySteadyState);
#endif
+
+ /* Decrement reference count with signal enabled */
+ if(RemoveStateTransition(pComponentPrivate, 1) != OMX_ErrorNone) {
+ return OMX_ErrorUndefined;
+ }
+
/*Send state change notificaiton to Application*/
OMX_VIDENC_EVENT_HANDLER(pComponentPrivate,
OMX_EventCmdComplete,
@@ -1954,6 +1979,10 @@ OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetPause (VIDENC_COMPONENT_PRIVATE* p
pComponentPrivate->eState = OMX_StatePause;
+ /* Decrement reference count with signal enabled */
+ if(RemoveStateTransition(pComponentPrivate, 1) != OMX_ErrorNone) {
+ return OMX_ErrorUndefined;
+ }
OMX_VIDENC_EVENT_HANDLER(pComponentPrivate,
OMX_EventCmdComplete,
@@ -2008,7 +2037,7 @@ OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetLoaded (VIDENC_COMPONENT_PRIVATE*
break;
case OMX_StateWaitForResources:
OMX_PRSTATE2(pComponentPrivate->dbg, "Transitioning from WFR to Loaded\n");
- #ifdef RESOURCE_MANAGER_ENABLED
+#ifdef RESOURCE_MANAGER_ENABLED
if (pPortDefOut->format.video.eCompressionFormat == OMX_VIDEO_CodingAVC)
{
/* TODO: Disable RM Send for now */
@@ -2054,8 +2083,13 @@ OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetLoaded (VIDENC_COMPONENT_PRIVATE*
NULL);
break;
}
- #endif
- pComponentPrivate->eState = OMX_StateLoaded;
+#endif
+ pComponentPrivate->eState = OMX_StateLoaded;
+ /* Decrement reference count with signal enabled */
+ if(RemoveStateTransition(pComponentPrivate, 1) != OMX_ErrorNone) {
+ return OMX_ErrorUndefined;
+ }
+
#ifdef __PERF_INSTRUMENTATION__
PERF_Boundary(pComponentPrivate->pPERFcomp,
@@ -2165,6 +2199,12 @@ OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetLoaded (VIDENC_COMPONENT_PRIVATE*
PERF_Boundary(pComponentPrivate->pPERFcomp,
PERF_BoundaryComplete | PERF_BoundaryCleanup);
#endif
+
+ /* Decrement reference count with signal enabled */
+ if(RemoveStateTransition(pComponentPrivate, 1) != OMX_ErrorNone) {
+ return OMX_ErrorUndefined;
+ }
+
OMX_VIDENC_EVENT_HANDLER(pComponentPrivate,
OMX_EventCmdComplete,
OMX_CommandStateSet,
@@ -4053,3 +4093,44 @@ OMX_U32 GetMaxAVCBufferSize(OMX_U32 width, OMX_U32 height)
/*150(bytes) = 1200(bits)/8 SN release notes*/
return 150*MaxCPB;
}
+
+OMX_ERRORTYPE AddStateTransition(VIDENC_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(VIDENC_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_encode/src/OMX_VideoEncoder.c b/omx/video/src/openmax_il/video_encode/src/OMX_VideoEncoder.c
index 05c5f4e..3998db3 100644
--- a/omx/video/src/openmax_il/video_encode/src/OMX_VideoEncoder.c
+++ b/omx/video/src/openmax_il/video_encode/src/OMX_VideoEncoder.c
@@ -998,6 +998,15 @@ sDynamicFormat = getenv("FORMAT");
OMX_CreateEvent(&(pComponentPrivate->InLoaded_event));
OMX_CreateEvent(&(pComponentPrivate->InIdle_event));
#endif
+
+ if(pthread_mutex_init(&pComponentPrivate->mutexStateChangeRequest, NULL)) {
+ return OMX_ErrorUndefined;
+ }
+
+ if(pthread_cond_init (&pComponentPrivate->StateChangeCondition, NULL)) {
+ return OMX_ErrorUndefined;
+ }
+
OMX_CONF_CMD_BAIL:
OMX_PRINT2(dbg, "Component Init Exit\n");
return eError;
@@ -1158,30 +1167,32 @@ static OMX_ERRORTYPE SendCommand (OMX_IN OMX_HANDLETYPE hComponent,
switch (Cmd)
{
case OMX_CommandStateSet:
+ /* Add a pending transition */
+ if(AddStateTransition(pComponentPrivate) != OMX_ErrorNone) {
+ return OMX_ErrorUndefined;
+ }
#ifdef __KHRONOS_CONF__
- if(nParam1 == OMX_StateLoaded &&
- pComponentPrivate->eState == OMX_StateIdle)
- {
+ if(nParam1 == OMX_StateLoaded && pComponentPrivate->eState == OMX_StateIdle) {
pComponentPrivate->bPassingIdleToLoaded = OMX_TRUE;
}
#endif
OMX_PRCOMM2(pComponentPrivate->dbg, "Write to cmd pipe!\n");
nRet = write(pComponentPrivate->nCmdPipe[1], &Cmd, sizeof(Cmd));
- if (nRet == -1)
- {
- OMX_DBG_SET_ERROR_BAIL(eError, OMX_ErrorUndefined,
- pComponentPrivate->dbg, OMX_PRCOMM4,
- "Failed to write to cmd pipe.\n");
+ if (nRet == -1) {
+ /* Decrement reference count without generating any signal */
+ if(RemoveStateTransition(pComponentPrivate, 0) != OMX_ErrorNone) {
+ return OMX_ErrorUndefined;
+ }
}
nRet = write(pComponentPrivate->nCmdDataPipe[1],
&nParam1,
sizeof(nParam1));
- if (nRet == -1)
- {
- OMX_DBG_SET_ERROR_BAIL(eError, OMX_ErrorUndefined,
- pComponentPrivate->dbg, OMX_PRCOMM4,
- "Failed to write to cmd pipe.\n");
+ if (nRet == -1) {
+ /* Decrement reference count without generating any signal */
+ if(RemoveStateTransition(pComponentPrivate, 0) != OMX_ErrorNone) {
+ return OMX_ErrorUndefined;
+ }
}
break;
case OMX_CommandFlush:
@@ -2618,17 +2629,63 @@ static OMX_ERRORTYPE GetState (OMX_IN OMX_HANDLETYPE hComponent,
OMX_OUT OMX_STATETYPE* pState)
{
OMX_ERRORTYPE eError = OMX_ErrorNone;
+ OMX_COMPONENTTYPE* pHandle = NULL;
VIDENC_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(hComponent, ((OMX_COMPONENTTYPE *) hComponent)->pComponentPrivate, 1);
+ if(hComponent == NULL || pState == NULL) {
+ return OMX_ErrorBadParameter;
+ }
- pComponentPrivate = (VIDENC_COMPONENT_PRIVATE*)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
- OMX_DBG_CHECK_CMD(pComponentPrivate->dbg, pState, 1, 1);
+ pHandle = (OMX_COMPONENTTYPE*)hComponent;
+ pComponentPrivate = (VIDENC_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;
+ }
- *pState = pComponentPrivate->eState;
+ /* No pending state transitions */
+ *pState = ((VIDENC_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 = ((VIDENC_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;
+ }
-OMX_CONF_CMD_BAIL:
return eError;
}
@@ -3098,6 +3155,9 @@ static OMX_ERRORTYPE ComponentDeInit(OMX_IN OMX_HANDLETYPE hComponent)
PERF_Done(pComponentPrivate->pPERF);
#endif
+ pthread_mutex_destroy(&pComponentPrivate->mutexStateChangeRequest);
+ pthread_cond_destroy(&pComponentPrivate->StateChangeCondition);
+
if (pComponentPrivate != NULL)
{
VIDENC_FREE(pComponentPrivate, pMemoryListHead, dbg);