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

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

  • 引言
  • [OpenHarmony 音频概述](#OpenHarmony 音频概述)
  • [HDF 音频驱动框架概述](#HDF 音频驱动框架概述)
    • [HDF 音频驱动框架分析 ------ 音频设备驱动](#HDF 音频驱动框架分析 —— 音频设备驱动)
    • [HDF 音频驱动框架分析 ------ supportlibs 实现](#HDF 音频驱动框架分析 —— supportlibs 实现)
    • [HDF 音频驱动框架分析 ------ hdi-passthrough 实现](#HDF 音频驱动框架分析 —— hdi-passthrough 实现)
    • [HDF 音频驱动框架分析 ------ hdi-binder 实现](#HDF 音频驱动框架分析 —— hdi-binder 实现)
    • [HDF 音频驱动记载过程](#HDF 音频驱动记载过程)
    • [HDF 音频驱动播音流程](#HDF 音频驱动播音流程)
    • [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 描述可知它是向用户态和内核态发布服务,并满足按需加载。

C 复制代码
struct HdffDriverEntry g_hdiServerEntry = {
    .moduleVersion = 1,
    .moduleName = "audio_hdi_adapter_server",
    .Bind = AudioHdiServerBind,
    .Init = AudioHdiServerInit,
    .Release = AudioHdiServerRelease,
}

HDF_INIT(g_hdiServerEntry);

hcs 配置文件如下:

C 复制代码
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 驱动框架提供了驱动加载、驱动服务管理和驱动消息机制三大驱动框架能力

参考资料链接

相关推荐
LNTON羚通20 分钟前
算法定制LiteAIServer摄像机实时接入分析平台玩手机打电话检测算法:智能监控的新篇章
安全·目标检测·音视频·监控·视频监控
Stara051127 分钟前
Linux系统常用操作与命令指南
linux·vim
柯南二号32 分钟前
HarmonyOS ArkTS 下拉列表组件
前端·javascript·数据库·harmonyos·arkts
white.tie1 小时前
linux配置nginx
linux·运维·nginx
Komorebi.py1 小时前
【Linux】-学习笔记03
linux·笔记·学习
dessler1 小时前
云计算&虚拟化-kvm创建网桥(bridge)
linux·运维·云计算
YRr YRr2 小时前
Ubuntu20.04 解决一段时间后键盘卡死的问题 ubuntu
linux·数据库·ubuntu
帅比九日2 小时前
【HarmonyOS NEXT】实战——登录页面
前端·学习·华为·harmonyos
鸿蒙开天组●2 小时前
鸿蒙进阶篇-属性动画-animateTo&转场动画
华为·harmonyos
棱角~~2 小时前
10款音频剪辑工具的个人实践体验感受!!
人工智能·经验分享·其他·音视频·学习方法