WebRTC中丟包重傳NACK實現分析

在WebRTC中,前向糾錯(FEC)和丟包重傳(NACK)是抵抗網絡錯誤的重要手段。FEC在發送端將數據包添加冗余糾錯碼,糾錯碼連同數據包一起發送到接收端;接收端根據糾錯碼對數據進行檢查和糾正。RFC5109[1]定義FEC數據包的格式。NACK則在接收端檢測到數據丟包后,發送NACK報文到發送端;發送端根據NACK報文中的序列號,在發送緩沖區找到對應的數據包,重新發送到接收端。NACK需要發送端發送緩沖區的支持,RFC5104[2]定義NACK數據包的格式。</br>

本文在研究WebRTC源代碼的基礎上,以Video數據包的發送和接收為例,深入分析ANCK丟包重傳機制的實現。主要內容包括:SDP協商NACK,接收端丟包判定,NACK報文構造、發送、接收和解析,RTP數據包重傳。下面分別詳細論述之。</br>

1 SDP協商NACK

</br>

NACK作為RTP層反饋參數,和Video Codec聯系在一起。WebRTC在初始化階段,創建PeerConnectionFactory對象,在該對象中創建MediaEngine,其中的VideoEngine為WebRtcVideoEngine2。該對象在構造時,會收集本端支持的所有Video Codec,NACK作為Codec的屬性被一起收集。在接下來的SDP協商過程中,NACK屬性被協商到Offer/Answer中,如圖1所示。</br>

圖1 SDP協商NACK及作用于Video JitterBuffer

PeerConnection在CreateOffer時,收集本端的會話控制信息、音視頻Codec信息和網絡信息等內容。視頻Codec信息從WebRtcVideoEngine2中獲取。最后本端Offer形成SDP報文,經過PeerConnection對象發送到網絡。</br>

接收端在收到Offer之后,首先調用SetRemoteDescription,根據本地配置信息向下創建VideoReceiveStream對象,本地NACK配置信息會最終到達VCMJitterBuffer。接著PeerConnection調用CreateAnswer,生成Answer;根據Offer中的Codec信息和本端支持的Codec信息,最終選定雙方都支持的Codec集合。最后用生成的Answer作為參數調用SetLocalDescription,根據Answer中的Video Codec信息向下重新創建VideoReceiveStream對象。NACK信息向下傳遞最終到達VCMJitterBuffer,在這里設置NACK相關參數。這些參數在接收RTP數據包過程中發揮作用,比如判斷丟包、是否發送NACK報文等。Answer發回發送端時,發送端調用SetRemoteDescription執行同樣的設置流程。</br>

2 接收端丟包判定

</br>

Video接收端丟包判定在Worker線程中進行。RTP數據包到達接收端后,經過RTP模塊到達VCM模塊的JitterBuffer對象,最終調用VCMJitterBuffer的InsertPacket函數對數據包進行緩存和重排。</br>

VCMJitterBuffer把丟失RTP數據包的序列號存儲在集合missing_seq_nums中。對于本次從RTP模塊到來的數據包,標記其序列號為seq1,而上次到達數據包的序列號為seq2。如果seq1 > seq2,則表示seq1順序到達,標記(seqnum2, seqnum1)區間內的數據包為丟失狀態,將其存儲到missing_seq_nums集合中。注意這里的丟失狀態是暫時的,如果下個數據包到達時有seq1 < seq2,則表示數據包亂序到達,則把missing_seq_nums中小于seq1的序列號都刪除掉。</br>

在更新missing_seq_nums集合時,如果集合中存儲的序列號超過預設的容量,則通過調用RecycleFramesUntilKeyFrame()不斷丟包來減少集合中的序列號,直到集合中的序列號總數低于預設容量值。</br>

3 NACK報文發送和接收

</br>

接收端的NACK報文構造和發送工作在ModuleProcessThread線程中周期性完成。過程如圖2所示。</br>

圖2 NACK報文構造和發送

ModuleProcessThread線程周期性調用VideoReceiver::process函數,該函數通過VCMReceiver調用VCMJitterBuffer::GetNackList,從missing_seq_nums集合中得到過去一段時間內丟失RTP數據包的序列號。然后調用RtpStreamReceiver::ResendPackets函數。調用流程最終會到達RTCPSender::SendRTCP,發送類型為NACK的RTCP報文。</br>

NACK報文是類型為205的RTCP 擴展反饋報文,在RFC4585中定義[4]。具體格式如圖3所示:</br>

圖3 NACK報文格式

其中PT = 205,FMT = 1,Packet identifier(PID)即為丟失RTP數據包的序列號,Bitmao of Lost Packets(BLP)指示從PID開始接下來16個RTP數據包的丟失情況。一個NACK報文可以攜帶多個RTP序列號,NACK接收端對這些序列號逐個處理。</br>

NACK報文構造完成以后,發送到網絡層。NACK報文是RTCP報文的一種,因此其發送、接收和分析遵循RTCP報文處理的一般流程。這部分內容可參考文檔[3]。</br>

4 RTP數據包重傳

</br>

接收端在接收和解析NACK報文后,通過回調機制處理各種類型的RTCP報文,對于NACK報文,會調用RTPSender重新發送RTP數據包,如圖4所示:</br>

圖4 發送端數據包重傳

RTCPReceiver在解析RTCP之后,得到RTCP報文的描述結構,然后通過回調進行報文語義處理。NACK報文會被發送到RTPSender進行處理。RTPSender根據NACK報文中包含的序列號,到RTPPacketHistory緩存中查找對應的RTP數據包。如果找到,則把數據包發送到網絡。</br>

至此,一個完整的NACK報文回路完成,丟失的RTP數據包會重新發送到接收端。</br>

5 總結

</br>

本文深入分析了WebRTC內部關于丟包重傳(NACK)的實現細節,對NACK的SDP協商、丟包判定和重傳進行深入研究,為繼續學習掌握WebRTC的QoS機制奠定基礎。</br>

</br>

參考文獻

[1] RFC5109 - RTP Payload Format for Generic Forward Error Correction.</br>

[2] RFC5104 - RFC 5104 - Codec Control Messages in the RTP Audio-Visual Profile with Feedback (AVPF) </br>

[3] RFC4585 - Extended RTP Profile for Real-time Transport Control Protocol (RTCP)-Based Feedback (RTP/AVPF)

作者:weizhenwei

免責聲明:本文僅代表文章作者的個人觀點,與本站無關。其原創性、真實性以及文中陳述文字和內容未經本站證實,對本文以及其中全部或者部分內容文字的真實性、完整性和原創性本站不作任何保證或承諾,請讀者僅作參考,并自行核實相關內容。

http://www.uswqb.club/style/images/nopic.gif
分享
評論
首頁
高速公路之王电子游艺
澳洲体彩5开奖结果 意甲排行榜积分榜 大嘴棋牌官方免费下载 山西快乐十分电视开奖 五分pk10是否有漏洞 自制刮刮乐 熊猫游戏平台官方 幸运飞艇345678真的 pk10开奖规律 真人广东麻将下载 东方6 1开奖结果 二四六精选免费大全 白城吉祥棋牌老版下载 上海十一选五今日开奖 好运快3诈骗 虚拟炒股