Android Media Framework(三)OpenMAX API阅读与分析

news2024/11/29 10:58:45

这篇文章我们将聚焦Control API的功能与用法,为实现OMX Core、Component打下坚实的基础。

1、OMX_Core.h

OMX Core在OpenMAX IL架构中的位置位于IL Client与实际的OMX组件之间,OMX Core提供了两组API给IL Client使用,一组API用于管理OMX组件,另一组API用于操作/使用创建的OMX组件。

1.1

OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void);
  • OMX_Init:OMX_Init用来初始化OMX Core,在第一次使用OMX组件前它需要先被调用,并且只被调用一次;初始化可能包含以下几个步骤:
    • 分配并初始化使用OMX组件所需的内存和资源;
    • 扫描系统中的所有可用OXM组件,并将它们加载到OMX Core中;
OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void);
  • OMX_Deinit:与OMX_Init功能相反,它用作于卸载OMX_Init加载的资源;
OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum(
    OMX_OUT OMX_STRING cComponentName,
    OMX_IN  OMX_U32 nNameLength,
    OMX_IN  OMX_U32 nIndex);
  • OMX_ComponentNameEnum:用于枚举OMX Core中可用的所有组件,该API包含三个参数,第一个参数cComponentName用于返回找到的组件名称(输出参数),第二个参数是字符串的长度(输入参数),第三个参数是遍历OMX Core组件列表的索引,通过递增索引并反复调用这个函数,就可以枚举出OMX Core中所有的组件名称,该API有两个作用:
    • 当需要查看 OMX Core 中有哪些可用的组件时,可以使用这个函数来获取所有组件的名称;
    • 当需要通过名称来查找特定的组件时,可以使用这个函数来对所有组件进行遍历,直到找到与给定名称匹配的组件;
OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
    OMX_OUT OMX_HANDLETYPE* pHandle,
    OMX_IN  OMX_STRING cComponentName,
    OMX_IN  OMX_PTR pAppData,
    OMX_IN  OMX_CALLBACKTYPE* pCallBacks);
  • OMX_GetHandle:用于创建一个OMX组件,返回的句柄就是我们前面学过的OMX_COMPONENTTYPE,该函数需要传递四个参数:
    • OMX_HANDLETYPE* pHandle:这是一个二级指针void**,用于接收创建的OMX_COMPONENTTYPE指针;
    • OMX_STRING cComponentName:组件名称,根据该名称创建对应的组件;
    • OMX_PTR pAppData:调用者(Application/IL Client)的指针;
    • OMX_CALLBACKTYPE* pCallBacks:给OMX_COMPONENTTYPE注册的回调函数,用于回传消息;
OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(
    OMX_IN  OMX_HANDLETYPE hComponent);
  • OMX_FreeHandle:销毁创建的OMX组件,传入参数为OMX_HANDLETYPE hComponent
OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel(
    OMX_IN  OMX_HANDLETYPE hOutput,
    OMX_IN  OMX_U32 nPortOutput,
    OMX_IN  OMX_HANDLETYPE hInput,
    OMX_IN  OMX_U32 nPortInput);

OMX_API OMX_ERRORTYPE   OMX_GetContentPipe(
    OMX_OUT OMX_HANDLETYPE *hPipe,
    OMX_IN OMX_STRING szURI);

这两个API Android中没有用到,暂不了解。

OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole (
    OMX_IN      OMX_STRING role,
    OMX_INOUT   OMX_U32 *pNumComps,
    OMX_INOUT   OMX_U8  **compNames);
  • OMX_GetComponentsOfRole:用于获取在给定role(角色)下可以使用的所有OMX组件的列表,包含三个参数:
    • OMX_STRING role:Role是用来描述OMX组件功能的字符串,每个OMX组件都拥有一个或多个角色,需要用role去指定OMX组件执行什么任务,role的名字规律"video_decoder.avc"、“audio_encoder.aac”,第一个字段表示音频/视频,下划线后表示编码/解码,后缀表示具体的编解码类型;
    • OMX_U32 *pNumComps:输出参数,返回role对应的组件的数量;
    • OMX_U8 **compNames:输出参数,返回role对应的所有组件的名称
OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent (
    OMX_IN      OMX_STRING compName,
    OMX_INOUT   OMX_U32 *pNumRoles,
    OMX_OUT     OMX_U8 **roles);
  • OMX_GetRolesOfComponent:获取一个组件名对应的所有的Role,功能和OMX_GetComponentsOfRole类似;

根据OMX_Init和OMX_ComponentNameEnum等API中的描述,我们大致可以猜到,OMX Core中需要维护一个列表(map),列表中的内容是一组一组的Role和Component Name。

1.2

在OpenMAX IL框架设计中,IL Client不能直接访问OMX组件的函数,它需要调用OMX Core提供的宏来间接操作OMX组件。要注意的是,OMX Core没有为OMX组件的所有函数都提供宏,换言之有些OMX组件函数不是给IL Client使用的。

首先来看定义的宏:

#define OMX_SendCommand(                                    \
         hComponent,                                        \
         Cmd,                                               \
         nParam,                                            \
         pCmdData)                                          \
     ((OMX_COMPONENTTYPE*)(hComponent))->SendCommand(       \
         hComponent,                                        \
         Cmd,                                               \
         nParam,                                            \
         pCmdData)

OMX_SendCommand用于发送控制命令到组件,可用命令参考上文的枚举,该方法是非阻塞的,命令执行完成后需要发送callback通知IL Client。包含有四个参数:

  • hComponent:组件句柄;
  • Cmd:要发送的命令类型;
  • nParam:int类型的命令参数;
  • pCmdData:无法使用int表示的命令参数;
#define OMX_GetParameter(                                   \
        hComponent,                                         \
        nParamIndex,                                        \
        pComponentParameterStructure)                       \
    ((OMX_COMPONENTTYPE*)(hComponent))->GetParameter(       \
        hComponent,                                         \
        nParamIndex,                                        \
        pComponentParameterStructure)

OMX_GetParameter用于从组件获取参数设置,该方法为阻塞调用:

  • nParamIndex:参数索引,用来指定获取什么参数;
  • pComponentParameterStructure:指针,用于装载获取到的参数;
#define OMX_SetParameter(                                   \
        hComponent,                                         \
        nParamIndex,                                        \
        pComponentParameterStructure)                       \
    ((OMX_COMPONENTTYPE*)(hComponent))->SetParameter(       \
        hComponent,                                         \
        nParamIndex,                                        \
        pComponentParameterStructure)

OMX_SetParameter用于给组件设定参数,该方法为阻塞调用,参数功能与OMX_GetParameter类似。

#define OMX_GetConfig(                                      \
        hComponent,                                         \
        nConfigIndex,                                       \
        pComponentConfigStructure)                          \
    ((OMX_COMPONENTTYPE*)(hComponent))->GetConfig(          \
        hComponent,                                         \
        nConfigIndex,                                       \
        pComponentConfigStructure)

#define OMX_SetConfig(                                      \
        hComponent,                                         \
        nConfigIndex,                                       \
        pComponentConfigStructure)                          \
    ((OMX_COMPONENTTYPE*)(hComponent))->SetConfig(          \
        hComponent,                                         \
        nConfigIndex,                                       \
        pComponentConfigStructure)

OMX_GetConfig和OMX_SetConfig分别用于从组件获取配置、给组件设定配置,组件加载完成后可以
随时调用这两个方法,都是阻塞调用。不同于OMX_SetParameter设置的是组件的静态参数值,SetConfig设置的是运行时可更改的配置信息,例如视频的播放速度、音频的音量、视频的亮度等。

#define OMX_GetExtensionIndex(                              \
        hComponent,                                         \
        cParameterName,                                     \
        pIndexType)                                         \
    ((OMX_COMPONENTTYPE*)(hComponent))->GetExtensionIndex(  \
        hComponent,                                         \
        cParameterName,                                     \
        pIndexType)

OMX_GetExtensionIndex用于将OMX IL或厂商定义的扩展字符串转换为相应的结构体索引,该方法是阻塞的。许多音频和视频处理硬件具有特定的特性和特性,这些在OpenMAX IL标准中并未明确定义,为了使这些功能可以被利用,硬件厂商会提供特定的扩展;当应用程序需要访问这些特定的扩展功能时,就需要使用OMX_GetExtensionIndex来获取相关扩展的索引,然后使用这个索引去访问或者操作这些特定的扩展功能。

