伊戈达拉把球扣出篮筐:Android-StageFright之OpenMAX的实现

来源:百度文库 编辑:偶看新闻 时间:2024/05/06 05:54:26

Android-StageFright之OpenMAX的实现

OMXCodec是一个MediaSource,完成数据的parse和decode。而OMXCodec则主要通过IOMX跨越OpenBinder机制操作OMX来实现。

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

一、NodeInstance列表的管理。

这个主要包括NodeInstance的生成(allocateNode)和删除(freeNode)。其实就是对mDispatchers和 mNodeIDToInstance进行添加和删除。mNodeIDToInstance就是一个key为node_id,value为 NodeInstance的名值对列表。而mDispatchers就是一个key为node_id,value为 OMX::CallbackDispatcher的名值对列表。并且,一个NodeInstance都拥有一个 OMX::CallbackDispatcher。

二、NodeInstance节点的操作。

主要成员函数如下:

sendCommand

getParameter

setParameter

… …

fillBuffer

emptyBuffer

getExtensionIndex

这些方法执行时,都是先通过findInstance在mNodeIDToInstance列表中找到对应的NodeInstance,然后调用NodeInstance对应的方法。

三、事件处理

先看一下OMXNodeInstance.cpp中的这样一段代码:

12345
OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {     &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone };

它把三个OMXNodeInstance类的静态方法注册给了kCallbacks。而kCallbacks在哪里使用呢?看一下OMX.cpp中的allocateNode方法中的代码:

12345
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呢?看以下代码:

12345678
OMX::CallbackDispatcher::threadEntry()           dispatch(msg);       mOwner->onMessage(msg); mObserver->onMessage(msg);

这个mObserver是哪来的?OMXCodec::Create中初始化IOMX时传入的。

12345
sp 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标准头文件。