HIDL 音频 HAL

本文最后更新于 2024年5月14日 晚上

在 Android 13 及更低版本中,音频 HAL 接口使用 HIDL(在扩展名为 .hal 的 HIDL HAL 文件中)和配置文件的 XSD 架构来定义,如下所示。

audio_hal

图 1. 音频 HAL 接口。

注意:如需了解详情,请参阅音频 HAL 接口定义并查看相应 HAL 版本目录的 *.hal 文件中的注释。如需了解 HIDL 的音频 HAL 目录结构,请参阅音频 HAL 自述文件

配置文件

音频政策和音频效果 XML 配置文件被视为音频 HIDL HAL 接口的一部分。这些文件必须符合其架构,并通过 VTS 测试验证其是否符合。

在实现音频 HIDL HAL 的过程中,您必须创建一个描述音频拓扑的音频政策配置文件。必须在 audio_policy_configuration.xml 文件中声明音频 HAL 功能,框架才能使用相应功能。

音频 HIDL HAL API

本部分将介绍 HIDL 的核心 API、音效和通用 HAL API。

注意:对于 Android 13,所有包含 7.0 的代码路径都将替换为 7.1。在 Android 12 中,所有包含 6.0 的代码路径均已替换为 7.0

Core HAL

Core HAL 的一些关键接口(使用 HIDL)如下所示:

  • IDeviceFactory.hal 是 API 的入口点。
  • IDevice.halIPrimaryDevice.hal 包含一些方法,例如 setMasterVolumeopenInputStream
  • 音频流是单向的,AudioFlinger 使用音频流通过 IStream.halIStreamOut.halIStreamIn.hal 向 HAL 发送音频或从 HAL 接收音频。

下表列出了有用的 Core HAL HIDL 组件的位置:

Core HAL 组件 位置
最新版本的 API /hardware/interfaces/audio/6.0
最新 Core HAL API 的专用类型 /hardware/interfaces/audio/6.0/types.hal
音频政策配置文件 XSD 架构 /hardware/interfaces/audio/6.0/config/audio_policy_configuration.xsd

Core HAL API 的默认实现 (/hardware/interfaces/audio/core/all-versions/default/) 是一个封装容器,用于封装 Treble 推出前的使用旧版共享库的 HAL 实现。在实现直接与内核驱动程序交互的新版音频 HAL 时,也可将默认实现作为参考。

Effects HAL

下表列出了使用 HIDL 的实用 Effects HAL 组件的位置:

Effects HAL 组件 位置
最新版本的 API /hardware/interfaces/audio/effect/6.0/
效果配置文件 XSD 架构 /hardware/interfaces/audio/effect/6.0/xml/audio_effects_conf.xsd

如需了解详情,请参阅 Effects HAL API 的示例实现 (/hardware/interfaces/audio/effect/all-versions/default/) 和音频效果部分。

Common HAL

使用 HIDL 的 HAL 通用 API 包含以下内容:

  • 由 Core API 和 Effect API 共享的定义 (/hardware/interfaces/audio/common/6.0/types.hal)。
  • 用于帮助实现、客户端和测试针对 HIDL API 进行编码的实用程序 (/hardware/interfaces/audio/common/all-versions)。

音频 HAL V7 更新

如本节所述,Android 12 中对音频 HAL 版本 7 做出了重大变更。音频 HAL V7 执行以下操作:

  • 统一了框架和 HAL 使用的数据模型。
  • 最大限度地减少了 HIDL 数据类型(枚举)与用于音频政策配置的 XML 架构之间的重复。

具体而言,音频 HAL V7 在以下方面做出了变更:

下面的相应部分对这些变更进行了详细介绍。

枚举

从 Audio HAL V7 开始,音频政策配置文件中使用的枚举类型仅在 XSD 架构中定义,而不在 HIDL 中定义。

在音频 HAL V6 中,types.hal 中的枚举类型(例如 AudioFormat)的值也在音频政策配置文件 XSD 架构中定义,因此造成了重复。为了避免 V7 中发生这种情况,枚举类型更改为 string,并且改为在 XSD 架构中列出所有可能的枚举值。

图 2 比较了 V7 中对 AudioFormat 枚举类型做出的一些变更:

audioformat-change

图 2. 比较对 AudioFormat 枚举做出的一些变更。

如需了解已转换为 string 的枚举类型,请参阅下面的列表:

  • AudioChannelMask
  • AudioContentType
  • AudioDevice:供应商可扩展
  • AudioFormat:供应商可扩展
  • AudioGainMode
  • AudioSource
  • AudioStreamType
  • AudioUsage

