Android IOS WebRTC 音視頻開發總結(五七)-- 網絡傳輸上的一種QoS方案


本文主要介紹一種QoS的解決方案,文章來自博客園RTC.Blacker,歡迎關注微信公眾號blacker,更多詳見www.rtc.help

 

QoS出現的背景:

而當網絡發生擁塞的時候,所有的數據流都有可能被丟棄;為滿足用戶對不同應用不同服務質量的要求,就需要網絡能根據用戶的要求分配和調度資源,對不同的數據流提供不同的服務質量:

1、對實時性強且重要的數據報文優先處理;

2、對於實時性不強的普通數據報文,提供較低的處理優先級,網絡擁塞時甚至丟棄。

 

為了滿足上述需求,QoS出現了,定義如下:

QoS(Quality of Service)指一個網絡能夠利用各種基礎技術,為指定的網絡通訊提供更好的服務能力, 是網絡的一種安全機制, 是用來解決網絡延遲和阻塞等問題的一種技術。所以當網絡過載或擁塞時,QoS 能確保重要業務量不受延遲或丟棄,同時保證網絡的高效運行。

 支持QoS功能的設備,能夠提供傳輸品質服務;針對某種類別的數據流,可以為它賦予某個級別的傳輸優先級,來標識它的相對重要性,並使用設備所提供的各種優先級轉發策略、擁塞避免等機制為這些數據流提供特殊的傳輸服務。配置了QoS的網絡環境,增加了網絡性能的可預知性,並能夠有效地分配網絡帶寬,更加合理地利用網絡資源。

 

在RTC開發中我們了解到實際網絡狀況非常復雜,如果需要保證通話必須先保證通訊質量,而實時音視頻通訊包括采集、編碼、網絡傳輸、解碼、播放等環節,其中采集、編解碼和播放是不受網絡條件影響的,只受限於編解碼算法和播放策略等因素。但網絡傳輸的丟包、抖動和亂序對qos的影響最為重大,因此下面介紹的qos解決方案要解決的是網絡傳輸丟包、抖動和亂序因素對服務質量的不好影響,具體如下:

 

1、發送端原理:

對於實時音視頻通訊,常采用UDP協議來傳輸多媒體數據,下面是采用基於udp的rtp協議來傳輸音視頻數據。對於不同格式的編碼數據,會有不同的rtp打包協議,比如對於H.264視頻數據,文檔rfc3984對NAL U的rtp打包封裝進行了規范,詳情請參考該文檔。對於視頻數據的打包封裝,因為一幀視頻數據的數據長度可能大於MTU,所以相關的打包協議都會規定將長度大於MTU的幀進行切割,分塊封裝到多個rtp包進行傳輸。為了避免丟包、抖動和亂序對服務質量的影響,本方案在發送端和接收端各建立了節點數相等的一段循環buffer,用於緩存發送端數據和接收端數據。

發送端在發送數據的時候,某個rtp包的seq為send_seq,發送端把這個包通過udp socket發送出去的同時,把這

個rtp包的數據拷貝到send_seq對應節點的buffer中去,以便這個rtp包接收方沒收到時,發送方還能重發這個rtp包。

這里要注意的一點是,發送端和接收端的循環buffer節點數要能被65536整除,這樣rtp seq增加到最大值65535時對應

最后一個節點,下一個rtp包的seq為0正好對應上第一個節點,避免rtp seq掉頭時出現漏洞。

 

2、接收端原理:

和發送端類似,接收端也開辟了一段節點數能被65536整除的循環buffer,用於緩存接收到的rtp包。接收端收到rtp

包時,需要去解析rtp包頭,取出接收到的rtp包的seq,對應下圖中的received_seq。

當收到第一個包時,start_seq和end_seq都被設置為received_seq,並把收到的rtp包送到解碼單元。后面收到rtp包時,有做兩件事情:

第一、接收的模塊將接收到的rtp包拷貝到received_seq指向的節點的buffer,並將這個節點的數據flag(用於標記該節點是否填充了數據)設置為true,同時要根據start_seq、end_seq和received_seq的關系來決定要不要將end_seq更新為received_seq的值,如果received_seq對應的包本來應該end_seq對應的包之前到達,則不更新end_seq的值,否則就更新。

第二、要每過一段時間都要去掃描start_seq到end_seq對應的每個節點,首先,若當前時間和start_seq對應的數據到達時間的差值超過一定閾值(比如500ms),則將start_seq和end_seq之間的每個節點的數據全部丟棄,將每個節點的數據flag設置為false,更新start_seq為end_seq。其次,若start_seq對應的節點的下一個節點的數據falg為true,則將該節點的數據送到解碼單元,同時將start_seq更新為該節點的seq,並將該節點的數據flag設置為false;若flag為false,且當前時間和start_seq對應的數據到達時間的差值超過一定閾值(比如50ms),則將該節點的seq(lost_seq)發送給發送端,請求發送端將seq對應的rtp數據再發一遍。

這樣,當有些包很久(大於500ms)都沒收到,就認為它來不了,直接將它們丟棄;有些包短時間(小於50ms)沒來,則向發送端發送重傳請求,請求發送端再發一次該包,試圖能補上這些包。

 

3、結果說明

3.1、沒加qos模塊時,兩個手機視頻通信在有丟包情況下回出現視頻幀不完整,播放出現馬賽克的現象,加上qos模塊后,視頻播放流暢,效果大為改善。同時我們為了測試該方案的作用,在發送端人為地分別丟棄10%和20%的視頻rtp包,接收端解碼播放效果良好,沒有出現馬賽克現象。

3.2、加入qos模塊會帶來一定的延遲和卡頓,因為丟包重傳是需要時間的。

3.3、上述方案也就是webrtc里面的nack的具體實現方式。

 

上述方案由環信資深音視頻技術專家彭祖元提供(部分內容有調整),kelly進行編輯和整理。

彭老師擁有多年音視頻編解碼開發經驗,在Android,iOS等平台音視頻采集,編碼,傳輸,解碼,播放等方面有着豐富的經驗,熟悉流媒體服務器開發。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM