OpenHarmony 标准系统 HDF 框架音视频驱动开发

news2024/9/29 9:38:54

OpenHarmony 标准系统 HDF 框架音视频驱动开发

  • 引言
  • OpenHarmony 音频概述
  • HDF 音频驱动框架概述
    • HDF 音频驱动框架分析 —— 音频设备驱动
    • HDF 音频驱动框架分析 —— supportlibs 实现
    • HDF 音频驱动框架分析 —— hdi-passthrough 实现
    • HDF 音频驱动框架分析 —— hdi-binder 实现
    • HDF 音频驱动记载过程
    • HDF 音频驱动播音流程
    • HDF 音频驱动录音流程
  • HDF 音频驱动实现总结
  • 参考资料链接

引言

OpenHarmony 操作系统为了做到给千行百业提供全场景业务能力,达到设备快速互联、硬件互助、资源共享;统一 OS、一次开发多端弹性部署的目标。在此背景下 OpenHarmony 提出在传统的单设备系统能力基础上,基于同一套系统能力、适配多种终端形态的分布式理念,并且内核层、系统服务层、框架层和应用层做了全新的设计和开发。内核层作为 OpenHarmony 最底层设计,包括支持多内核以及全新硬件驱动框架(HDF)。同时随着手机被发明应用到如今的智能语音等等,音频应用的形态和场景也是越来越丰富。在这两大背景下,音频需要支撑从轻设备到富设备应用需求,所以 OpenHarmony 下基于 HDF 驱动框架的音频驱动实现存在多种方式:

  • 轻设备直接驱动
  • 富设备用户态驱动
  • 富设备内核态驱动

OpenHarmony 音频概述

根据 OpenHarmony 系统的自下而上的层次结构划分:内核层、系统服务层、框架层和应用层。下面简要概述为实现 OpenHarmony 音频功能,各个层次做了哪些工作:

  • 内核层包含两方面,内核子系统和驱动子系统。这层主要以 HDF 驱动框架为基础实现音频 codec 驱动,audio HDI 接口的封装。由于产品形态和解决方案的多样化,音频 codec 的驱动方式也分用户态驱动方式和内核态驱动方式来实现。音频 codec 驱动工作后需要对硬件资源进行统一抽象封装,对上层暴露统一的音频接口,这样做的目的就是符合音频规范化操作,保证生态良性发展
  • 系统服务层主要通过 pulseaudio 框架对 audio HDI 的调用来获取音频驱动能力。之后基于 pulseaudio 框架实现 audiosystemmanager 和 audioserviceclient,前者对音频服务进行管理、对音频流进行管理。最后 napi 实现,并且 sa_main 会根据 sa_profile 会将音频 SA(system ability)拉起
  • 框架层的 ability 框架和 ui 框架等就会根据系统层提供的音频能力进行相应的调用,实现应用 FA(feature ability)和 PA(particle ability)
  • 应用层则是根据应用需求和场景调用相应的 FA 和 PA 进行打包生成 .hap 应用包

在这里插入图片描述

HDF 音频驱动框架概述

HDF 音频驱动框架的实现需要考虑符合 HDI-adapter 规范,保证生态良性演进。所以 HDF 音频驱动框架和 OpenHarmony 一样,实现过程也是遵循分层设计的。通过如下步骤完成 HDF 音频驱动框架的实现:

  • 设备驱动的实现:设备驱动实现方式主要有用户态驱动和内核态驱动。用户态有通过 libusb 走私有协议完成驱动的;内核态有注册 HDF 服务驱动的,也有按照标准 alsa 框架的。以上不管是哪种方式,都是对 audio codec 的硬件配置,使能相应功能
  • supportlibs:不同的设备驱动实现方式,用户态访问控制方式也会相应不一样。为了屏蔽访问控制的差异,在用户态实现一套统一的访问接口的接口集合,包括设备能力、启停控制、fifo 读写、音频属性设置获取等
  • hdi_passthough:对 supportlibs 二次封装,将 audio codec 的能力接口集合抽象 adapter 并通过 adapter manager 进行管理,满足 HDI-adapter 的规范性,保证产品生态良性演进
  • hdi-binder:首先实现 hdi_adapter_server 获取 adapter manager 并注册 HDF 服务,然后实现一个对应的 service porxy 对这个服务通过 binder 机制访问,最后传递给系统服务层 dlopen 的方式动态加载