传递字符串枚举值

字符串值作为枚举值,用于跨 HAL 接口边界传输信息。框架和 HAL 封装容器都使用整数枚举值来实现业务逻辑,并采用图 3 中所示的转换方法:

audio-passing-values

图 3. 传递字符串枚举值。

注意:API 在此处使用字符串可能显得有些不寻常或效率低下。我们选择使用字符串是为了消除 HIDL 与 XSD 文件之间的枚举常量重复,并简化添加供应商扩展的操作。建议仅出于通过 HAL 接口进行传输的目的将枚举表示为字符串。不建议在业务逻辑中使用以字符串表示的枚举,因为在实现布尔逻辑运算和生成比较映射时会产生关联的开销。

例如,将一个音频格式类型值从框架传递给供应商的过程如下:

  1. AudioFormat 的枚举值被转换为 libaudiohal 中的字符串值,并被传递给 HAL。
  2. 在 HAL 端,默认封装容器将字符串转换为枚举值,该值会被传递给旧版 HAL。

注意:供应商可以修改 system/audio.h 以使用自己的枚举值。

XML 架构的变更

XML 架构定义 (XSD) 中包含枚举值的完整列表,这使 VTS 可以更好地验证音频政策配置 XML 文件。为了符合 XSD 的相关要求,我们对用于 HAL V7 的音频政策配置文件做出了一些变更。

V7 使用标准的 (空格)字符来分隔属性(例如采样率、声道掩码和标志)中的值列表,而不是使用 V6 及更低版本中所用的 ,(英文逗号)和 |(竖线)符号。正如下例中所示,使用空格来分隔 channelMasks 的值列表:

1
<profile channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO" … />

如需更改符号,请使用名为 update_audio_policy_config.sh 的自动转换脚本。如需为 Pixel 5 (Redfin) 设备将 V6 音频政策配置文件转换为 V7 版本,请参阅以下命令:

1
2
hardware/interfaces/audio/7.0/config/update_audio_policy_config.sh \
device/google/redfin/audio/audio_policy_configuration.xml 6.0

数据类型

我们在 V7 中重新定义了一些数据结构,以最大限度地减少重复定义。重复的数据项元组被组合在一起,形成了可重复使用的结构。这些数据结构使用安全联合体等最新 HIDL 功能。

例如,在 V6 及更低版本中,HIDL 接口和类型中经常使用三元组 <format, sampling rate, channel mask>。为了消除这种冗余,V7 中按如下方式定义 AudioConfigBase 数据类型和其他数据类型:

  • AudioConfigBase := <format, sampling rate, channel mask>

  • AudioConfigBaseOptional := <[fmt], [sampl. rate], [chan. mask]>

    AudioConfigAudioOffloadInfoAudioPortConfig 使用

  • AudioProfile := <format, {sampling rates}, {channel masks}>

    替换 AudioPort/PortConfig 中的未绑定集合

  • AudioPortExtendedInfo := device | mix | session

    替换 AudioPort/PortConfig 中的联合体

供应商标记

除了设备类型和格式之外,供应商还可以为音轨元数据添加自定义标记。

对于播放和录制曲目元数据,供应商可以传递自己的标记,用于向应用到 HAL 的音频 I/O 流添加属性。

注意:供应商标记类似于音频格式和音频设备类型的供应商扩展。不同之处在于,AOSP 中未定义供应商标记的值,因此供应商标记仅包含供应商扩展的值。

添加播放曲目元数据的供应商标记,如以下示例所示:

1
2
3
4
5
struct PlaybackTrackMetadata {

/** Tags from AudioTrack audio attributes */
vec<AudioTag> tags;
};

RecordTrackMetadata 结构的实现方式类似,通过添加录制曲目元数据专用的标记来实现。

供应商扩展命名空间

从 HAL V7 开始,供应商扩展需要额外添加 V6 中不需要使用的 {vendor} 前缀。{vendor} 前缀必须至少包含三个字母数字字符才有效。

请在 V7 中使用以下格式:

1
VX_{vendor}_{letters/numbers}

以下是有效的 V7 供应商扩展的一些示例:

  • VX_**GOOGLE**_VR
  • VX_**QCI**_AMBIENT_MIC

版本信息

下表列出了每个 Android 版本的 HAL 版本号:

Android 版本 HIDL HAL 版本
Android 13 7.1
Android 12 7.0
Android 11 6.0
Android 10 5.0
Android 9 4.0
Android 8 2.0

HIDL 音频 HAL
https://www.shangyexin.com/2024/09/02/audio-hidl-implement/
作者
Yasin
发布于
2024年9月2日
许可协议