Android 4.1 版本引進了內部架構變更,以提供更低延遲的音訊輸出路徑。公開用戶端 API 或 HAL API 變更幅度不大。本文件說明初始設計,該設計隨時間持續演進。充分瞭解這項設計,有助於裝置 OEM 和 SoC 供應商在特定裝置和晶片組上正確實作這項設計。本文不適用於應用程式開發人員。
建立曲目
用戶端可以選擇在 AudioTrack C++ 建構函式或 AudioTrack::set()
的 audio_output_flags_t
參數中設定位元 AUDIO_OUTPUT_FLAG_FAST
。目前只有以下客戶會這樣做:
- 以 OpenSL ES 或 AAudio 為基礎的原生 Android 音訊
- android.media.SoundPool
- android.media.ToneGenerator
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
是用戶端 -> 伺服器概念。