当前位置: 首页 > news >正文

Android 13 - Media框架(25)- OMXNodeInstance(二)

上一节我们了解了 OMXNodeInstance 的创建过程,以及 IOmx 服务和 OMXNodeInstance、OMX组件之间的联系。接下来我们将一起了解 ACodec 是如何通过 OMXNodeInstance 这个中间层进行端口定义设置,以及端口Buffer分配的。

OMXNodeInstance 的代码还是比较长的,我们需要重点抓住和 Buffer 相关的内容,也就是端口定义、Buffer分配以及 Buffer 传递,了解了 Buffer 那我们对 OpenMax 的学习就会很轻松了。

1、setPortMode

我们之前在学习 ACodec configureCodec 流程时看到有很多 portMode,端口类型确定之后就会调用 setPortMode 方法将端口模式设定给 OMXNode,最终设置给 OMX 组件。

status_t ACodec::setPortMode(int32_t portIndex, IOMX::PortMode mode) {status_t err = mOMXNode->setPortMode(portIndex, mode);if (err != OK) {ALOGE("[%s] setPortMode on %s to %s failed w/ err %d",mComponentName.c_str(),portIndex == kPortIndexInput ? "input" : "output",asString(mode),err);return err;}mPortMode[portIndex] = mode;return OK;
}

OMXNodeInstance 会根据设定的内容对 OMX 组件进行配置,我们这里暂时只研究解码的情况,一般解码流程可能会涉及到如下几种 port Mode:

  • in Port
    • non-secure:kPortModePresetByteBuffer,上层可以直接读写buffer;
    • secure:kPortModePresetSecureBuffer,上层需要用特殊的方式读写buffer;
  • out Port
    • has native window
      • tunnel mode:上层不需要接收 output buffer;
      • non tunnel mode:kPortModeDynamicANWBuffer,使用动态的native window;
    • no native window
      • non-secure: kPortModePresetByteBuffer,上层可以直接读写buffer;
      • secure:error,不允许这种情况。

1.1、kPortModePresetByteBuffer

之前我们讲过,Preset 是预设的意思,表示这块buffer是预先分配好的,之后使用过程中就不会发生变化了;ByteBuffer 指的是普通的buffer,我们通过指针就可以读写buffer中的内容。

kPortModePresetByteBuffer 会在两个情况下使用:

  • 普通解码的 input buffer;
  • 普通解码且无surface的 output buffer;

这两种情况下是可以通过指针读写 buffer 中内容的,也就意味着内容是不受保护的。

