減少延遲的設計

Android 4.1 版本為更低延遲的音頻輸出路徑引入了內部框架更改。公共客戶端 API 或 HAL API 更改最少。本文檔描述了隨著時間的推移不斷發展的初始設計。對這種設計有很好的理解應該有助於設備 OEM 和 SoC 供應商在他們的特定設備和芯片組上正確實施設計。本文不適用於應用程序開發人員。

音軌創建

客戶端可以選擇在 AudioTrack C++ 構造函數或AudioTrack::set()audio_output_flags_t參數中設置AUDIO_OUTPUT_FLAG_FAST位。目前唯一這樣做的客戶是:

AudioTrack C++ 實現審查AUDIO_OUTPUT_FLAG_FAST請求,並且可以選擇在客戶端級別拒絕該請求。如果它決定繼續傳遞請求,它會使用IAudioTrack工廠方法IAudioFlinger::createTrack()track_flags_t參數的TRACK_FAST位來傳遞請求。

AudioFlinger 音頻服務器審查TRACK_FAST請求,並且可以選擇在服務器級別拒絕該請求。它通過共享內存控制塊的位CBLK_FAST通知客戶端請求是否被接受。

影響決策的因素包括:

  • 此輸出存在快速混音器線程(見下文)
  • 跟踪採樣率
  • 存在用於執行此軌道的回調處理程序的客戶端線程
  • 跟踪緩衝區大小
  • 可用的快速通道插槽(見下文)

如果客戶的請求被接受,則稱為“快速通道”。否則,它被稱為“正常軌道”。

混合器線程

在 AudioFlinger 創建一個普通的混音器線程時,它決定是否也創建一個快速混音器線程。普通混音器和快速混音器都與特定軌道無關,而是與一組軌道相關聯。總是有一個正常的混音器線程。快速混合器線程(如果存在)從屬於普通混合器線程並在其控制下運行。

快速攪拌機

特徵

快速混音器線程提供以下功能:

  • 混合普通混音器的子混音和多達 7 個客戶端快速軌道
  • 每軌衰減

省略的功能:

  • 每軌採樣率轉換
  • 每軌效果
  • 每個混合效果

時期

快速混合器會定期運行,建議的周期為 2 到 3 毫秒 (ms),如果需要調度穩定性,則周期稍長一些,為 5 毫秒。選擇這個數字是為了考慮到完整的緩衝區流水線,總延遲大約為 10 毫秒。較小的值是可能的,但可能會導致功耗增加和出現故障的機會,具體取決於 CPU 調度的可預測性。更大的值是可能的,最多 20 毫秒,但會導致總延遲降低,因此應避免。

調度

快速混合器以提升的SCHED_FIFO優先級運行。它需要很少的 CPU 時間,但必須經常運行並且調度抖動低。抖動表示週期時間的變化:它是實際週期時間與預期週期時間之間的差異。運行太晚將導致因欠載而出現故障。由於在軌道提供數據之前從快速軌道拉出,過早運行會導致故障。

阻塞

理想情況下,除了 HAL write()之外,快速混合器線程永遠不會阻塞。快速混合器中的其他阻塞事件被認為是錯誤。特別是,避免了互斥體。相反,使用非阻塞算法(也稱為無鎖算法)。有關此主題的更多信息,請參閱避免優先級反轉

與其他組件的關係

快速混音器與客戶幾乎沒有直接互動。特別是,它看不到綁定器級別的操作,但它確實訪問了客戶端的共享內存控制塊。

快速混合器通過狀態隊列從普通混合器接收命令。

除了提取軌道數據外,與客戶端的交互是通過普通的混音器進行的。

快速混音器的主要接收器是音頻 HAL。

普通攪拌機

特徵

所有功能均已啟用:

  • 多達 32 條軌道
  • 每軌衰減
  • 每軌採樣率轉換
  • 效果處理

時期

該週期被計算為 >= 20 ms 的快速混頻器週期的第一個整數倍。

調度

普通混音器以提升的SCHED_OTHER優先級運行。

阻塞

普通的混音器被允許阻塞,並且經常在各種互斥體以及阻塞管道上這樣做以寫入其子混音。

與其他組件的關係

普通混音器與外界廣泛交互,包括綁定線程、音頻策略管理器、快速混音器線程和客戶端軌道。

普通混音器的水槽是快速混音器軌道 0 的阻塞管道。

標誌

AUDIO_OUTPUT_FLAG_FAST位是一個提示。不能保證請求會得到滿足。

AUDIO_OUTPUT_FLAG_FAST是一個客戶端級別的概念。它不會出現在服務器中。

TRACK_FAST是一個客戶端 -> 服務器的概念。