解析5G時代音視頻 WebRTC音頻引擎實現分析

前言

5G時代的到來 音視頻的崛起 多少又真正瞭解音視頻的開發呢?想學習轉行?卻還在爲技術擔憂嗎?

音視頻學習大綱 

 

小編分享一篇webrtc視頻解析

音視頻開發第十八講|CC++程序員進入互聯網公司的捷徑-WebRTC開發|流媒體|音視頻開發|

更多音視頻開發、c/c++ Linux服務器高階知識、電子書籍、視頻等等可以點擊鏈接加入羣聊【linux後臺服務架構交流】 

WebRTC的音頻引擎作爲兩大基礎多媒體引擎之一,實現了音頻數據的採集、前處理、編碼、發送、接收、解碼、混音、後處理、播放等一系列處理流程。本文在深入分析WebRTC源代碼的基礎上,學習並總結其音頻引擎的實現框架和細節。

 

1. WebRTC音頻引擎整體架構

WebRTC音頻引擎的實現代碼主要分佈在如下幾個源碼目錄中:

webrtc/audio
webrtc/common_audio
webrtc/media/engine
webrtc/voice_engine
webrtc/module/audio_coding
webrtc/module/audio_conference_mixer
webrtc/module/audio_device
webrtc/module/audio_processing

WebRTC音頻引擎的整體架構如圖1所示。

解析5G時代音視頻 WebRTC音頻引擎實現分析

圖1 WebRTC音頻引擎的整體架構.png

從整個WebRTC框架結構來看,音頻引擎和和視頻引擎都位於比較底層的位置,負責音視頻數據的採集、編解碼、渲染播放等工作。音視頻引擎的上一層是多媒體引擎WebRtcMediaEngine2,是對底層音視頻引擎VideoEngine的進一步高層抽象,由WebRtcVoiceEngine對VoiceEngine進行封裝,WebRtcVideoEngine2對VideoEngine進行封裝。

在內部實現上,音頻引擎VoiceEngineImpl通過一系列對象來實現音頻處理,包括VoEAudioProcessingImpl、VoECodecImpl、VoENetworkImpl等等,每個對象負責具體某方面功能,例如VoEAudioProcessingImpl負責調用底層AudioProcessing模塊對音頻數據進行預處理。在這些功能對象中,比較重要的有VoEBaseImpl、SharedData和Channel。其中VoEBaseImpl是連接音頻設備AudioDevice和音頻引擎VoiceEngineImpl的紐帶,是音頻數據流水線上的重要一站;SharedData是一個聚合類,持有一系列重要對象;Channel則代表一路音頻數據,負責大部分對該路數據的重要操作,包括音頻數據的前處理、編解碼、發送和接收、後處理、混音等等。

從功能依賴上講,VoiceEngineImpl依賴五個重要的底層功能模塊:音頻數據採集和播放AudioDeviceModule 、音頻數據預處理AudioProcessing、音頻數據編解碼AudioCodingModule、接收端音頻數據緩衝區NetEq、接收端混音AudioConferenceMixer。此外音頻數據編解碼還依賴一系列音頻編解碼器如G711、G722、Opus等等。在發送端,音頻數據由AudioDevice採集得到,經過AudioProcessing預處理後,到達AudioCodingModule進行編碼,然後由RTPRTCP模塊發送到網絡。在接收端,音頻數據經過RTPRTCP模塊接收後到達AudioCodingModule,存儲在NetEq中進行抖動控制和錯誤消除,然後解碼。解碼後的數據經過AudioConferenceMixer進行混音,最終發送到AudioDeviceModule進行播放。

2. WebRTC音頻引擎重要數據結構

本節在第一節的基礎上,靜態分析WebRTC音頻引擎實現上的一些重要數據結構。爲了便於理解,採用從高層到底層的順序進行分析。

WebRtcMediaEngine2在MediaEngine層對底層的音視頻引擎進行封裝,分別是WebRtcVoiceEngine和WebRtcVideoEngine2。而WebRtcVoiceEngine則封裝了音頻引擎層的VoiceEngineImpl對象。VoiceEngineImpl以多繼承方式聚集一系列接口,包括SharedData、VoEAudioProcessingImpl、VoECodecImpl、VoENetworkImpl、VoEBaseImpl等等。

SharedData是一個聚合類,內部包括ChannelManager、AudioDeviceModule、OutputMixer、TransmitMixer、AudioProcess等對象,大部分關於VoiceEngineImpl的操作最終都會經過SharedData委託給內部對象。在創建SharedData對象時,其構造函數會創建一個名爲“VoiceProcessThread”的線程,該線程用以處理音頻引擎的週期性事務。

