關鍵字:VOIP,AudioUnit,AudioQueue,RemoteIO
問題描述
VOIP通話,iOS底層音頻方式采用AudioUnit機制,本來也挺好,但是會有遇到CS域來電時RemoteIO掛死的問題
[1876:492456] 20:46:05.584 WARNING: [AVAudioSession Notify Thread] 1250: AURemoteIO::Stop: error 0x10000004 calling TerminateOwnIOThread
[1876:492846] 20:46:05.586 ERROR: [AURemoteIO::IOThread] >aurioc> 1499: AURemoteIO@0x13e225040: IOThread exiting with error 0x10004002
[1876:492456] 20:46:05.592 ERROR: [AVAudioSession Notify Thread] AVAudioSessionPortImpl.mm:52: ValidateRequiredFields: Unknown selected data source for Port iPhone 麦克风 (type: MicrophoneBuiltIn)
[1876:492456] 20:46:05.601 ERROR: [AVAudioSession Notify Thread] AVAudioSessionPortImpl.mm:52: ValidateRequiredFields: Unknown selected data source for Port iPhone 麦克风 (type: MicrophoneBuiltIn)
[1876:492456] 20:46:05.606 ERROR: [AVAudioSession Notify Thread] AVAudioSessionPortImpl.mm:52: ValidateRequiredFields: Unknown selected data source for Port iPhone 麦克风 (type: MicrophoneBuiltIn)
[1876:492456] 20:46:05.612 ERROR: [AVAudioSession Notify Thread] AVAudioSessionPortImpl.mm:52: ValidateRequiredFields: Unknown selected data source for Port iPhone 麦克风 (type: MicrophoneBuiltIn)
[1876:492456] 20:46:05.614 ERROR: [AVAudioSession Notify Thread] AVAudioSessionPortImpl.mm:52: ValidateRequiredFields: Unknown selected data source for Port iPhone 麦克风 (type: MicrophoneBuiltIn)
掛死就掛死吧,如果能強制關閉也行,問題是他一定要等25S左右,才出錯誤,在這之前,所有對音頻設備的接口調用都會被阻塞住.這就成問題了.
本來場景可以這樣做,iOS監聽到收到CS域來電,發通知,HOLD通話,底層實現是直接銷毀媒體控制對象.在CS域電話掛斷后(不掛斷,單純切回APP無效,搶不回來)
發UNHOLD動作,這時重建媒體,結果由於對媒體的動作被阻塞住,導致執行動作的底層線程被阻塞住了,媒體在信令發出后15S內沒能建立(直接掛CS電話),被對端掛了.
反復跟蹤,搜索,終於發現stackoverflow上有幾個問題和這個相關,提示是去采用AudioQueue,沒想到這里還有一個坑.
代碼集成后發現問題倒是解決了,但是音質卡頓,和之前的算法完全無法相比.
分析,發現AudioQueue上報數據有延遲.視數據緩沖區大小,20ms~1S之內,區別還挺大的.
AudioUnit上報數據的間隔基本是均勻的,20ms左右,故WebRTC底層發送時就根本不做延時.直接認為采集是均勻的就行.
而AudioUnit在上報數據大小為250ms以下時,會每隔10個包左右,延遲256ms一次,而且這延時也沒有帶來更多的數據;超過500ms以后,延遲才比較均勻,700多ms一次的延時間隔.