audio_port_handle_t
• 定义:audio_port_handle_t标识音频设备(如扬声器、耳机)或虚拟端口(如远程 submix)。它在设备连接或策略路由时由AudioPolicyManager分配,例如通过setDeviceConnectionState()动态注册设备。
周期
audio_port_handle_t的生命周期,其周期可分为以下几个阶段:
-
生成阶段
• 动态分配:当物理设备(如耳机、蓝牙设备)连接或虚拟设备(如远程submix)初始化时,AudioPolicyManager通过setDeviceConnectionState()动态分配唯一的audio_port_handle_t,并注册到系统可用设备列表(如mAvailableOutputDevices或mAvailableInputDevices)中。例如,USB声卡插入时会生成独立的标识符。
• 静态预定义:部分内置设备(如扬声器)的audio_port_handle_t在系统启动时通过解析audio_policy_configuration.xml预生成,无需动态注册。
-
绑定与路由阶段
• 策略路由选择:应用创建AudioTrack或AudioRecord时,AudioPolicyManager根据音频属性(如usage、contentType)从可用设备中选择目标设备,并返回其audio_port_handle_t。例如,媒体播放会选择扬声器,而通话则选择听筒。
• 动态更新:设备状态变化(如拔出耳机)会触发路由更新,系统销毁原有绑定并重新分配audio_port_handle_t到新设备(如切换到扬声器)。此过程通过SessionRouteMap维护会话与设备的关联。
-
复用与共享
• 多会话共享:同一设备的audio_port_handle_t可被多个音频会话复用。例如,多个AudioTrack输出到蓝牙设备时共享同一标识符,但各自维护独立会话ID。
• 策略优先级调整:通过setPreferredDeviceForStrategy()等API,应用可指定策略的优先设备,系统动态更新audio_port_handle_t的绑定关系。
-
销毁阶段
• 设备断开时释放:设备断开(如蓝牙关闭)或虚拟设备销毁时,AudioPolicyManager释放对应的audio_port_handle_t并清理路由。例如,USB声卡拔出后其标识符从可用设备列表中移除。
• 资源回收:若设备长时间未重新连接,系统可能回收其audio_port_handle_t以避免标识符耗尽。
关键特点
• 唯一性与动态性:每个标识符在生命周期内全局唯一,但设备重连可能重新分配不同值。
• 策略依赖性:生命周期受AudioPolicyManager路由规则控制,与硬件状态和用户配置强相关。
AudioPatch
1.核心变量
-
audio_patch 结构体:
• num_sources - 源端数量
• sources[] - 源端配置数组(可以是设备或混音端口)
• num_sinks - 接收端数量
• sinks[] - 接收端配置数组(可以是设备或混音端口)
-
AudioPatch 类成员:
• mPatch - 存储当前的音频补丁配置
• mUid - 创建该补丁的用户ID
• mHandle - 补丁的唯一标识符
• mAfHandle - AudioFlinger 分配的补丁句柄
-
线程相关变量:
• mAudioPatches - 存储所有音频补丁的集合
• mPatchSinks - 输出设备描述
• mPatchSources - 输入设备描述
2.核心函数
-
创建补丁:
• createAudioPatch() - 创建新的音频路由补丁
• sendCreateAudioPatchConfigEvent() - 发送创建补丁的配置事件
• installPatch() - 实际安装补丁到系统中
-
释放补丁:
• releaseAudioPatch() - 释放已存在的音频补丁
• sendReleaseAudioPatchConfigEvent() - 发送释放补丁的配置事件
-
管理函数:
• updateAudioProfiles() - 更新与补丁相关的音频配置
• checkForNewParameter_l() - 检查补丁参数变化
• getParameters() - 获取补丁参数
-
工具函数:
• patchSinksToString() - 将补丁接收端转换为字符串
• patchSourcesToString() - 将补丁源端转换为字符串
3.调用场景
-
设备连接/断开时:
• 当音频设备连接或断开时,系统会创建或释放相应的音频补丁
• 调用createAudioPatch()或releaseAudioPatch()
-
路由策略变化时:
• 当音频策略要求改变路由时(如通话时切换到耳机)
• 通过setParameters()触发补丁更新
-
动态策略应用时:
• 应用请求特定路由(如远程submix)时
• 使用sendCreateAudioPatchConfigEvent()通知音频系统
-
效果链管理时:
• 当音频效果需要特定设备路由时
• 通过补丁系统确保效果处理在正确的设备上
-
多设备输出时:
• 需要同时输出到多个设备(如蓝牙和有线耳机)
• 创建多接收端的补丁配置
4.关键流程
-
补丁创建流程:
应用请求 -> AudioPolicyManager -> AudioFlinger -> ThreadBase::createAudioPatch()
-> installPatch() -> HAL层实现
-
补丁释放流程:
设备断开/策略变化 -> AudioPolicyManager -> AudioFlinger -> releaseAudioPatch()
-> HAL层清理
-
参数更新流程:
参数变化 -> checkForNewParameter_l() -> 必要时创建/释放补丁