Android-StageFright之OpenMAX的实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Android-StageFright之OpenMAX的实现
Android-StageFright之OpenMAX的实现
OMXCodec是一个MediaSource,完成数据的parse和decode。

而OMXCodec则主要通过IOMX跨越OpenBinder机制操作OMX 来实现。

重点介绍一下OMX。

OMX主要完成三个任务,NodeInstance 列表的管理,针对一个NodeInstance的操作以及事件的处理。

一、NodeInstance列表的管理。

这个主要包括NodeInstance的生成(allocateNode)和删除(freeNode)。

其实就是对mDispatchers和mNodeIDT oInstance 进行添加和删除。

mNodeIDToInstance就是一个key为node_id,value为NodeInstance的名值对列表。

而mDispatchers就是一个key为node_id,value为 OMX::CallbackDispatcher的名值对列表。

并且,一个NodeInstance都拥有一个 OMX::CallbackDispatcher。

二、NodeInstance节点的操作。

主要成员函数如下:
sendCommand
getParameter
setParameter
… …
fillBuffer
emptyBuffer
getExtensionIndex
这些方法执行时,都是先通过findInstance在mNodeIDT oInstance列表中找到对应的NodeInstance,然后调用NodeInstance对应的方法。

三、事件处理
先看一下OMXNodeInstance.cpp中的这样一段代码:
1 2 3 4 5
OMX_CALLBACKTYPE OMXNodeInstance ::kCallbacks = { &OnEvent , &OnEmptyBufferDone , &OnFillBufferDone };
它把三个OMXNodeInstance 类的静态方法注册给了kCallbacks 。

而kCallbacks 在哪里使用呢?看一下OMX.cpp 中的allocateNode 方法中的代码:
1 2 3 4 5
OMX_ERRORTYPE err = mMaster ->makeComponentInstance ( name, &OMXNodeInstance ::kCallbacks, instance, &handle );
事件处理函数传给了组件ComponentInstance 。

当组件有事件发生时,就会调用OMXNodeInstance 中这几个注册过的事件处理函数,而这几个函数又会去调用OMX 中对应的函数,也就是下面这三个:
OnEvent 、OnEmptyBufferDone 、OnFillBufferDone 。

这几个方法都采用相同的路子:根据node_id 找到CallbackDispatcher ,并把事件信息post 过去。

具体点儿,就是调用findDispatcher(node)->post(msg)。

这里不得不提一下CallbackDispatcher 的实现机制。

它内部开启了一个线程,使用了信号量机制。

可以看一下OMX::CallbackDispatcher 的属性:Condition mQueueChanged;
可以看出findDispatcher(node)->post(msg)是一个异步操作,只把msg 给POST 过去,不会等待事件处理完毕就返回了。

那么CallbackDispatcher 是怎么处理接收到的msg 呢?看以下代码: 1 2 3 4 5 6 OMX ::CallbackDispatcher ::threadEntry () dispatch (msg ); mOwner ->onMessage (msg );
7
8
mObserver ->onMessage (msg ); 这个mObserver 是哪来的?OMXCodec::Create 中初始化IOMX 时传入的。

1 2 3 4 5
sp <OMXCodecObserver > observer = new OMXCodecObserver ; ... ... omx ->allocateNode (componentName , observer , &node ); 这样算下来,事件最终还是跨越OpenBinder 又传到了OMXCodec 里面去,交给OMXCodecObserver 了。

对节点的操作
NodeInstance 的大部分方法的实现,如sendCommand 等,都是通过OMX_Core.h 中的宏定义间接调用 OMX_Component.h 中的OMX_COMPONENTTYPE 这个struct 中的相应函数指针来完成。

在这里提到的OMX_Core.h 和 OMX_Component.h 都是OpenMAX 标准头文件。

相关文档
最新文档