The first port being enabled to the Camera Input port ( Port #73 ), the port is being enabled using the “OMX_CommandPortEnable” command, as with the “OMX_CommandPortDisable” command, it is expected for the camera component to fire it’s “OMX_CALLBACKTYPE::EventHandler” event handler having “eEvent == OMX_EventCmdComplete” and “nData1 == OMX_CommandPortEnable”, however, this never happen and the application infinitely wait for the port to become enabled.
I am using std::condition_variable in conjunction with std::mutex to wait for the state change to complete, hence, OMX_CALLBACKTYPE::EventHandler updates the condition variable and calls “notify_one()” while the caller thread locks std::mutex and wait for the condition variable to be set, using this approach “OMX_CALLBACKTYPE::EventHandler” is never called ( with any argument ), and the program locks forever.
NOTE: When waiting for the condition variable the mutex is verified not to be owned, this is done by verifying (0 == std::mutex::__owner).
HOWEVER, All works fine when polling the status of the port by calling usleep and OMX_GetParameter(OMX_IndexParamPortDefinition) iteratively.
Why is “OMX_CALLBACKTYPE::EventHandler” triggered when polling it’s value and NOT triggered when using a conditional_variable? With windows there is the notion of APC & Alertable threads, is there any equivalent in linux? One that can explain the above mentioned?
My experience is that enabling a port does not issue the event callback until the port is populated with buffers. That is, the sequence is:
OMX_SendCommand()
with OMX_CommandPortEnable
).OMX_AllocateBuffer()
or OMX_UseBuffer()
).OMX_CommandPortEnable
event callback.If you wait for the event callback before you allocate the buffers then you will have deadlock.
When you poll by testing OMX_PARAM_PORTDEFINITIONTYPE.bEnabled
, that is going to return OMX_TRUE
immediately because the spec says this member is set synchronously:
The port shall immediately set
bEnabled
in its port definition structure when the port receivesOMX_CommandPortEnable
.
Here's what I think is happening for you when things "work":
bEnabled
is OMX_TRUE
(which happens immediately).OMX_CommandPortEnable
event callback.You may be mistakenly thinking that it happens in this order instead:
bEnabled
is OMX_TRUE
(which happens immediately).OMX_CommandPortEnable
event callback.This makes it seem that using a condition variable somehow changes OpenMAX behavior. In actuality bEnabled
and the OMX_CommandPortEnable
callback aren't really reporting the same thing. I don't believe that any synchronization is necessary (or desirable) between enabling the port and allocating its buffers.