SRT傳輸庫評估

SRT傳輸庫簡介

        SRT是Haivision開源的一套集FEC前向糾錯、ACK、NAK選擇性重傳、JitterBuff、擁塞控制、傳輸安全保障等技術於一體的實時傳輸解決方案。方案基於UDP協議進行擴展,目前SRT在廣電領域獲得了不錯的應用,因其弱網抵抗以及較好的實時性,必將取代基於TCP的RTMP僞直播方案。SRT方案使用C++開發,提供C風格接口,依賴OpenSSL\Pthreads庫,官方編譯腳本支持Windows、Linux、Mac\IOS系統,可自行參考移植到Android。

        本文對SRT封裝庫SD-SRT進行測試,該封裝庫主要針對音視頻領域需求,進行了幀碼流拆分合並、丟包凍結、自動重連、EPoll收發、狀態回調等功能的擴展,並對外提供簡潔易用的接口,可用於內網點對點或者公網CS架構,其接口說明見附錄。希望通過本測試,加深對於SRT的傳輸特徵、參數配置、適用場合的認識。

     從官方聲明可見,SRT具有以下特點:

  

                                                                           圖1  SRT ACK機制

  1. 基於ARQ(ACK+NAK),ACK機制相比TCP ACK做了一定改進,採用Full ACK和Light ACK結合的模式,其中Full ACK每10ms發送一次,對端收到ACK後會返回ACKACK信令。Light ACK則無需ACKACK,每64個包發送一次。 SRT利用Full ACK完成RTT的計算、反饋接收端的接收緩存情況等。
  2. SRT中的NAK機制可與FEC相結合,可以選擇三種模式:僅對FEC恢復失敗的情況下發起NAK重傳請求、丟包均發起NAK、丟包不發起NAK。另外SRT會在預估超時的情況下,提前結束無意義的重傳動作,在延時和碼率允許的情況下支持反覆重傳直至成功。
  3. 在1.4版本之後支持2D 異或FEC(默認關閉,需自行以Filter方式啓用)。注:經過測試,收發雙方均設置FEC成功,碼流中確實產生冗餘包,但未見顯著的丟包恢復能力,當開啓FEC時,SRT庫長時間拷機存在異常奔潰的情況。正如Nimble Streamer描述的那樣(https://blog.wmspanel.com/search/label/srt),SRT中的FEC功能正處於開發完善中,存在較大風險,用戶根據自身情況決策是否在當前版本開啓。在本次測試中,我們使用SRT的默認配置即關閉FEC功能。
  4. 發端Smooth處理和收端JitterBuff處理。
  5. 仿socket,支持雙向通訊,支持Epoll異步處理。
  6. 支持AES 128/192/256加密
  7. 內容無關,即可以傳輸音視頻也可以傳輸其他類型數據。
  8. 提供較爲詳盡的統計信息(上下行丟包率、碼率、RTT、重傳成功率等),支持帶寬估計參考(定時插入探針包,通過包間隔評估碼率)。
  9. 支持Message消息模式、文件Buff模式和Live實時模式(默認),前兩者可保證傳輸不丟包但不保證實時性,後者以實時性爲目標允許丟包。本文僅考慮Live實時模式。

     SRT基於UDP,在UDP基礎上增加16字節頭部,其包結構如下:

                                                

                                                                                  圖2  SRT包結構

 

       默認情況,SRT按MTU 1500字節進行配置,去除20字節IP頭、8字節UDP頭、16字節SRT頭後,支持負載可達到1456字節,又因其保持對TS容器的友好性,默認限定負載長度爲188*7=1316字節。(Windows平臺爲了網絡性能達到最優,建議用戶設置UDP負載小於1024,此時用戶可設置SRT最大長度不超過1024 - 16)。

 

實驗環境

 

SRT版本說明

本次測試使用SRT版本:1.4.1-152-a4ff6ab

下載地址

本評測使用到的SD-SRT庫以及DEMO下載地址:

https://github.com/waterfoxfox/SD-SRT

網絡環境說明

爲了保證測試環境一致性和可重現性,我們將在較好的網絡環境下藉助第三方弱網模擬工具Clumsy,模擬各類網絡情況。

Clumsy是一款小巧而功能強大的開源弱網模擬工具,支持windows平臺,可用於模擬:丟包(Drop)、延時(Lag)、重複(Duplicate)、亂序(Out of order)、篡改(Tamper)、抖動(Throttle)等。其項目地址:http://jagt.github.io/clumsy/cn/index.html

 

                                         

                                                           圖3  Clumsy對所有發送的包按10%進行丟包處理示意

如果要對發往指定某IP的UDP包進行丟包,可將Filtering條件設置爲:

udp and (ip.DstAddr == 192.168.31.33)

本次測試我們使用兩臺PC機器,二者接入到同一個WIFI網絡,信號強度充足,其中一臺作爲發送端並在其上執行Clumsy,另一臺作爲接收端。

 

測試DEMO說明

本次測試使用windows平臺下的桌面投屏DEMO,DEMO分爲發送端和接收端,發送端採集自身桌面和揚聲器音頻,壓縮後通過SD-SRT 點對點SDK發往接收端,後者解碼並渲染輸出,從而實現屏幕共享功能。在此場景下,DEMO接收端將充SRT服務端,DEMO發送端充當SRT客戶端。

A、接收端

該組DEMO的功能與投屏類應用類似,我們首先啓動接收端DEMO。進入UDP-AVClient-ScreenPlay文件夾,雙擊啓動AVClient.exe即可。

 

                

                                                                               圖4 接收端DEMO啓動界面

接收端啓動後,將顯示其投屏碼(IP:PORT),發送端可以使用該投屏碼進行投屏。

當發送端碼流到來時,接收端將使用一個新的窗口“Remote Video”顯示遠端畫面,如下圖所示:

 

                                                   

                                                                     圖5 接收端獨立的窗口展示遠端畫面

注意:“Remote Video”窗口是一個全屏窗口,用戶可以自行在底部任務欄切換。當遠端停止音視頻傳輸時,該窗口內容無更新。該窗口不會響應鼠標事件,只能底部切換。

接收端文件夾下的AVClient.ini文件爲其配置文件,對配置文件的修改需要重啓客戶端方能生效。配置文件包括如下幾項:

 

                                                                       

                                                                                  圖6 接收端配置文件

UseFreezeFrameWhenLost 表示當出現視頻丟包無法恢復時,爲了不展現出花屏而將畫面凍結,直至完整的關鍵幀到來再繼續送顯。該值一般設置爲1開啓。

BufferTime表示接收端Jitter buff緩存毫秒數,對應SRT的SRTO_RCVLATENCY參數。爲了抵抗網絡傳輸、丟包重傳等行爲帶來的抖動,SRT需要設置接收端緩存以保障輸出的流暢性(可以在發送端和接收端中任意一方或雙方設置,實際緩存時間取二者中的較大值),SRT的默認緩存時間爲120ms,官方建議設置爲RTT*4,最小值不低於120ms。因爲流暢性和實時性(時延)是一對矛盾的指標,Jitter buff必然將引入一定延時。在後面的測試過程中,將會對BuffTime進行調整,查看調整前後的效果對比。

 

B、發送端

發送端爲UDP-AVClient-ScreenCap目錄下的AVClient.exe,在啓動前我們需要先對其進行配置,配置文件爲AVClient.ini

 

                                                                       

                                                                               圖7 發送端配置文件

VideoBitrate表示發送端使用的視頻編碼碼率,單位kbps,設置爲2000即表示2Mbps

VideoTransWidth表示發送端使用的視頻編碼寬度,VideoTransHeight表示視頻編碼高度,ViceFrameRate表示視頻編碼幀率(本程序使用Direct桌面採集,在性能較低的機器上可能採集幀率無法達到30fps,編碼幀率仍然會按30fps配置編碼器)

EncodeQualityLevel0to7表示當採用X264軟編碼時,使用的preset級別,0表示ultrafast,1表示superfast,2表示veryfast,3表示faster,4表示fast,5表示medium,6表示slow,7表示slower。等級越高同等碼率下的圖像質量越好,但CPU佔用也越高,請根據自身機器配置而定,建議設置爲1。當使用X264軟編碼時,使用5秒一個IDR幀。當使用硬編碼時,使用3秒一個IDR幀。

HWEnable表示是否啓用硬編碼,程序支持Intel QSV硬編碼和Nvidia硬編碼,相比X264能獲得更低的CPU佔用。不過硬編碼的缺點是靈活性不足,無法支持傳輸層IDR幀請求機制。

SrtMaxBitrateFactor表示設置SRT最大碼率MAXBW爲編碼碼率VideoBitrate的幾倍,我們稱之爲峯值碼率容忍度。比如該值爲2.0,VideoBitrate爲2000時,則將設置SRT的SRTO_MAXBW爲2.0*2000 kbps(實際內部會轉換爲SRT所要求的BytePerSecond)。當設置爲0.0時,SRT將不限碼率。

SRT的 MAXBW對於傳輸性能影響較大,主要體現在兩個方面,發送端將依據MAXBW調整發送數據間隔,實現Smooth發送平滑處理。另一方面,允許的MAXBW越大,短時間內允許的重傳次數更多,越能提高弱網重傳成功率,但也會給網絡帶來更大的碼率波動壓力。實際過程中應該根據自身編碼器碼率及其波動範圍、信道帶寬來綜合權衡,設置合理的MAXBW。

啓動發送端後進入如下界面,輸入接收端展示的投屏碼(IP:PORT)即可開始SRT連接。

 

                                             

                                                                                圖8 發送端啓動界面

連接後,客戶端將進入下圖所示的待共享屏幕狀態。可以點擊主界面啓動按鈕或者使用懸浮球來啓動桌面共享。啓動後,接收端就能看到發送端的桌面並能聽到發送端揚聲器播放的音樂了。

 

                             

                                                                    圖9 發送端開始共享桌面

 

測試項說明

說明:同市面上各大實時視頻服務商一樣,DEMO也提供丟幀凍結機制,這樣用戶無法察覺到丟幀帶來的花屏,從而獲得更好的用戶體驗。因此本次測試中,丟包最終將體現爲畫面卡頓。

評測項:流暢度

關於流暢度,我們將分爲以下幾個級別:

  1. 畫面流暢
  2. 偶爾微弱卡頓(附加:卡頓時長+頻率描述)
  3. 明顯卡頓(附加:卡頓時長+頻率描述)
  4. 較長時間卡頓

評測項:延時

延時計算方式:在發送端打開毫秒精度秒錶,接收端將看到秒錶值,使用手機對二者屏幕拍照,計算二者差值得到總延時。整個系統中,延時主要有非傳輸層延時和傳輸層延時兩部分組成。非傳輸層延時包括:採集、編碼、解碼、渲染引入的延時,本DEMO實際採集幀率無法達到恆定30fps,對整體延時稍有影響。

傳輸層延時主要由接收端JitterBuff引入,後者用於消除網絡因丟包重傳、網絡本身帶來的抖動。JitterBuff越大,播發端緩存的數據越多。

需要說明的是延時指標和流暢性指標往往是一對矛盾,播發端緩存的數據越多,流暢性越好,延時也越大,反之若緩存的數據較少或者不緩存,則延時更低,但與此同時它的弱網抵抗力越差,重傳恢復成功率越低進而影響流暢性。

 

            

                                                                    圖10 SRT的Too-Late Packet Drop機制

上圖是SRT的Too-Late Packet Drop機制描述,雖然爲3號包的丟失發起了NAK請求,但發送端在收到NAK請求後判斷3號包即便發出也已經超出了其接收端的dead line,已經錯過了它的輸出時間,而放棄重傳。同樣即便3號包被重傳,接收端也會因其錯過輸出時間而直接丟棄之。

 

評測項:清晰度

DEMO圖像質量與傳輸層無緊密關係,主要由用戶指定的編碼分辨率、碼率、桌面畫面內容決定。注:幀率降低時,幀間相關性降低,運動估計殘差更大,同等碼率下編碼質量會稍弱。

 

 

測試結果

丟包測試

爲了研究接收端緩存時間、發送端峯值碼率容忍度對於丟包抵抗力的影響,我們設計以下測試(發送端編碼碼率爲2Mbps,720P分辨率,X264軟編碼,30fps,發送端全屏播放影片《美女與野獸》,畫面中等複雜度)。

A、丟包率5%,發送端峯值碼率容忍度設置爲2.0,接收端緩存時間依次設置爲200ms、300ms、400ms、500ms,觀察卡頓頻率、峯值碼率、延時三個指標。

接收緩存時間

卡頓頻率

實際峯值/平均碼率

實際延時

120ms(SRT默認值)

約20秒卡頓一次

2.7Mbps/2.1Mbps

300ms

200ms

約30秒卡頓一次

2.7Mbps/2.1Mbps

420ms

300ms

約40秒卡頓一次

2.9Mbps/2.1Mbps

530ms

400ms

約40秒卡頓一次

2.9Mbps/2.1Mbps

630ms

500ms

約40秒卡頓一次

2.9Mbps/2.1Mbps

720ms

通過本項實驗,我們發現接收端緩存時間對丟包抵抗有一定正向作用,緩存時間過短,容易在發送端放棄重傳(預判超出接收端包輸出時間)或者接收端收到後因超時而主動丟棄。當緩存時間達到要求後,繼續增大緩存時間對丟包抵抗力無明顯作用。

  1. 丟包率5%,接收端緩存時間設置爲500ms,發送端峯值碼率容忍度依次設置爲3.0、4.0、0.0(無限制),觀察卡頓頻率、峯值碼率、延時三個指標。

峯值碼率容忍度

卡頓頻率

實際峯值/平均碼率

實際延時

3.0

約220秒卡頓一次

3.2Mbps/2.2Mbps

720ms

4.0

約240秒卡頓一次

3.5Mbps/2.3Mbps

720ms

無限制(SRT默認值)

長時間無卡頓

3.6Mbps/2.3Mbps

720ms

通過本項實驗,我們確定發送端碼率峯值放得越寬,丟包抵抗力越強,這是因爲短時間內可以更高頻率的進行丟包重傳,增加了重傳次數也就提升了成功率。當我們的網絡允許較大的碼率波動時,非受限的MAXBW設置可以獲得顯著的質量提升。

  1. 接收端緩存時間設置爲500ms,發送端峯值碼率容忍度設置爲0.0(無限制),依次設置丟包率爲10%、20%、30%、50%,觀察卡頓頻率、峯值碼率三個指標。

丟包率

卡頓頻率

實際峯值/平均碼率

10%

長時間無卡頓

3.5Mbps/2.4Mbps

20%

約300秒卡頓一次

3.5Mbps/2.5Mbps

30%

約30秒卡頓一次

4.5Mbps/2.9Mbps

50%

約10秒卡頓一次

8Mbps/4Mbps

隨着丟包率的繼續上升,即便不限制碼率峯值,由於緩存時間的限制,在有限的時間內重傳仍然存在失敗的可能,導致最終丟包卡頓。此時需要增大接收緩存時間來進一步提高丟包抵抗力。

 

重複測試

發送端使用Clumsy 設置Duplicate發送重複率5%、12%、20%、30%,每次重複1包(Count設置爲2)。發送端使用峯值碼率容忍度設置爲0.0(無限制),接收端使用緩存時間120ms。

5%重複包時,連續觀察20分鐘,畫面流暢,延時穩定在300ms左右。

12%重複包時,連續觀察20分鐘,畫面流暢,延時穩定在300ms左右。

20%重複包時,連續觀察20分鐘,畫面流暢,延時穩定在300ms左右。

30%重複包時,連續觀察20分鐘,畫面流暢,延時穩定在300ms左右。

可見單純的重複包對SRT影響很小。

 

亂序測試

發送端使用Clumsy 設置Out of order發送亂序率30%。發送端使用峯值碼率容忍度設置爲0.0(無限制),接收端使用緩存時間依次爲120ms、300ms、500ms。

緩存時間

卡頓頻率

實際峯值/平均碼率

120ms

約100秒卡頓一次

3.5Mbps/2.5Mbps

300ms

約120秒卡頓一次

3.5Mbps/2.5Mbps

500ms

約155秒卡頓一次

3.5Mbps/2.5Mbps

 

可見亂序包對系統影響很大,接近丟包的影響,可能系統內部的亂序容忍窗口上限較小,很多亂序當做丟包處理(SRT會根據超時遲到包的偏離間隔來更新亂序容忍窗口)。但緩存時間增大時,對亂序的恢復能力明顯增加,這可能是亂序容忍窗口擴大以及重傳成功率提升兩方面因素導致。

 

延時測試

發送端使用Clumsy 設置Lag發送延時50、100、200、400、600ms。

經過測試,線路延時最終會疊加到總體延時之上,測試結果符合預期。

 

抖動測試

發送端峯值碼率容忍度設置爲0.0(無限制),接收端使用緩存時間爲120ms,進行如下實驗:

發送端使用Clumsy 設置Throttle分別5%、12%、20%、30%概率抖動30ms。

測試結果:5%~30%概率30ms抖動對流暢性、延時無可感知的影響。

發送端使用Clumsy 設置Throttle  30%概率抖動100ms

測試結果:小概率卡頓,延時增長到500ms,關閉抖動後延時仍爲500ms未迴歸。說明SRT根據抖動情況自動增大緩存時間,避免因緩存不足而持續卡頓。

 

極速測試

發送端峯值碼率容忍度設置爲0.0(無限制),接收端使用緩存時間爲5ms,不開啓丟包等其他弱網測試,視頻卡頓頻繁。也證實了官網的說法,即便網絡RTT非常小,也不要修改接收端緩存時間小於默認值120ms。

 

斷網測試

本DEMO基於SD-SRT庫,內部實現了自動重連機制,當物理網絡斷開或者丟包率過高導致SRT斷開後,SD-SRT將不斷嘗試重連,網絡恢復後將快速重連上並恢復業務。實際驗證網線插拔,突發丟包率達到80%以上等場景,業務均可恢復。

 

SRT中的FEC方案

SRT採用濾鏡的方式引入FEC並且默認情況下關閉了FEC功能,可通過SRTO_PACKETFILTER選項設置FEC描述字符串來啓用。描述字符串格式爲:

"fec,cols:%d,rows:%d,layout:%s,arq:%s"

其中col用於描述2D 異或FEC的列數,rows描述行數,layout描述FEC的佈局(even、staircase),arq描述FEC與NAK的結合方式。下圖是一種3行6列even佈局的FEC示意圖,圖中1~18號灰色包爲媒體包,R1~R9號橙色包爲冗餘包,它們共同組成一個FEC Group。其中1號冗餘包由1~6號媒體包異或得到,4號冗餘包由1、7、13號媒體包異或得到。以上佈局,冗餘率爲9/18=50%。

 

         

                                                                        圖11  2D FEC rows=3, cols=6

假設丟包1、2、3、4、5、6、R1、7共8個,可以由8~12 + R2恢復7號媒體包,7、13、R4恢復1號媒體包,8、14、R5恢復2號媒體包並按此規則依次恢復3、4、5、6。

假設丟包13、14、15、16、17、18、R3、R4,將無法恢復。

假設超出8個丟包,比如丟包1、2、3、4、5、6、R1、7、8,只能恢復3、4、5、6號媒體包。這種兩頭丟失、中間恢復的情況對於視頻流用途不太大,因爲視頻流往往採用丟包凍結機制,一幀中任意丟包均丟棄整幀碼流避免花屏。對於音頻包,任何包的恢復都是有利的。兩頭丟失、中間恢復對於重傳來說可以減少部分包的重傳,但相比全部重傳是否一定產生優勢比較難說。(對比2D異或FEC,若採用RS FEC 50%的冗餘(18 + 9),可以抵抗任意9個丟包)

以上爲even佈局,包的發送順序爲:1、2、3、4、5、6、R1、7、8、9、10、11、12、R2、13、R4、14、R5、15、R6、16、R7、17、R8、18、R9、R3,可見在Group的尾部形成了較爲密集的數據發送(帶寬增長了一倍),對網絡並不友好。Staircase階梯佈局正是爲了解決這一問題,通過階梯排列可以將冗餘包的發送錯開,避免集中發送帶來的碼率波動。

值得注意的是2D FEC的冗餘度是由行和列決定的,列越大抵抗連續丟包的能力越強。如果上圖改成6行3列,其最多抵抗連續5個丟包。

開啓FEC時,若發生丟包,FEC恢復處理將引入抖動,比如收到的媒體包和冗餘包:1、3、4、5、6、7、8、R1、R2、R3,其中2號媒體包的丟失需要暫停輸出,並等到R1號冗餘包到來才能恢復並輸出。對於2D異或FEC,爲消除FEC帶來的抖動,至少需要準備的延時LatencyFec爲N個包的發送時長:

N = (R + (C - 1)) + 2

其中R爲row行大小,C爲cols列大小,N個包的發送時長與碼率、幀率強相關。極端情況下假設碼率比較低,1幀視頻僅1個包,幀率30fps,N爲30時,最小需要準備的緩存時間爲1秒。

當FEC的ARQ選項配置爲ALWAYS時,即只要發現丟包即刻發起NAK重傳請求,則推薦的延時爲max(RTT*4,  LatencyFec)。當FEC的ARQ選項配置爲ONREQ時,推薦的延時爲RTT*4 + LatencyFec即二者之和,這是因爲ONREQ模式下,需要等到確認FEC失敗才發起NAK重傳,確認失敗的條件是當前FEC GROUP已經接收完成了仍舊無法恢復GROUP內丟失的包。

QOS-FEC-NACK方案的重傳機制與SRT有所不同,QOS-FEC-NACK會根據GROUP內已檢測到的丟包數目、包類型結合GROUP的冗餘包數量提前預判是否需要發起重傳,不需要等到下一個GROUP到來才發起重傳請求,這樣做的目的是儘量減少重傳等待時間進而減小延時,對於已經具備媒體包恢復條件或者媒體包未丟失的情況,FEC冗餘包的丟失不會觸發重傳,因爲它們已經沒有意義。

 

SRT與QOS-FEC-NACK方案的區別

 

SRT

QOS-FEC-NACK

機制

ARQ(ACK+NACK)+ FEC

NACK + FEC

模式

Live /File/Message

Live

主要技術

發端Smooth

JitterBuff

2D XOR FEC,固定冗餘度

FEC作爲NACK重傳參考

超時時間內反覆重傳

NACK信令冗餘防丟失

NACK主動放棄機制

帶寬估計

內部傳輸模式(內部維護socket)

OpenSSL安全

發端Smooth

JitterBuff

1D RS FEC 自適應冗餘度

FEC 視頻幀邊界形成大GROUP抗連續丟包抵抗力強

FEC作爲NACK重傳參考

僅單次重傳機會

NACK預判提前發起

NACK信令冗餘防丟失

NACK主動放棄機制

內部傳輸模式

外部傳輸模式

碼率自適應參考信息提供

推薦場景

推薦單鏈路上4*RTT延時(服務器轉發模式下總延時8*RTT)。適合實時性要求1秒左右的單向抗弱網直播或者RTT較小、帶寬不受限但需要抵抗突發丟包的內網場合。

有望成爲一些領域的標準協議。

推薦在實時性要求較高的互動場合使用,允許一定的丟包(體現爲畫面卡頓)。適合要求帶寬波動比較穩定可控的場合。

對外無依賴性、輕量級、跨平臺性能佳。

缺點

默認未開啓FEC的情況下,弱網抵抗力重點依賴ARQ機制,總體延時偏大。

FEC爲新增功能穩定性還有所欠缺,FEC未與視頻幀信息結合,同樣冗餘度的情況下抗丟包能力弱。

即便放寬延時指標,也無法保證100%的接收成功率。(FEC+單次NACK重傳,若重傳仍然丟失或者重傳超時,都將體現爲最終丟包)。

爲私有協議,收發雙方均需集成才能互通。

 

 

總結

我們測試了SRT在默認關閉FEC的場景下的弱網抵抗力,對其傳輸性能影響較大的兩個參數(接收緩存時間、最大碼率)進行了重點評估。當前SRT版本的推薦應用場景爲:實時性要求1秒左右的單向抗弱網直播或者RTT較小、帶寬不受限但需要抵抗突發丟包的內網場合。另外SRT提供的可靠傳輸文件模式和消息模式可用於改進現有TCP傳輸方案,提高弱網下的吞吐率。我們將進一步跟蹤SRT項目的進展,待其FEC功能穩定性提升後另行評估。

 

 

 

參考文獻

1、Efficient usage of SRT latency and maxbw parameters, Nimble Streamer的SRT推薦配置

https://blog.wmspanel.com/2019/06/srt-latency-maxbw-efficient-usage.html

2、SRT FEC (forward error correction) support in Nimble Streamer,Nimble Streamer的SRT FEC風險說明

https://blog.wmspanel.com/2020/04/srt-fec-forward-error-correction.html

3、SRT_Protocol_TechnicalOverview_DRAFT_2018-10-17.pdf

https://datatracker.ietf.org/meeting/107/materials/slides-107-dispatch-srt-overview-01

4、Interoperable Retransmission Protocols with Low Latency and Constrained Delay

http://kth.diva-portal.org/smash/get/diva2:1335907/FULLTEXT01.pdf

 

 

附錄

 

SD-SRT封裝庫接口

1、系統初始化接口

/***

* 環境初始化,系統只需調用一次,主要用於SRT環境以及日誌模塊的初始化

* @param: outputPath 表示日誌存放路徑,支持相對路徑和絕對路徑,若目錄不存在將自動創建

* @param: outputLevel表示日誌輸出的級別,只有等於或者高於該級別的日誌輸出到文件,取值範圍參考LOG_OUTPUT_LEVEL

* @return:

*/

void  SDSrtAvCom_Enviroment_Init(const char* outputPath, int outputLevel);

 

void  SDSrtAvCom_Enviroment_Free();

 

2、創建和刪除SD-SRT對象

/***

* 創建SrtAvCom

* @param unLogId: 日誌ID,僅用於日誌輸出時的對象標識。

* @return: 返回模塊指針,爲NULL則失敗

*/

void*  SDSrtAvCom_Create(UINT unLogId);

 

/***

* 銷燬SrtAvCom,使用者應該做好與其他API之間的互斥保護

* @param pRtp_avcom: 模塊指針

* @return:

*/

void  SDSrtAvCom_Delete(void* pRtp_avcom);

 

3、啓動

/***

* 開始工作

* @param strLocalIP: 本地IP地址,允許爲NULL,爲非NULL時將綁定到該IP(網卡)。

* @param shLocalPort: 本地通信端口(該端口用於音頻,視頻端口號將在此基礎上加1),對於客戶端模式時,允許設置本地端口號爲0,此時將由系統自動選擇可用的端口。

* @param strRemoteIP: 對方IP地址,當爲服務端模式時設置爲NULL

* @param shRemotePort: 對方收發端口(該端口用於音頻,視頻端口號將在此基礎上加1),當爲服務端模式時設置爲0

* @param pfVideoRecvCallBack: 接收到視頻數據後的對外輸出回調函數

* @param pfAudioRecvCallBack: 接收到音頻數據後的對外輸出回調函數

* @param pObject: 調用上述兩個回調函數時的附帶透傳形參,模塊內部不會解析本參數僅做透傳處理

* @return: TRUE FALSE

*/

BOOL  SDSrtAvCom_Start(

void* pRtp_avcom,

const char *strLocalIP,

USHORT shLocalPort,

const char *strRemoteIP,

USHORT shRemotePort,

CallBackFuncRecvVideoData pfVideoRecvCallBack,

CallBackFuncRecvAudioData pfAudioRecvCallBack,

void *pObject);

 

4、結束

/***

* 停止SrtAvCom工作

* @param pRtp_avcom: 模塊指針

* @return:

*/

void  SDSrtAvCom_Stop(void* pRtp_avcom);

 

5、發送視頻

/***

* 發送視頻數據

* @param pRtp_avcom: 模塊指針

* @param byBuf: 傳入一幀帶起始碼的裸碼流,內部自行拆分拼接。

* @param nLen: 數據長度

* @return:

*/

BOOL  SDSrtAvCom_SendVideoData(void* pRtp_avcom, unsigned char *byBuf, int nLen);

 

6、發送音頻

/***

* 發送音頻數據

* @param pRtp_avcom: 模塊指針

* @param byBuf: 傳入一幀音頻裸碼流,可以是ADTS,內部無拆包透傳

* @param nLen: 數據長度

* @return:

*/

BOOL  SDSrtAvCom_SendAudioData(void* pRtp_avcom, unsigned char *byBuf, int nLen);

 

7、設置通用傳輸參數

/***

* 設置基礎傳輸參數,請在Start接口之前調用

* @param pRtp_avcom: 模塊指針

* @param nRecvDelayMs: 接收緩存時間,建議4*RTT,單位ms。可在發送端或接收端設置,將取其中較大的值

* @param nMaxBitrateKbps:最大傳輸碼率,建議3*VideoEncBitrate,單位kbps。需要在發送端設置,當設置爲0時表示不受限。若碼率本身比較平穩,可設置爲2*VideoEncBitrate。

* @return:

*/

BOOL  SDSrtAvCom_SetBaseTransParams(void* pRtp_avcom, int nRecvDelayMs, int nMaxBitrateKbps);

 

8、設置視頻通道傳輸參數

/***

* 設置視頻通道FEC傳輸參數,請在Start接口之前調用

* @param pRtp_avcom: 模塊指針

* @param bEnable: 是否啓用FEC,收發雙方需保持一致

* @param nCols: FEC Group列數

* @param nRows: FEC Group行數

* @param eLayoutMode:2D FEC佈局模式

* @param eArqMode:FEC-ARQ配合模式

* @return:

*/

BOOL  SDSrtAvCom_SetVideoFecParams(void* pRtp_avcom, BOOL bEnable, int nCols, int nRows, E_SRT_FEC_LAYOUT eLayoutMode, E_SRT_FEC_ARQ eArqMode);

 

9、設置音頻通道傳輸參數

/***

* 設置音頻通道FEC傳輸參數,請在Start接口之前調用

* @param pRtp_avcom: 模塊指針

* @param bEnable: 是否啓用FEC,收發雙方需保持一致

* @param nCols: FEC Group列數

* @param nRows: FEC Group行數

* @param eLayoutMode:2D FEC佈局模式

* @param eArqMode:FEC-ARQ配合模式

* @return:

*/

BOOL  SDSrtAvCom_SetAudioFecParams(void* pRtp_avcom, BOOL bEnable, int nCols, int nRows, E_SRT_FEC_LAYOUT eLayoutMode, E_SRT_FEC_ARQ eArqMode);

 

10、獲得視頻通道統計數據

/***

* 獲取視頻通道統計信息

* @param pRtp_avcom: 模塊指針

* @param pfRttMs: RTT,單位毫秒

* @param pfUpLossRate: 上行丟包率.內部已經乘100

* @param pfDownLossRate: 下行丟包率.內部已經乘100

* @param pfEstimatedUpBitrate:上行帶寬估算.Kbps

* @param pfUpBitrate:上行碼率.Kbps

* @param pfDownBitrate:下行碼率.Kbps

* @return:

*/

BOOL  SDSrtAvCom_GetVideoTransStatis(void* pRtp_avcom, double *pfRttMs, double *pfUpLossRate, double *pfDownLossRate, double *pfEstimatedUpBitrate, double *pfUpBitrate, double *pfDownBitrate);

 

11、獲得音頻通道統計數據

/***

* 獲取音頻通道統計信息

* @param pRtp_avcom: 模塊指針

* @param pfRttMs: RTT,單位毫秒

* @param pfUpLossRate: 上行丟包率.內部已經乘100

* @param pfDownLossRate: 下行丟包率.內部已經乘100

* @param pfEstimatedUpBitrate:上行帶寬估算.Kbps

* @param pfUpBitrate:上行碼率.Kbps

* @param pfDownBitrate:下行碼率.Kbps

* @return:

*/

BOOL  SDSrtAvCom_GetAudioTransStatis(void* pRtp_avcom, double *pfRttMs, double *pfUpLossRate, double *pfDownLossRate, double *pfEstimatedUpBitrate, double *pfUpBitrate, double *pfDownBitrate);

 

 

結構體說明

//2D  FEC佈局模式

Typedef  enum  E_SRT_FEC_LAYOUT

{

//普通連續模式

e_SRT_FEC_LAYOUT_EVEN = 0,

//階梯模式,可以降低一定碼率波動(冗餘包分散發送)

e_SRT_FEC_LAYOUT_STAIR

E_SRT_FEC_LAYOUT;

 

 

//FEC-ARQ配合模式

typedef  enum  E_SRT_FEC_ARQ

{

//只要丟包均會發起NAK,不管FEC能否恢復

e_SRT_FEC_ARQ_ALWAYS = 0,

//僅在FEC失敗時發起NAK

e_SRT_FEC_ARQ_ONREQ,

//關閉NAK

e_SRT_FEC_ARQ_NEVER,

E_SRT_FEC_ARQ;

 

 

/*輸出接收到的視頻數據 回調函數

*  @param  bComplete用來表示當前幀數據是否完整(無局部丟包)

*  @param bPrevTotalFrameLost用來表示當前幀與上一次輸出幀之間無整幀丟失的情況,即本幀序號與上一幀序號是否連續。

* 通過以上兩個標誌,結合關鍵幀判定標誌,外層可以很方便的實現丟幀凍結機制

*/

typedef void (*CallBackFuncRecvVideoData)(void* pObj, int nLen, unsigned char *byBuf, unsigned int unPTS, BOOL bComplete, BOOL bPrevTotalFrameLost);

 

/*輸出接收到的視頻數據 回調函數*/

typedef void (*CallBackFuncRecvAudioData)(void* pObj, int nLen, unsigned char *byBuf, unsigned int unPTS);

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