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機制
- 基於ARQ(ACK+NAK),ACK機制相比TCP ACK做了一定改進,採用Full ACK和Light ACK結合的模式,其中Full ACK每10ms發送一次,對端收到ACK後會返回ACKACK信令。Light ACK則無需ACKACK,每64個包發送一次。 SRT利用Full ACK完成RTT的計算、反饋接收端的接收緩存情況等。
- SRT中的NAK機制可與FEC相結合,可以選擇三種模式:僅對FEC恢復失敗的情況下發起NAK重傳請求、丟包均發起NAK、丟包不發起NAK。另外SRT會在預估超時的情況下,提前結束無意義的重傳動作,在延時和碼率允許的情況下支持反覆重傳直至成功。
- 在1.4版本之後支持2D 異或FEC(默認關閉,需自行以Filter方式啓用)。注:經過測試,收發雙方均設置FEC成功,碼流中確實產生冗餘包,但未見顯著的丟包恢復能力,當開啓FEC時,SRT庫長時間拷機存在異常奔潰的情況。正如Nimble Streamer描述的那樣(https://blog.wmspanel.com/search/label/srt),SRT中的FEC功能正處於開發完善中,存在較大風險,用戶根據自身情況決策是否在當前版本開啓。在本次測試中,我們使用SRT的默認配置即關閉FEC功能。
- 發端Smooth處理和收端JitterBuff處理。
- 仿socket,支持雙向通訊,支持Epoll異步處理。
- 支持AES 128/192/256加密
- 內容無關,即可以傳輸音視頻也可以傳輸其他類型數據。
- 提供較爲詳盡的統計信息(上下行丟包率、碼率、RTT、重傳成功率等),支持帶寬估計參考(定時插入探針包,通過包間隔評估碼率)。
- 支持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也提供丟幀凍結機制,這樣用戶無法察覺到丟幀帶來的花屏,從而獲得更好的用戶體驗。因此本次測試中,丟包最終將體現爲畫面卡頓。
評測項:流暢度
關於流暢度,我們將分爲以下幾個級別:
- 畫面流暢
- 偶爾微弱卡頓(附加:卡頓時長+頻率描述)
- 明顯卡頓(附加:卡頓時長+頻率描述)
- 較長時間卡頓
評測項:延時
延時計算方式:在發送端打開毫秒精度秒錶,接收端將看到秒錶值,使用手機對二者屏幕拍照,計算二者差值得到總延時。整個系統中,延時主要有非傳輸層延時和傳輸層延時兩部分組成。非傳輸層延時包括:採集、編碼、解碼、渲染引入的延時,本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 |
通過本項實驗,我們發現接收端緩存時間對丟包抵抗有一定正向作用,緩存時間過短,容易在發送端放棄重傳(預判超出接收端包輸出時間)或者接收端收到後因超時而主動丟棄。當緩存時間達到要求後,繼續增大緩存時間對丟包抵抗力無明顯作用。
- 丟包率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設置可以獲得顯著的質量提升。
- 接收端緩存時間設置爲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);