在这里插入图片描述

HDF 音频驱动框架分析 —— 音频设备驱动

了解了 HDF 音频驱动的基本框架和实现技术路线后,下面遵循自下而上的分层设计 supportlibs、hdi_passthrough、hdi_binder 的实现逐一分析讲解对于设备驱动而言,这里大概描述 hi3516 和 rk3568 两个平台内核态实现的技术方式,

  • HI3516 内核态注册多个 HDF driver,具体在 drivers/framework/model/audio/ 下会将 HI3516 的音频模型化和平台化,在 drivers/peripheral/audio/chipsets/ 会基于前面平台化驱动实现音频 codec 配置, DAI 驱动等。两部分实现内核态 HDF server 组成 HI3516 内核态完整音频设备驱动
  • RK3568 的内核态驱动实现是完全遵循标准 Linux 的 alsa 框架,音频设备的驱动实现包含 codec 驱动、DAI 驱动、DMAMACHINE 驱动。一般的开发都是 codec 驱动的移植,剩下的 DAI 驱动和 DMAMACHINE 驱动都是验证性开发。

HDF 音频驱动框架分析 —— supportlibs 实现

前面 HDF 音频驱动框架概述有描述,supportlib 为了屏蔽声卡访问控制的差异,在用户态实现一套符合 hdi-adapter 规范的访问控制,如下图所示:

在这里插入图片描述

开发者根据对应音频设备的驱动能力和实现方式完成对应接口。比如 HI3516 平台通过调研 IO service 完成接口集合声明的 api,RK3568 是调研 tinyalsa 完成接口结合声明的 api

HDF 音频驱动框架分析 —— hdi-passthrough 实现

根据面向对象的编程思想,hdi-passthrough 层的实现思路是将声卡(片内声卡、usb 声卡、HDMI 声卡等)抽象成 adapter,每个 adapter 都包含 supportlibs 抽象的 audioRender 和 audiocapture,最后通过 audiomanager 管理 adapters。此实现方式进一步将音频 HDI 接口规范化封装。如下图所示:

在这里插入图片描述

HDF 音频驱动框架分析 —— hdi-binder 实现

hdi-binder 是处于 HDF 音频驱动框架最上层的封装,这一层分为 server 实现和 proxy 实现。server 实现是将声卡管理、声卡录播控制以 HDF ioservice 的方式绑定到 modulename 为 audio_hdi_adapter_server 的 HDF 驱动服务。根据这个驱动服务的 hcs 描述可知它是向用户态和内核态发布服务,并满足按需加载。

struct HdffDriverEntry g_hdiServerEntry = {
    .moduleVersion = 1,
    .moduleName = "audio_hdi_adapter_server",
    .Bind = AudioHdiServerBind,
    .Init = AudioHdiServerInit,
    .Release = AudioHdiServerRelease,
}

HDF_INIT(g_hdiServerEntry);

hcs 配置文件如下:

device0 :: deviceNode {
    policy = 2;
    priority = 100;
    moduleName = "libaudio_hdi_adapter_server.z.so";
    serviceName = "audio_hdi_service";
}

Note:proxy 通过 serviceName 获取的该服务。proxy 的山西爱你首先是获取 server 实现时注册的 audio_hdi_service ,然后通过 ipc 机制获取声卡管理和声卡能力接口集后遵循 hdi-adapter 的规范对声卡进行系统框架层的应用。总结 hdi-binder 的 server 和 proxy 的相互调用实现,可以参考下图所示:

在这里插入图片描述

HDF 音频驱动记载过程

