減少延遲時間的設計

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,通知用戶端是否接受要求。

影響這項決定的因素包括:

  • 此輸出內容是否有快速混合器執行緒 (請參閱下方說明)
  • 曲目取樣率
  • 是否有用戶端執行緒,可執行此追蹤項目的回呼處理常式
  • 追蹤緩衝區大小
  • 可用的快速通關時段 (請見下方)

如果客戶的要求已獲准,就稱為「快速通道」。否則稱為「一般軌道」。

Mixer 執行緒

AudioFlinger 在建立一般混合器執行緒時,會決定是否也要建立快速混合器執行緒。一般混合器和快速混合器都不會與特定音軌建立關聯,而是與一組音軌建立關聯。系統一律會提供一般調音盤執行緒。如果有快速調音器執行緒,則會從屬於一般調音器執行緒,並在其控制下運作。

快速混合器

功能

Fast Mixer 執行緒提供下列功能:

  • 混合一般混合器的子混合內容,以及最多 7 個用戶端快速音軌
  • 每個曲目衰減

省略的功能:

  • 依曲目轉換取樣率
  • 個別音軌效果
  • 每個混合效果

句號

快速混合器會定期執行,建議的週期為 2 到 3 毫秒 (ms),如果需要排程穩定性,則可稍微延長至 5 毫秒。我們選擇這個數字,是為了在考量完整緩衝區管道時,讓總延遲時間維持在 10 毫秒的等級。雖然可以使用較小的值,但這可能會導致耗電量增加,並且根據 CPU 調度可預測性,導致發生異常的機率提高。雖然可以使用更大的值 (最高 20 毫秒),但會導致總延遲時間降低,因此應避免使用。

時段設定

快速混合器會以較高的 SCHED_FIFO 優先順序執行。這類工作需要的 CPU 時間很少,但必須經常執行,且排程抖動率低。Jitter 是指週期時間的變化:即實際週期時間與預期週期時間之間的差異。如果執行時間太晚,則會因不足而出現異常情形。如果執行時間過早,系統會在曲目提供資料之前從快速曲目提取資料,導致出現錯誤。

會使影片被封鎖

理想情況下,除了在 HAL write() 時,快速混合器執行緒不會阻斷。在快速混合器中發生的其他封鎖事件則視為錯誤。特別是避免使用互斥鎖。而是使用非阻塞演算法 (也稱為無鎖演算法)。如要進一步瞭解這個主題,請參閱「避免優先順序反轉」。

與其他元件的關係

快速混合器與用戶端的直接互動很少。具體來說,它不會看到繫結器層級作業,但會存取用戶端的共用記憶體控制區塊。

快速混合器會透過狀態佇列接收來自一般混合器的指令。

除了擷取曲目資料,與用戶端的互動會透過一般混音器進行。

快速調節器的主要接收端是音訊 HAL。

一般混合器

功能

所有功能都已啟用:

  • 最多 32 個音軌
  • 每個音軌的衰減
  • 依曲目轉換取樣率
  • 特效處理

句號

系統會將週期計算為大於或等於 20 毫秒的快速混合器週期的首個整數倍。

時段設定

一般調音器會以較高的 SCHED_OTHER 優先順序執行。

會使影片被封鎖

一般混合器可進行封鎖,且通常會在各種互斥鎖和封鎖管道中進行,以便寫入其子混合內容。

與其他元件的關係

一般混合器會與外部世界進行廣泛的互動,包括 Binder 執行緒、音訊政策管理器、快速混合器執行緒和用戶端音軌。

一般混合器的接收端是快速混合器的曲目 0 的阻斷管道。

旗幟

AUDIO_OUTPUT_FLAG_FAST 位元是提示。我們無法保證一定會滿足要求。

AUDIO_OUTPUT_FLAG_FAST 是用於用戶端的概念。不會顯示在伺服器中。

TRACK_FAST 是用戶端 -> 伺服器概念。