#define OMX_GetState(                                       \
        hComponent,                                         \
        pState)                                             \
    ((OMX_COMPONENTTYPE*)(hComponent))->GetState(           \
        hComponent,                                         \
        pState)

OMX_GetState用于获取组件的当前状态。

#define OMX_UseBuffer(                                      \
           hComponent,                                      \
           ppBufferHdr,                                     \
           nPortIndex,                                      \
           pAppPrivate,                                     \
           nSizeBytes,                                      \
           pBuffer)                                         \
    ((OMX_COMPONENTTYPE*)(hComponent))->UseBuffer(          \
           hComponent,                                      \
           ppBufferHdr,                                     \
           nPortIndex,                                      \
           pAppPrivate,                                     \
           nSizeBytes,                                      \
           pBuffer)

OMX_UseBuffer用于让组件使用由IL Client已经分配的buffer,或者使用tunneled组件已经提供的buffer。OMX_UseBuffer的实现应该分配出buffer header,并用参数填充它,最后通过ppBufferHdr返回。该方法是阻塞调用的,可以在LoadedToIdle状态下使用,也可在OMX_StateExecuting、OMX_StateIdle且端口被禁用的情况下使用。


全文阅读:Android Media Framework(三)OpenMAX API阅读与分析

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1804444.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

对Java中二维数组的深层认识

首先,在JAVA中,二维数组是一种数组的数组。它可以看作是一个矩阵,通常是由于表示二维数据节后,如表格和网格。 1.声明和初始化二维数组 声明 int[][] arr;初始化 int[][] arrnew int[3][4];或者用花括号嵌套 int[][] arr{{1,…

数据结构 -- 树状数组

前言 树状数组或二叉索引树(Binary Indexed Tree),又以其发明者命名为 Fenwick 树。其初衷是解决数据压缩里的累积频率的计算问题,现多用于高效计算数列的前缀和、区间和。它可以以 O(logn) 的时间得到任意前缀和。并同时支持在 …

Django更改超级用户密码

Django更改超级用户密码 1、打开shell 在工程文件目录下敲入: python manage.py shell再在python交互界面输入: from django.contrib.auth.models import User user User.objects.get(username root) user.set_password(123456) user.save()其中ro…

千行赏金:闲暇时间的价值创造者

在这个高速发展的信息时代,人们的生活节奏越来越快,闲暇时间似乎成为了一种奢侈品。然而,正是这些看似零散的闲暇时间,如果能够妥善利用,也能产生巨大的价值。今天,我要为大家介绍一款能够充分利用闲暇时间…

深度学习 - 梯度下降优化方法

梯度下降的基本概念 梯度下降(Gradient Descent)是一种用于优化机器学习模型参数的算法,其目的是最小化损失函数,从而提高模型的预测精度。梯度下降的核心思想是通过迭代地调整参数,沿着损失函数下降的方向前进&#…

金融领域的AI解决方案

AI可赋能金融营销、资管、风控等领域,面向金融消费者、金融机构和金融监管机构,改善金融 市场信息对称性并提升金融交易的效率和安全性。目前,金融行业各机构对于安全认证和客户身份识别的需求较为迫切,身份识别和智能客服应用和落…

深度解析:AI Prompt 提示词工程的兴起、争议与未来发展

PART1: 提示词工程的兴起 在人工智能领域中,一个新的领域——提示词工程(prompt engineering)——开始显露头角。 这个领域的核心在于精心设计输入,以引导AI模型产生特定的、期望的输出。 随着AI技术的飞速发展,特别…

值类型和引用类型在使用和存储上的区别

使用上的区别 //值类型 int a 10; //引用类型 int[] arr new int[] { 1, 2, 3, 4, 5 };//声明了一个b让其等于之前的a int b a; //声明了一个arr2让其等于之前的arr int[] arr2 arr; Console.WriteLine("a{0},b{1}", a, b); Console.WriteLine("arr[0]{0},…

【JavaEE】Spring Boot 配置文件详解

一.配置文件的相关概念. 配置文件主要用于配置应用程序的行为和属性. Spring Boot的配置文件提供了一种灵活且强大的方式,用于管理应用程序的配置信息。很多项目或框架的配置信息也放在配置文件中: 项目的启动端口.数据库的连接信息(用户名/密码/驱动等的信息).第三…

AI图书推荐:这就是ChatGPT

这本书《这就是ChatGPT》(What Is ChatGPT Doing ... and Why Does It Work )由Stephen Wolfram撰写 全书内容概要如下: **引言与预备知识** - 作者首先表达了对ChatGPT技术突破的兴奋之情,指出这不仅是技术的故事,也是…

Hadoop3:MapReduce源码解读之Map阶段的Job任务提交流程(1)

3、Job工作机制源码解读 用之前wordcount案例进行源码阅读,debug断点打在Job任务提交时 提交任务前,建立客户单连接 如下图,可以看出,只有两个客户端提供者,一个是YarnClient,一个是LocalClient。 显然&a…

ChatTTS 文字生成语言本地模型部署

ChatTTS部署 官方信息 [ChatTTS首页](https://chattts.com/)搭建步骤 1、下载源码 git clone https://github.com/2noise/ChatTTS.git 2、按照环境 pip install torch ChatTTS pip install -r requirements.txt 3、下载模型 git clone https://www.modelscope.cn/pzc163/ch…

ssm610学生社团管理系统+vue【已测试】

前言:👩‍💻 计算机行业的同仁们,大家好!作为专注于Java领域多年的开发者,我非常理解实践案例的重要性。以下是一些我认为有助于提升你们技能的资源: 👩‍💻 SpringBoot…

Hadoop3:MapReduce源码解读之Map阶段的数据输入过程整体概览(0)

一、MapReduce中数据流向 二、MapTask并行度 1、原理概览 数据块:Block是HDFS物理上把数据分成一块一块。数据块是HDFS存储数据单位。 数据切片:数据切片只是在逻辑上对输入进行分片,并不会在磁盘上将其切分成片进行存储。数据切片是MapRed…

ctfshow解题,知识点学习

1.easy_zip(misc) 1)打开环境后是一个压缩包,解压里面有个flag.txt文件需要密码, 2)直接用工具爆破,即可找到密码 2.easy_eval 1)进入题目环境,先进行代码审计 首先说是…