VoEBaseImpl是連接底層音頻採集播放模塊AudioDeviceModule和音頻引擎內部音頻通道Channel的重要紐帶。它實現三個接口:VoEBase負責創建Channel、啓動/停止音頻數據的發送/接收;AudioTransport負責AudioDeviceModule模塊和Channel之間數據傳送,包括採集後的音頻數據發送到Channel進行編碼、從Channel拉取解碼後的音頻數據進行播放;AudioDeviceObserver負責把AudioDeviceModule工作過程中出現的錯誤和警告向上層報告。

Channel是對一路音頻數據及其處理過程的抽象,是VoiceEngineImpl中最重要的底層實現類,其繼承並實現RtpData、RtpFeedback、FileCallback、Transport、PacketizationCallback、ACMVADCallback、MixerParticipant等多個接口,分別負責音頻數據編碼後回掉、發送到網絡、接收後存儲到NetEq緩衝區、播放前混音等一些列重要操作。在類內部, Channel包含的重要成員對象包括RtpReceiver、RtpRtcpModule、AudioCodingModule、CodecManager、OutputMixer、TransmitMixer、ProcessThread、AudioDeviceModule、VoiceEngineObserver、Transport、AudioProcessing、PacketRouter等等。

AudioDeviceModule模塊負責音頻數據的採集和播放,是音頻數據的發源地和目的地。其內部主要包含三個對象:AudioDeviceModule、AudioDeviceGeneric和AudioDeviceBuffer。AudioDeviceModule是對外接口類,負責對AudioDevice和AudioDeviceBuffer進行管理、設置和對音頻數據進行傳遞。AudioDevice是平臺相關的音頻設備,它管理音頻採集設備和播放設備,包括初始化、設置音頻採集設備和播放設備、開始/停止設備、控制設備音量、設置設備的音頻數據緩衝區,等等。在初始化階段,AudioDevice創建採集線程和播放線程,用來執行採集任務和播放任務。AudioDeviceBuffer是音頻數據緩衝區,負責臨時存儲和傳遞音頻數據。

AudioCodingModule模塊負責音頻數據的編解碼,它由音頻引擎層的Channel持有並調用。在內部,AudioCodingModul包含如下重要對象:AcmReceiver、AudioEncoder、AudioDecoder和NetEq,其中AcmReceiver負責接收音頻數據並存儲到NetEq中,NetEq負責音頻數據的抖動消除和錯誤隱藏,AudioEncoder負責音頻數據編碼,AudioDecoder負責音頻數據解碼。WebRTC支持一系列音頻編解碼器,包括CNG、G711、G722、ilbc、isac、opus等等。數據編碼完成後通過AudioPacketizationCallback接口回調到Channel進行下一步發送工作,數據解碼完成後由Channel拉取進行下一步播放工作。

Audio Processing模塊實現音頻數據的預處理操作,包括聲學回聲消除AEC、自動增益控制AGC、噪聲抑制NS、語音活動檢測VAD,等等。AudioProcessing聚合一系列子模塊實現各種音頻處理算法,其重要的對外接口由兩個:ProcessStream()和ProcessReverseStream(),前者負責採集後編碼前的音頻數據的前處理,後者播放前解碼後的音頻數據的後處理。

TransmitMixer用於發送端混音。OutputMixer用於接收端混音。OutputMixer在內部使用AudioConferenceMixer負責解碼後音頻數據的混音操作。

3. WebRTC音頻引擎數據流分析

本節在前兩節分析的基礎上,動態分析WebRTC音頻引擎的數據流,包括音頻數據的採集、前處理、編碼、發送、接收、緩存、解碼、混音、後處理、播放。如圖2所示。

解析5G時代音視頻 WebRTC音頻引擎實現分析

圖2 WebRTC音頻引擎數據流.png

3.1 音頻引擎創建及初始化

音頻引擎的創建及初始化流程如圖3所示:

解析5G時代音視頻 WebRTC音頻引擎實現分析

圖3 WebRTC音頻引擎創建及初始化.png

WebRTC音頻引擎的創建從PeerConnectionFactory對象的創建及初始化開始,這個過程由WebRTC的應用程序發起,並在signal線程在進行,最終調用CreateMediaEngine_w()轉到worker線程。在worker線程中,先創建WebRtcMediaEngine2,進而WebRtcVoiceEngine,最終創建VoiceEngineImpl。而最重要的初始化操作則VoEBaseImpl的Init()函數中完成。