前面完整分析了 OpenHarmony HDF 音频驱动框架的分层实现,以及每个层次的组件如何依赖组合关系。至此虽然大概知道 HDF 音频驱动框架的实现,但是 hdi-binder 下实现的 audio_hdi_service 何时被拉起,整个过程简单分析:

  • 系统在开机的时候 init 进程会拉起 hdf_devmgr,hdf_devmgr 会对 HDF 服务进行管理
  • HdfDriverEntry 被实现时通过 HDF_INIT 放在一个特定的 section
  • 当 proxy 被调用时,会调用 HDIServiceManager 类的 GetService(serviceName) 方法
  • 匹配成功后就会执行 HdfDriverEntry 对应的 bind 和 init ,这时整个驱动服务被注册拉起成功

HDF 音频驱动播音流程

在这里插入图片描述
在这里插入图片描述

HDF 音频驱动录音流程

在这里插入图片描述
在这里插入图片描述

HDF 音频驱动实现总结

  • HDF 音频驱动开发包含设备驱动开发,HDI 的实现封装
  • HDF 音频驱动框架实现必须遵循当前的层次划分和 hdi-adapter 规范,方便演进和去差异化
  • HDF 音频驱动框架的处理对象是 PCM,不能进行其他复杂音频业务,比如 AI 和音频分析
  • HDF 音频驱动往系统服务层暴露的只有一个 HDF 服务,这个服务是动态按需拉取和注销的
  • HDF 驱动框架提供了驱动加载、驱动服务管理和驱动消息机制三大驱动框架能力

参考资料链接

  • OpenHarmony官方 doc 文档:https://gitee.com/openharmony/docs#/openharmony/docs/blob/master/zh-cn/readme.md

  • OpenHarmony官网:https://www.openharmony.cn/mainPlay

  • 课程链接:https://growing.openharmony.cn/mainPlay/learnPathMaps?id=49

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

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

相关文章

从零开始计算机网络——计算机网络课程的了解初步认识计算机网络

目录 🍘计算机网络学科到底学什么? 🧇两个参考模型的介绍 🥪OSI参考模型&TPC参考模型&五层参考模型 🍱 计算机网络学科的重难点——网络协议 🥘如何学好计算机网络课程? 🍣相…

Java使用BigDecimal(公式精确计算)+(精度丢失问题)

