您的位置:首页 > 移动开发 > Android开发

Android-StageFright之OpenMAX的实现

2012-06-11 21:54 281 查看


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中的这样一段代码:

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
56
7
8

OMX::CallbackDispatcher::threadEntry()

dispatch(msg);

mOwner->onMessage(msg);

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标准头文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: