https://github.com/whtang/GoRTP
GoRTP實現了修改RTP數據包的頭部和內容的一些重要的函數。而大多數只處理RTP數據包的負載和時間戳。
RTP數據分組
分組模塊實現了一個允許漏接的緩沖機制,這樣能夠減少內存的動態分配請求。盡管不是必要的但還是建議使用FreePacket()來歸還分組到分組隊列,這樣能夠減少動態內存分配和過度的垃圾回收。這對於長時間發送音視頻的應用可能有利。
傳輸模塊
GoRTP使用棧式傳輸模塊來實現。最底層使用udp,tcp或者其他網絡協議。傳輸模塊如果想要作為一個接收者預定發送者就必須實現TransportRecv和/或TransportWrite。
上層的傳輸模塊過濾接收到的數據並產生特定的輸出,比如ICE傳輸莫款能處理所有的ICE相關的數據並且將不會把ICE數據分組發送給會話模塊,因為會話模塊只期待接受RTP數據。會話模塊將丟棄所有的非RTP和非RTCP分組。
客戶端程序應根據自己的需要來構建傳輸棧。應用使用高層的傳輸模塊來初始化RTP回話,通常來說一個應用只用一個傳輸模塊。以下代碼展示了它是怎么工作的。
var localPort = 5220
var local, _ = net.ResolveIPAddr("ip", "127.0.0.1")
var remotePort = 5222
var remote, _ = net.ResolveIPAddr("ip", "127.0.0.1")
...
// 用本地地址創建一個udp傳輸並用於RTP會話
// RTP會話用傳輸層來向遠端接收和發送RTP分組
tpLocal, _ := rtp.NewTransportUDP(local, localPort)
// TransportUDP 實現了 TransportWrite and TransportRecv 接口,因此
// 使用它來作為Session的讀寫模塊
rsLocal = rtp.NewSession(tpLocal, tpLocal)
你可能注意到了,代碼中沒有使用標准的Go UDP地址,而是分開的IP和端口號。這種做法使得實現多個tcp和udp傳輸更加簡單。網絡傳輸模塊有自己的地址格式,RTP需要兩個端口,一個用來傳輸數據另一個用來管理連接。RFC3550要求偶數號端口用來發送數據,該偶數號的下一個奇數號端口用來管理連接。因此傳輸模塊只需要數據連接的端口號。
一個應用程序可能會堆疊多個傳輸模塊。要做到這樣的要求,首先先創建傳輸模塊,然后像下面這樣讓他們連接。
|
1
2
3
4
5
6
7
8
|
transportNet, _ := rtp.NewTransportUDP(local, localPort)
transportAboveNet, _ := rtp.NewTransportWhatEver(....)
// Register AboveNet as upper layer transport
transportNet.SetCallUpper(transportAboveNet)
// Register transportNet as lower layer
transportAboveNet.SetToLower(transportNet)
|
// todo
