解析以OpenMAX非Tunneled为例,从应用线程开始。 一、应用线程基本流程 1. OMX_Init() 2. 获取句柄,组件转到Loaded状态 OMX_GetHandle(out handle, in componentName, in appData, in callbacks); 其中callbacks结构包括三个回调函数指针(作用后文介绍): 1) EventHandler 2) EmptyBufferDone 3) FillBufferDone 3. 参数交互 如: OMX_GetParameter(in handle, in type, out param); OMX_SetParameter(in handle, in type, in param); 其中关键需要设置每个端口上的Buffer数量,一般采用2个Buffer,如下对端口参数进行设置: paramPort.nBufferCountActual = 2; 具体参数详见后文介绍 4. 命令组件转到Idle状态 OMX_SendCommand(in handle, in cmd = OMX_CommandStateSet, in nParam = OMX_StateIdle, in pCmdData = 0); 5. Idle期准备 包括: 1) Buffer分配 2) 等待组件正式转到Idle状态,这个由信号量控制。这个信号量在上述EventHandler回调函数中put,而这个回调函数在状态转换完毕以后作为OMX_EventCmdComplete事件的响应被调用。 6. 组件转到Executing状态 OMX_SendCommand(in handle, in cmd = OMX_CommandStateSet, in nParam = OMX_StateExecuting, in pCmdData = 0); 命令组件转到Executing状态 等待转换完成,同样用信号量控制。 7. 初始化端口Buffer并绑定 通过调用OMX_FillThisBuffer设置组件的输出Buffer 通过调用OMX_EmptyThisBuffer设置组件的输入Buffer,此处可为输入Buffer加载初始数据流。 8. 主线程消息循环 在这里等待应用信号量,其中包括组件完毕的消息,用以退出循环。 9. 收尾工作1:命令并等待组件进入Idle状态 10. 收尾工作2:命令并等待组件进入Loaded状态,并销毁Buffer 11. 释放组件句柄 二、组件缓冲处理 当组件完成数据输出(Fill Buffer)后会调用FillBufferDone回调函数以通知应用层准备数据(仅非Tunneled模式) 函数C代码原型: FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent, OMX_OUT OMX_PTR pAppData, OMX_OUT OMX_BUFFERHEADERTYPE *pBuffer) 其中hComponent是组件句柄;pAppData为GetHandle时赋入的应用数据;pBuffer为缓冲地址。由于该缓冲已经填写完毕(通常是一帧完成),回调函数将改数据输出到适当位置,完后再次调用OMX_FillThisBuffer,链入下一轮工作。 当组件完成数据消耗(Empty Buffer)后会调用EmptyBufferDone回调函数以通知应用层准备数据(仅非Tunneled模式) 函数C代码原型: EmptyBufferDone(OMX_OUT OMX_HANDLETYPE hComponent, OMX_OUT OMX_PTR pAppData, OMX_OUT OMX_BUFFERHEADERTYPE *pBuffer) 三个参数含义同上。由于改缓冲已经消耗殆尽,回调函数将读入数据载入缓冲,完后再次调用OMX_EmptyThisBuffer,链入下一轮工作。 上述缓冲操作是组件运行的一个环节,OpenMAX组件运行于一个独立线程。 三、组件事件处理 当组件接收到一个OpenMAX事件时会调用EventHandler EventHandler(OMX_OUT OMX_HANDLETYPE hComponent, OMX_OUT OMX_PTR pAppData, OMX_OUT OMX_EVENTTYPE eEvent, OMX_OUT OMX_U32 nData1, OMX_OUT OMX_U32 nData2, OMX_IN OMX_PTR pEventData); 其中前两个参数已在第二章介绍。eEvent为事件代号,例如第一章提到的OMX_SendCommand,对命令完成的所引发的事件即OMX_EventCmdComplete。 nData1 和nData2是该事件的两个关联数据。例如,对于命令完成事件,如果命令为状态切换,其中nData1即 OMX_CommandStateSet;nData2即对应的目标状态,如OMX_StateIdle等。又如对于缓冲事件,其eEvent为 OMX_EventBufferFlag,当nData2为OMX_BUFFERFLAG_EOS时往往说明输入码流结束,从而对该事件的响应通常是设置 EOF标记并put信号量通知处于循环中的应用线程。 |
|