3.2 音頻數據的採集和編碼

音頻數據的採集是平臺相關的,在此以Windows平臺爲例,整個採集和編碼過程如圖4所示:

解析5G時代音視頻 WebRTC音頻引擎實現分析

圖4 音頻數據的採集和編碼.png

在Windows 7平臺上,WebRTC默認使用Windows Core接口採集和播放音頻數據。採集線程叫做webrtc_core_audio_capture_thread,線程入口是AudioDeviceWindowCore的CaptureAudio函數。該函數從麥克風中採集到音頻數據後,存儲到AudioDeviceBuffer中,並調用DeliverRecordedData()把音頻數據向上推送到VoEBaseImpl對象中。VoEBaseImpl對象調用ProcessRecordedDataWithAPM()函數進行處理,首先創建AudioFrame對象並進行前處理,然後進行解複合和混音,最後數據到達Channel進行編碼和發送。

在Channel對象中,編碼任務委託給AudioCodingModule對象,首先從AudioFrame中獲取10ms的音頻數據,然後調用具體的編碼器如Opus進行編碼。編碼後的數據通過AudioPacketizationCallback接口的SendData()回到Channel對象進行下一步的RTP打包和發送過程。

3.3 音頻數據的發送

音頻數據在AudioCodingModule編碼完成後,通過回調接口回到Channel對象進行下一步的RTP打包和發送過程,如圖5所示。

解析5G時代音視頻 WebRTC音頻引擎實現分析

圖5 音頻數據的發送.png

Channel調用把數據發送給RtpRtcp模塊,後者經過一系列的調用進行RTP打包後到達RtpSender對象。如果沒有配置平滑發送線程PacedSender,則RtpSender直接調用SendPacketToNetwork()把數據發送到network線程。否則數據會先存儲到PacedSender線程中,再由後者進行平滑發送,最終數據發送到network線程。

3.4 音頻數據的接收

network線程從網絡接收到音頻數據後,交給worker線程進行下一步接收。Worker線程的工作流程如圖6所示。

解析5G時代音視頻 WebRTC音頻引擎實現分析

圖6 音頻數據的接收.png

worker線程在收到網絡數據後,通過BaseChannel的OnPacketReceived()接口向下傳遞,到達MediaEngine層的WebRtcVoiceMediaChannel,然後繼續向下經過Call和AudioReceiveStream到達Channel的ReceivedRTPPacket()接口。Channel把數據推送到RtpRtcp模塊進行RTP解包操作,得到純音頻數據,然後再經過Channel的OnReceivedPaylaodData()接口把數據推送到AudioCodingModule模塊,最終經過AcmReceiver把數據存儲在NetEq中,進行抖動消除和錯誤隱藏等操作。

3.5 音頻數據的解碼和播放

worker線程把接收到的音頻數據存儲到NetEq後,爲播放線程提供數據源。播放線程具體負責音頻數據解碼和播放操作。Windows Core接口的播放線程名稱爲webrtc_core_audio_render_thread,其工作流程如圖7所示。

解析5G時代音視頻 WebRTC音頻引擎實現分析

圖7 音頻數據的解碼和播放.png

AudioDeviceWindowsCore設備向AudioDeviceBuffer請求音頻數據,後者進一步向VoeBaseImpl請求數據,接下來主要操作都在GetPlayoutData()中進行:1)在AudioConferenceMixer中對所有活動Channel中的音頻數據進行混音,每個Channel都作爲混音的參與者。這包括獲取解碼後的音頻數據(從AudioCodingModule模塊中解碼音頻數據並返回)、對音頻數據進行混音、得到最終音頻數據並返回給OutputMixer。2)OutputMixer對混音後的音頻數據執行AudioProcessing後處理操作。3)對後處理操作後的音頻數據進行再混合和再採樣。最終OutputMixer拿到最終的音頻數據,交給VoEBaseImpl,並進一步向下交給AudioDeviceBuffer。AudioDeviceBuffer則把數據交給AudioDeviceWindowsCore進行播放操作。

至此,我們完整分析了音頻數據從採集到播放的全部過程。

4. 總結

本文在深入分析WebRTC關於音頻引擎實現代碼的基礎上,首先給出了WebRTC音頻引擎的整體框架,然後靜態分析了其實現上的若干重要對象,最後完整分析了音頻數據從採集到播放的完整流動過程。通過本文,對WebRTC有了更深入的認識和體會,爲未來進一步學習打下堅實基礎。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章