status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {case IOMX::kPortModePresetByteBuffer:{// Disable secure buffer, native buffer and metadata.(void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);(void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);break;}
}

从注释中我们可以看出来,需要关闭端口的 secure buffer,native buffer以及metadata功能,这里的native buffer指的应该就是graphic buffer。

从这里我们可以猜测,OMX 组件端口使用的buffer可能有3种,默认使用普通buffer:

  • 普通buffer;
  • secure buffer;
  • graphic buffer;

1.1.1、enableNativeBuffers_l

使用普通 buffer 就要把另外两个配置关闭,这里可以通过enableNativeBuffers_l方法来完成,之所以通过一个方法(并且方法名为 native buffer),是因为这些buffer本身都应该是由 native 层分配。由于OMXNodeInstance 把 secure buffer, graphic buffer的设置放到一起了,所以enableNativeBuffers_l容易把人看晕,把他拆成两部分:

先看 native buffer(graphic buffer)的配置部分,除了调用OMX_SetParameter对组件进行设定外,还将 mGraphicBufferEnabled 数组置为了 true/false,用于标记端口是否使用graphic buffer,如果使用了就置为true,没有使用就置为false。

		OMX_STRING name = "OMX.google.android.index.enableAndroidNativeBuffers"EnableAndroidNativeBuffersParams params;InitOMXParams(&params);params.nPortIndex = portIndex;params.enable = enable;err = OMX_SetParameter(mHandle, index, &params);CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d", name, index,portString(portIndex), portIndex, enable);if (err == OMX_ErrorNone) {mGraphicBufferEnabled[portIndex] = enable;} else if (enable) {mGraphicBufferEnabled[portIndex] = false;}

再看 secure buffer 的配置部分,secure buffer 对应的配置名称为 native handle,这是因为native层分配的buffer会以handle的形式回传上层,从而保护buffer。

		OMX_STRING name = "OMX.google.android.index.allocateNativeHandle"EnableAndroidNativeBuffersParams params;InitOMXParams(&params);params.nPortIndex = portIndex;params.enable = enable;err = OMX_SetParameter(mHandle, index, &params);CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d", name, index,portString(portIndex), portIndex, enable);if (!graphic) {if (err == OMX_ErrorNone) {mSecureBufferType[portIndex] =enable ? kSecureBufferTypeNativeHandle : kSecureBufferTypeOpaque;} else if (mSecureBufferType[portIndex] == kSecureBufferTypeUnknown) {mSecureBufferType[portIndex] = kSecureBufferTypeOpaque;}}

如果 secure buffer 设置成功,那么 mSecureBufferType 会被设置为 kSecureBufferTypeNativeHandle,否则置为 kSecureBufferTypeOpaque。

我们这里大概知道:

  • secure buffer -> Native Handle;
  • graphic buffer -> Native Buffer;

1.1.2、storeMetaDataInBuffers_l

除了以上两项配置外,还有额外的meta data type需要配置,我们前面了解过graphic buffer需要和metadata 搭配使用,但是metadata也有不同的类型,我们需要告知 OMX 组件使用哪一种 metaData,运行过程中OMX组件就会根据类型来解析metaData了:

status_t OMXNodeInstance::storeMetaDataInBuffers_l(OMX_U32 portIndex, OMX_BOOL enable, MetadataBufferType *type) {OMX_INDEXTYPE index;OMX_STRING name = const_cast<OMX_STRING>("OMX.google.android.index.storeMetaDataInBuffers");OMX_STRING nativeBufferName = const_cast<OMX_STRING>("OMX.google.android.index.storeANWBufferInMetadata");MetadataBufferType negotiatedType;// 如果参数type不指定具体类型,那么默认使用kMetadataBufferTypeANWBufferMetadataBufferType requestedType = type != NULL ? *type : kMetadataBufferTypeANWBuffer;StoreMetaDataInBuffersParams params;InitOMXParams(&params);params.nPortIndex = portIndex;params.bStoreMetaData = enable;// 接下来是尝试设置 meta data type,如果设置不成功就设置另外一种OMX_ERRORTYPE err =requestedType == kMetadataBufferTypeANWBuffer? OMX_GetExtensionIndex(mHandle, nativeBufferName, &index): OMX_ErrorUnsupportedIndex;OMX_ERRORTYPE xerr = err;if (err == OMX_ErrorNone) {err = OMX_SetParameter(mHandle, index, &params);if (err == OMX_ErrorNone) {name = nativeBufferName; // set name for debuggingnegotiatedType = requestedType;}}if (err != OMX_ErrorNone) {err = OMX_GetExtensionIndex(mHandle, name, &index);xerr = err;if (err == OMX_ErrorNone) {negotiatedType =requestedType == kMetadataBufferTypeANWBuffer? kMetadataBufferTypeGrallocSource : requestedType;err = OMX_SetParameter(mHandle, index, &params);}if (err == OMX_ErrorBadParameter) {err = OMX_ErrorUnsupportedIndex;}}
...else {if (!enable) {negotiatedType = kMetadataBufferTypeInvalid;}mMetadataType[portIndex] = negotiatedType;}if (type != NULL) {*type = negotiatedType;}return StatusFromOMXError(err);
}

storeMetaDataInBuffers_l 的代码比较长,主要是因为由两种meta data,一种是 kMetadataBufferTypeANWBuffer,另一种是kMetadataBufferTypeGrallocSource

默认情况下storeMetaDataInBuffers_l的第三个参数不填类型,默认使用 kMetadataBufferTypeANWBuffer,也就是于 graphic buffer 搭配使用的 meta data类型。设置的 meta data类型会被记录到 mMetadataType 中,后续还会使用到。

如果是用的普通 buffer (Byte Buffer),那么就不需要meta data了,mMetadataType会被设置为 kMetadataBufferTypeInvalid

1.1.3、总结

综上:
当使用 Byte Buffer时,端口定义设置如下:

  • native handle(secure):disabled;
  • native buffer(graphic):disabled;
    • meta data:invaild;

1.2、kPortModeDynamicANWBuffer

有了上面内容的学习,设定端口为DynamicANWBuffer就很简单了:

    case IOMX::kPortModeDynamicANWBuffer:{if (portIndex == kPortIndexOutput) {if (mLegacyAdaptiveExperiment) {CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: ""not setting port mode to %s(%d) on output",asString(mode), mode);err = StatusFromOMXError(OMX_ErrorUnsupportedIndex);break;}err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);if (err != OK) {break;}}(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL);break;}

需要开启 grapihc buffer,关闭 secure buffer,使用 meta data,具体的端口设定如下:

  • native handle(secure):disabled;
  • native buffer(graphic):enabled;
    • meta data:kMetadataBufferTypeANWBuffer;

1.3、kPortModePresetSecureBuffer

secure buffer的设定同样很简单,需要关闭 grapihc buffer,开启 secure buffer,不使用 meta data,具体的端口设定如下:

  • native handle(secure):enabled;
  • native buffer(graphic):disabled;
    • meta data:invaild;
      这里我们要注意的是,secure buffer是不需要meta data的。
    case IOMX::kPortModePresetSecureBuffer:{// Allow on both input and output.(void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);(void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);err = enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_TRUE);break;}

相关文章:

Android 13 - Media框架(25)- OMXNodeInstance(二)

上一节我们了解了 OMXNodeInstance 的创建过程&#xff0c;以及 IOmx 服务和 OMXNodeInstance、OMX组件之间的联系。接下来我们将一起了解 ACodec 是如何通过 OMXNodeInstance 这个中间层进行端口定义设置&#xff0c;以及端口Buffer分配的。 OMXNodeInstance 的代码还是比较长…...

生物系统学中的进化树构建和分析R工具包V.PhyloMaker2的介绍和详细使用

V.PhyloMaker2是一个R语言的工具包&#xff0c;专门用于构建和分析生物系统学中的进化树&#xff08;也称为系统发育树或phylogenetic tree&#xff09;。以下是对V.PhyloMaker2的一些基本介绍和使用说明&#xff1a; 论文介绍&#xff1a;V.PhyloMaker2: An updated and enla…...

XStream 反序列化漏洞 CVE-2021-39144 已亲自复现

XStream 反序列化漏洞 CVE-2021-39144 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建 修复建议总结 漏洞名称 漏洞描述 在Unmarshalling Time处包含用于重新创建前一对象的类型信息。XStream基于这些类型的信息创建新实例。攻击者可以控制输入流并替换或注入对象&am…...

深入剖析LinkedList:揭秘底层原理

文章目录 一、 概述LinkedList1.1 LinkedList简介1.2 LinkedList的优点和缺点 二、 LinkedList数据结构分析2.1 Node节点结构体解析2.2 LinkedList实现了双向链表的原因2.3 LinkedList如何实现了链表的基本操作&#xff08;增删改查&#xff09;2.4 LinkedList的遍历方式 三、 …...

计算机网络复习-OSI TCP/IP 物理层

我膨胀了&#xff0c;挂我啊~ 作者简介&#xff1a; 每年都吐槽吉师网安奇怪的课程安排、全校正经学网络安全不超20人情景以及割韭菜企业合作的FW&#xff0c;今年是第一年。。 TCP/IP模型 先做两道题&#xff1a; TCP/IP协议模型由高层到低层分为哪几层&#xff1a; 这题…...

虚拟机服务器中了lockbit2.0/3.0勒索病毒怎么处理,数据恢复应对步骤

网络技术的不断发展也为网络威胁带来了安全隐患&#xff0c;近期&#xff0c;对于许多大型企业来说&#xff0c;许多企业的虚拟机服务器系统遭到了lockbit2.0/3.0勒索病毒攻击&#xff0c;导致企业所有计算机系统瘫痪&#xff0c;无法正常工作&#xff0c;严重影响了企业的正常…...

【MATLAB】 RGB和YCbCr互转

前言 在视频、图像处理领域经常会遇到不同色域图像的转换&#xff0c;比如RGB、YUV、YCbCr色域间的转换&#xff0c;这里提供一组转换公式&#xff0c;供大家参考。 色彩模型 RGB RGB色彩模型是一种用于表示数字图像的颜色空间&#xff0c;其中"RGB"代表红色&…...

【线性代数】决定张成空间的最少向量线性无关吗?

答1&#xff1a; 是的&#xff0c;张成空间的最少向量是线性无关的。 在数学中&#xff0c;张成空间&#xff08;span space&#xff09;是一个向量空间&#xff0c;它由一组向量通过线性组合&#xff08;即每个向量乘以一个标量&#xff09;生成。如果这组向量是线性无关的&…...

暴力破解(Pikachu)

基于表单的暴力破解 先随便输入一下&#xff0c;然后抓包&#xff0c;进行字典爆破 验证码绕过(on server) server服务端要输入正确的验证码后进行爆破 之后的操作没什么不一样 验证码绕过(on client) 这个也需要输入验证码&#xff0c;但是后面进行字典爆破的时候&#xf…...

如何使用CMake查看opencv封装好的函数

当我们有时想查看opencv自带的函数的源代码&#xff0c;比如函数cvCreateImage, 此时我们选中cvCreateImage, 点击鼠标右键->转到定义&#xff0c;我们会很惊讶的发现为什么只看到了cvCreateImage的一个简单声明&#xff0c;而没有源代码呢&#xff1f;这是因为openCV将很多…...

微盛·企微管家:用户运营API集成,电商无代码解决方案

连接电商平台的新纪元&#xff1a;微盛企微管家 随着电子商务的蓬勃发展&#xff0c;电商平台的高效运营已经成为企业成功的关键。在这个新纪元里&#xff0c;微盛企微管家以其创新的无代码开发连接方案&#xff0c;成为企业之间连接电商平台的强大工具。它允许企业轻松集成电…...

Hive 部署

一、介绍 Apache Hive是一个分布式、容错的数据仓库系统&#xff0c;支持大规模的分析。Hive Metastore&#xff08;HMS&#xff09;提供了一个中央元数据存储库&#xff0c;可以轻松地进行分析&#xff0c;以做出明智的数据驱动决策&#xff0c;因此它是许多数据湖架构的关键组…...

CopyOnWriteArrayList源码阅读

1、构造方法 无参构造函数 //创建一个空数组&#xff0c;赋值给array引用 public CopyOnWriteArrayList() {setArray(new Object[0]); }//仅通过getArray / setArray访问的数组。 private transient volatile Object[] array;//设置数组 final void setArray(Object[] a) {arra…...

Windows操作系统:共享文件夹,防火墙的设置

1.共享文件夹 1.1 共享文件夹的优点 1.2 共享文件夹的优缺点 1.3 实例操作 ​编辑 2.防火墙设置 2.1 8080端口设置 3.思维导图 1.共享文件夹 1.1 共享文件夹的优点 优点 协作和团队合作&#xff1a;共享文件夹使多个用户能够在同一文件夹中协作和编辑文件。这促进了团…...

STM32独立看门狗

时钟频率 40KHZ 看门狗简介 STM32F10xxx 内置两个看门狗&#xff0c;提供了更高的安全性、时间的精确性和使用的灵活性。两个看 门狗设备 ( 独立看门狗和窗口看门狗 ) 可用来检测和解决由软件错误引起的故障&#xff1b;当计数器达到给 定的超时值时&#xff0c;触发一个中…...

财务数据智能化:用AI工具高效制作财务分析PPT报告

Step1: 文章内容提取 WPS AI 直接打开文件&#xff0c;在AI对话框里输入下面指令&#xff1a; 假设你是财务总监&#xff0c;公司考虑与茅台进行业务合作、投资或收购&#xff0c;请整合下面茅台2021年和2022年的财务报告信息。整理有关茅台财务状况和潜在投资回报的信息&…...

vue3中使用three.js记录

记录一下three.js配合vitevue3的使用。 安装three.js 使用npm安装&#xff1a; npm install --save three开始使用 1.定义一个div <template><div ref"threeContainer" class"w-full h-full"></div> </template>可以给这个di…...

MySQL——表的内外连接

目录 一.内连接 二.外连接 1.左外连接 2.右外连接 一.内连接 表的连接分为内连和外连 内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选&#xff0c;我们前面学习的查询都是内连接&#xff0c;也是在开发过程中使用的最多的连接查询。 语法&#xff1a; s…...

基于IPP-FFT的线性调频Z(Chirp-Z,CZT)的C++类库封装并导出为dll(固定接口支持更新)

上一篇分析了三种不同导出C++类方法的优缺点,同时也讲了如何基于IPP库将FFT函数封装为C++类库,并导出为支持更新的dll库供他人调用。 在此基础上,结合前面的CZT的原理及代码实现,可以很容易将CZT变换也封装为C++类库并导出为dll,关于CZT的原理和实现,如有问题请参考: …...

【C语言】指针

基本概念 在C语言中&#xff0c;指针是一种非常重要的数据类型&#xff0c;它用于存储变量的内存地址。指针提供了对内存中数据的直接访问&#xff0c;使得在C语言中可以进行灵活的内存操作和数据传递。以下是关于C语言指针的一些基本概念&#xff1a; 1. 指针的声明&#xff…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...