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() -> 必要時創建/釋放補丁