「小明赠书活动」第五期“网安三剑客”套系图书《内网渗透技术》《渗透测试技术》《Web应用安全》

大模型风潮已掀起,各大巨头争相入局,从ChatGPT到Sora,全球的AI应用“卷出了花”。然而,网络安全人员在享受AI技术带来的便捷之余,也不得不面对一系列新兴的安全挑战,无法忽视。 ⭐️ 赠书 - 图书简介 人…

RabbitMQ python第三方库pika应用入门实践

1. RabbitMQ简介 RabbitMQ是一个可靠、高效的开源消息代理服务器,基于AMQP协议。它具备以下特点: 可以支持多种消息协议,如AMQP、STOMP和MQTT等。提供了持久化、可靠性和灵活的路由等功能。支持消息的发布和订阅模式。具备高可用性和可扩展…

From self-attention 2 flash-attention 数学原理与 cuda 实现优化

self attension 是transformer 编码器和解码器中共同的一个计算环节,在整个transformer 网络体系中耗费的算力比例占主导。所以节省self attention 的正向和反向的计算时间,就可以加速 transormer 的训练和推理过程。 1,self attention 的数…

学习笔记——路由网络基础——环回接口(loopback)

6、环回接口(loopback) (1)定义 环回接口(loopback) :是一种虚拟的接口,是一种纯软件性质的虚拟接口,模拟一个单独的网段。 Loopback等于在设备中模拟另外不同的网络,实现不需要物理接口连接设备,依然可以模拟的功能…

MobileNetV4实战:使用 MobileNetV4实现图像分类任务(二)

文章目录 训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整策略设置混合精度,DP多卡,EMA定义训练和验证函数训练函数验证函数调用训练和验证方法 运行以及结果查看测试完整的代码 在上…