一、Java使用BigDecimal公式计算(精确计算) 介绍: 使用BigDecimal加减乘除方法运算,可以使用BigDecimal类提供的add、subtract、multiply、divide方法函数实现。 公式加法计算~add public static void main(String[] args){BigDecimal a BigDecimal.valueOf(5.6);…

动态规划合集

62 斐波那契数列 public class Solution {public int Fibonacci(int n) { return f(n);}public int f(int n){if(n1||n2){return 1;}return f(n-1)f(n-2);} }这种做法时间复杂度O(2^N),空间复杂度是用递归栈,O(n) 改进:用动态规划,可以…

Pytorch优化器全总结(三)牛顿法、BFGS、L-BFGS 含代码

目录 写在前面 一、牛顿法 1.看图理解牛顿法 2.公式推导-三角函数 3.公式推导-二阶泰勒展开 二、BFGS公式推导 三、L-BFGS 四、算法迭代过程 五、代码实现 1.torch.optim.LBFGS说明 2.使用LBFGS优化模型 优化器系列文章列表 Pytorch优化器全总结(一&…

C 程序设计教程(09)—— 数据输出函数(printf)用法详解

C 程序设计教程(09)—— 数据输出函数(printf)用法详解 该专栏主要介绍 C 语言的基本语法,作为《程序设计语言》课程的课件与参考资料,用于《程序设计语言》课程的教学,供入门级用户阅读。 目录…

Python小案例

1、简单的打印输出 age =18 print("我的名字是%s,我的国籍是%s"%("小张","中国")) print("我的年纪是:%d岁"%age) print("www","baidu","com",sep=".") #sep是使用.分割的意思,这个输出是百…

微信小程序开发——小程序的宿主环境API,协同工作和发布

一.小程序API概述 小程序中的 API 是由宿主环境提供的,通过这些丰富的小程序 API ,开发者可以方便的调用微信提供的能力,例如:获取用户信息、本地存储、支付功能等。 二.小程序API的3大分类 a.事件监听AP1 特点:以…

【服务器数据恢复】服务器硬盘掉线的数据库数据恢复案例

服务器数据恢复环境&故障: 某公司服务器,配备24块FC硬盘,两块硬盘出现故障掉线,导致服务器上层的卷无法挂载。 服务器数据恢复过程: 1、查看服务器硬盘状态发现有两块硬盘离线,将服务器内的所有硬盘做好…

【数据结构-JAVA】栈(Stack)和队列(Queue)

栈1.1 栈的概念栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶,另一端称为栈底。栈中的数据元素遵守先进后出,后进先出的原则(LIFO——Last In First Out&a…

【从零开始学习深度学习】41. 算法优化之RMSProp算法【基于AdaGrad算法的改进】介绍及其Pytorch实现

上一篇文章AdaGrad算法中提到,因为调整学习率时分母上的变量st\boldsymbol{s}_tst​一直在累加按元素平方的小批量随机梯度,所以目标函数自变量每个元素的学习率在迭代过程中一直在降低(或不变)。因此,当学习率在迭代早…

LeetCode 45. 跳跃游戏 II

45. 跳跃游戏 II - 力扣(LeetCode) 解法1:(动态规划 贪心) 果然代码越短,思路越难。这题用的是动态规划贪心的思想。首先分析题意我们可以知道,从索引0这个点开始,我们走一步可以…

redis命令第二弹

1、redis命令-hash类型练习2、redis命令-list类型练习3、redis命令-set类型练习

YOLOV5环境搭建以及训练COCO128数据集

前言记录了自己训练coco128的全过程手把手教你YOLOV5环境搭建以及训练COCO128数据集。相关配置文件在百度网盘中。如果懒得话可以直接全部用我的数据一、准备工作1.1创建环境打开anaconda power shell(最好以管理员身份运行,免得到后面相关文件权限进不去…

sentinel-介绍(一)

Sentinel Website(Sentinel 官网网站) Sentinel: 分布式系统的流量防卫兵 Sentinel 是什么? 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、流量路由、熔断降级、系…

ansible配置yum源仓库

1.挂载本地光盘到/mnt 2.配置yum源仓库文件通过多种方式实现 仓库1 : Name: RH294_Base Description: RH294 base software Base urt: file:///mnt/BaseOS 不需要验证钦件包 GPG 签名 启用此软件仓库 仓库 2: Name: RH294_S…

LeetCode刷题模版:41 - 50

目录 简介41. 缺失的第一个正数42. 接雨水43. 字符串相乘44. 通配符匹配45. 跳跃游戏 II46. 全排列47. 全排列 II48. 旋转图像49. 字母异位词分组50. Pow(x, n)结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标…

axios系列之取消请求

文章の目录写在最后使用 cancel token 取消请求 Axios 的 cancel token API 基于cancelable promises proposal,它还处于第一阶段。 可以使用 CancelToken.source 工厂方法创建 cancel token,像这样: const CancelToken axios.CancelToken;…

Revit二次开发小技巧(十七)实时监控模型线的生成

前言:项目中需要一个需求,用户想调用出Revit中自带的绘制模型线方法,然后再绘制结束时,可以拿到绘制的模型线,然后实现后面的算法。这里记录一种方法,通过DocumentChange事件修改Tag的PropertyChanged事件来…

【Python】pandas获取全省人口数据并作可视化分析

前言 今天我们看看自己所在的省份的人口人数,使用pandas并作可视化分析。 环境使用 python 3.9pycharm 模块使用 pandasPandas 是基于NumPy的一种工具,该工具是为解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供…

java和vue募捐网水滴筹项目捐款爱心系统筹款系统

简介 募捐网,注册用户实名认证通过后可以发布募捐,管理员审核募捐通过后,前台用户可以看到该募捐信息,进行募捐或者举报(管理审核举报成功后,会拉黑该募捐发起人),前台展示公告、爱…