广安公司网站建设重庆建设教育协会网站首页
web/
2025/9/29 13:35:09/
文章来源:
广安公司网站建设,重庆建设教育协会网站首页,wordpress安装视频,做网站设计所遇到的问题这一节我们将了解Android OpenMax框架#xff0c;该框架了解完成之后#xff0c;我们会再回过头去了解 ACodec#xff0c;将 MediaCodec - ACodec - OpenMax 连接起来#xff0c;了解组件的创建控制以及 buffer 的流转。 本篇属于个人学习笔记#xff0c;如有错误欢迎指出… 这一节我们将了解Android OpenMax框架该框架了解完成之后我们会再回过头去了解 ACodec将 MediaCodec - ACodec - OpenMax 连接起来了解组件的创建控制以及 buffer 的流转。 本篇属于个人学习笔记如有错误欢迎指出。 我将Android OpenMax框架分为3个部分来学习
media.codec servicevendor下的HIDL服务用于查询平台编解码能力创建/管理编解码组件OpenMax ILOpenMax 框架标准接口底层编解码组件须实现这些接口OMXNodeInstanceOpenMax AL 完成 OpenMax IL层的封装与调用提供给上层 ACodec 调用
这一节我们先来了解下相关的代码路径
hardware/interfaces/media/omx/1.0 目录下定义有 media.codec 提供的 HIDL service 接口我们接触比较多的是IOmx.halIOmxStore.halIOmxStore.hal以及IOmxNode.halframeworks/av/services/mediacodec目录下是 media.codec service 实现文件编译后会生成 android.hardware.media.omx1.0-service位于板子 /vendor/bin/hw 目录下frameworks/av/media/libstagefright/omx目录下放有 media.codec service 的 Bn 端实现以及一些工具OMXUtils.cppframeworks/native/headers/media_plugin/media/openmax目录下放有 OpenMax 的标准接口底层 Omx Component 需要实现这些标准接口上层 ACodec 也需要按照标准接口来调用frameworks/av/media/libmedia/omx frameworks/av/media/libmedia/omx/1.0 以上两个目录下放有对 HIDL 调用的封装封装有两种类型一种是 LW Legacy Wrapper开头的类另一种是 TWTreble Wrapper开头的。
接下来我们来看这些文件是如何使用的
media.codec 作为一个 HIDL service 首先要有接口定义我们查看 hardware/interfaces/media/omx/1.0 目录可以发现 OpenMax 相关的类定义都是以大写的 I 开头后面接上 Omx这里的 O 是大写 mx 是小写。
接着看 frameworks/av/media/libstagefright/omx/1 目录路径下看到有 Omx.cpp 和 OmxStore.cpp这两个就是 media.codec 的 native 实现但是我们似乎没看到 IOmxNode 不要着急我们先接着往下看。
实现了服务相关的文件那么就要开启进程启动服务了相关的代码在 frameworks/av/services/mediacodec 下阅读 main_codecservice.cpp 的代码我们很容易就看出这个进程提供两个服务 IOmx 和 IOmxStore具体的代码这里不再展开所以上面提到的 IOmxNode 并不是一个服务而是服务提供的内容接下来的问题就是内容实现在哪里呢
服务启动后我们要获取并调用服务这里就要看 ACodec 的代码了 spCodecObserver observer new CodecObserver(notify);spIOMX omx;spIOMXNode omxNode;status_t err NAME_NOT_FOUND;OMXClient client;if (client.connect(owner.c_str()) ! OK) {return false;}omx client.interface();int prevPriority androidGetThreadPriority(tid);err omx-allocateNode(componentName.c_str(), observer, omxNode);这里看到 ACodec 并没有获取 IOmx 服务而是使用 OMXClient 封装了服务获取过程接着再调用其 interface 接口返回获取的服务代理不过这里有点要注意返回代理的类型是 IOMX三个字母都是大写并不是之前提到的 IOmx里面发生了什么
status_t OMXClient::connect(const char* name) {using namespace ::android::hardware::media::omx::V1_0;if (name nullptr) {name default;}spIOmx tOmx IOmx::getService(name);if (tOmx.get() nullptr) {ALOGE(Cannot obtain IOmx service.);return NO_INIT;}if (!tOmx-isRemote()) {ALOGE(IOmx service running in passthrough mode.);return NO_INIT;}mOMX new utils::LWOmx(tOmx);ALOGI(IOmx service obtained);return OK;
}从 OMXClient::connect 我们可以看到内部获取的服务代理类型仍为 IOmx但是又对该代理做了一层封装。IOmx 是一个 Treble 类型的对象LWOmx 是一个 Legacy 类型的对象。
我们都知道调用 Treble 对象方法时会比较麻烦要回传函数调用返回值时需要构造一个Lambda函数Legacy 对象的使用是符合我们常规使用习惯的对象。所以将 IOmx 封装成为 LWOmx 是为了封装 HIDL 调用简化使用。
WOmx.h 位于 frameworks/av/media/libmedia/include/media/omx/1.0可以看到它是继承于 IOMX的再看 IOMX.h 可以发现其方法名和 IOmx 提供的服务是一致的那这里就验证了我们的猜想:IOMX 是对 IOmx 代理调用的封装。
与之类似的调用 IOmx 服务获取 IOmxNode 对象后也要将其封装成为 LW 类型以便后续的使用
status_t LWOmx::allocateNode(char const* name,spIOMXObserver const observer,spIOMXNode* omxNode) {status_t fnStatus;status_t transStatus toStatusT(mBase-allocateNode(name, new TWOmxObserver(observer),[fnStatus, omxNode](Status status, spIOmxNode const node) {fnStatus toStatusT(status);*omxNode new LWOmxNode(node);}));return transStatus NO_ERROR ? fnStatus : transStatus;
}上面都是讲 mediaserver 进程使用 media.codec 进程的服务代理那有没有反过来调用的情况当然是有的。
还是看 LWOmx::allocateNode我们会传入一个 CodecObserver 对象用于接收Omx Callback但是CodecObserver 是继承于 BnOMXObserver 的这里会有个问题CodecObserver 将无法通过 HIDL 调用传递给 media.codec 进程所以调用之前 LWOmx::allocateNode 将 CodecObserver 封装到了 TWOmxObserver 以便该对象可以通过 HIDL 传输。
struct TWOmxObserver : public IOmxObserver {spIOMXObserver mBase;TWOmxObserver(spIOMXObserver const base);Returnvoid onMessages(const hidl_vecMessage tMessages) override;
};TWOmxObserver 继承于IOmxObserver 接口因此可以在 HIDL 中进行传输这也是 TW Treble Wrapper的作用。
再看 frameworks/av/media/libmedia/include/media/omx/1.0/WOmxObserver.h 里面还有个 LWOmxObserver 它的作用上面我们已经讲过了是将 mediaserver 进程传过来的 TWOmxObserver 对象进行封装达到简化 HIDL 调用的目的。 这一节我们对 Android OpenMax 相关的文件以及类做了简单介绍了解这些之后我们再追代码就可以忽略掉一些中间层后期如果相关的写作疑问也可以参考这里。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/83921.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!