安卓audio 架构解析

发布于:2025-08-04 ⋅ 阅读:(19) ⋅ 点赞:(0)

audio_port_handle_t

• 定义:audio_port_handle_t标识音频设备(如扬声器、耳机)或虚拟端口(如远程 submix)。它在设备连接或策略路由时由AudioPolicyManager分配,例如通过setDeviceConnectionState()动态注册设备。

周期

audio_port_handle_t的生命周期,其周期可分为以下几个阶段:

  1. 生成阶段

    • 动态分配:当物理设备(如耳机、蓝牙设备)连接或虚拟设备(如远程submix)初始化时,AudioPolicyManager通过setDeviceConnectionState()动态分配唯一的audio_port_handle_t,并注册到系统可用设备列表(如mAvailableOutputDevices或mAvailableInputDevices)中。例如,USB声卡插入时会生成独立的标识符。

    • 静态预定义:部分内置设备(如扬声器)的audio_port_handle_t在系统启动时通过解析audio_policy_configuration.xml预生成,无需动态注册。

  2. 绑定与路由阶段

    • 策略路由选择:应用创建AudioTrack或AudioRecord时,AudioPolicyManager根据音频属性(如usage、contentType)从可用设备中选择目标设备,并返回其audio_port_handle_t。例如,媒体播放会选择扬声器,而通话则选择听筒。

    • 动态更新:设备状态变化(如拔出耳机)会触发路由更新,系统销毁原有绑定并重新分配audio_port_handle_t到新设备(如切换到扬声器)。此过程通过SessionRouteMap维护会话与设备的关联。

  3. 复用与共享

    • 多会话共享:同一设备的audio_port_handle_t可被多个音频会话复用。例如,多个AudioTrack输出到蓝牙设备时共享同一标识符,但各自维护独立会话ID。

    • 策略优先级调整:通过setPreferredDeviceForStrategy()等API,应用可指定策略的优先设备,系统动态更新audio_port_handle_t的绑定关系。

  4. 销毁阶段

    • 设备断开时释放:设备断开(如蓝牙关闭)或虚拟设备销毁时,AudioPolicyManager释放对应的audio_port_handle_t并清理路由。例如,USB声卡拔出后其标识符从可用设备列表中移除。

    • 资源回收:若设备长时间未重新连接,系统可能回收其audio_port_handle_t以避免标识符耗尽。

关键特点

• 唯一性与动态性:每个标识符在生命周期内全局唯一,但设备重连可能重新分配不同值。

• 策略依赖性:生命周期受AudioPolicyManager路由规则控制,与硬件状态和用户配置强相关。

AudioPatch

1.核心变量
  1. audio_patch 结构体:
    • num_sources - 源端数量

    • sources[] - 源端配置数组(可以是设备或混音端口)

    • num_sinks - 接收端数量

    • sinks[] - 接收端配置数组(可以是设备或混音端口)

  2. AudioPatch 类成员:
    • mPatch - 存储当前的音频补丁配置

    • mUid - 创建该补丁的用户ID

    • mHandle - 补丁的唯一标识符

    • mAfHandle - AudioFlinger 分配的补丁句柄

  3. 线程相关变量:
    • mAudioPatches - 存储所有音频补丁的集合

    • mPatchSinks - 输出设备描述

    • mPatchSources - 输入设备描述

2.核心函数
  1. 创建补丁:
    • createAudioPatch() - 创建新的音频路由补丁

    • sendCreateAudioPatchConfigEvent() - 发送创建补丁的配置事件

    • installPatch() - 实际安装补丁到系统中

  2. 释放补丁:
    • releaseAudioPatch() - 释放已存在的音频补丁

    • sendReleaseAudioPatchConfigEvent() - 发送释放补丁的配置事件

  3. 管理函数:
    • updateAudioProfiles() - 更新与补丁相关的音频配置

    • checkForNewParameter_l() - 检查补丁参数变化

    • getParameters() - 获取补丁参数

  4. 工具函数:
    • patchSinksToString() - 将补丁接收端转换为字符串

    • patchSourcesToString() - 将补丁源端转换为字符串

3.调用场景
  1. 设备连接/断开时:
    • 当音频设备连接或断开时,系统会创建或释放相应的音频补丁

    • 调用createAudioPatch()或releaseAudioPatch()

  2. 路由策略变化时:
    • 当音频策略要求改变路由时(如通话时切换到耳机)

    • 通过setParameters()触发补丁更新

  3. 动态策略应用时:
    • 应用请求特定路由(如远程submix)时

    • 使用sendCreateAudioPatchConfigEvent()通知音频系统

  4. 效果链管理时:
    • 当音频效果需要特定设备路由时

    • 通过补丁系统确保效果处理在正确的设备上

  5. 多设备输出时:
    • 需要同时输出到多个设备(如蓝牙和有线耳机)

    • 创建多接收端的补丁配置

4.关键流程
  1. 补丁创建流程:

    应用请求 -> AudioPolicyManager -> AudioFlinger -> ThreadBase::createAudioPatch()
    -> installPatch() -> HAL层实现

  2. 补丁释放流程:

    设备断开/策略变化 -> AudioPolicyManager -> AudioFlinger -> releaseAudioPatch()
    -> HAL层清理

  3. 参数更新流程:

    参数变化 -> checkForNewParameter_l() -> 必要时创建/释放补丁


网站公告

今日签到

点亮在社区的每一天
去签到