音訊出現Xrun(underrun或overrun)的原因與解決辦法
音訊出現Xrun(underrun或overrun)的原因與解決辦法
2016年11月09日 16:14:44 Qidi_Huang 閱讀數:4614 標籤: xrununderrunoverrun原因解決方法 更多
版權宣告:本文為博主原創文章,若要轉載請註明出處。 https://blog.csdn.net/Qidi_Huang/article/details/53100493
【現象】
音訊檔案在播放時出現斷斷續續或類似“爆破”(Pop-Click)雜音的現象,稱之為 Xrun(可以是 underrun,也可以是 overrun)。
【相關例項】
《記一次Android系統下解決音訊UnderRun問題的過程》
【原因】
通常來說,出現 Xrun 問題時原因可能是以下幾個之一:
(1) Linux CFS 排程器導致。因為 CFS 排程器的“公平排程”是較長一段時間的平均表現,在很短的一個視窗時間段內,CFS 也可能會將 CPU 時間片完全分配給一個 nice 值更高的執行緒而不顧及另一個 nice 值更低的執行緒。如果這個低 nice 值的執行緒恰好是音訊相關的,就會導致 Xrun 問題。
(2) 更高優先順序的 SCHED_FIFO 執行緒排程。除了音訊執行緒以外,其它執行緒也可以使用 SCHED_FIFO 標記,如果這個其它執行緒的優先順序高於音訊執行緒,那麼它會被優先排程。這樣也會導致 Xrun 問題。
(3) 優先順序反轉。所謂的優先順序反轉是指一個更高優先順序的執行緒需要使用另一個更低優先順序執行緒所持有的資源,而不得不等待低優先順序執行緒在使用完畢後將資源釋放掉。如果音訊執行緒恰好是這個高優先順序執行緒,此時也將導致 Xrun 問題。
(4) 過長的排程延時。
(5) 頂半部中斷處理程式執行時間過長。
(6) 禁用中斷時間過長。
(7) 電源管理。核心會對晶片的工作電源進行適時地控制以免晶片溫度過高而燒燬,這些管理策略可能會暫時掛起晶片中正在進行的工作。如果音訊相關的任務因此被掛起,那麼就會出現 Xrun 問題。
(8) 核心安全策略原因。
【解決辦法】
最好的解決辦法當然是分析出 Xrun 的問題到底是上面哪個原因導致的,然後對症下藥的改動相應的程式碼以修復問題。但並不是所有人都對核心各部分了如指掌能精確定位到問題程式碼的位置(我承認至少我還沒有那個水平),所以這裡有一個類似萬金油的辦法:增加音訊資料的 buffer 大小或 buffer 數量來進行補償。但這樣也會使音訊播放/錄音的 資料準備時間變長,也就是說會增加音訊操作的延遲,算是這種方法的一個副作用。
【參考資料】
[1] 《Contributors to Audio Latency》(Google站點,需要翻牆才能閱讀)