首页 > 代码库 > Go实现的RTP栈——GoRTP介绍

Go实现的RTP栈——GoRTP介绍

https://github.com/whtang/GoRTP

GoRTP实现了修改RTP数据包的头部和内容的一些重要的函数。而大多数只处理RTP数据包的负载和时间戳。

RTP数据分组

分组模块实现了一个允许漏接的缓冲机制,这样能够减少内存的动态分配请求。尽管不是必要的但还是建议使用FreePacket()来归还分组到分组队列,这样能够减少动态内存分配和过度的垃圾回收。这对于长时间发送音视频的应用可能有利。

传输模块

GoRTP使用栈式传输模块来实现。最底层使用udp,tcp或者其他网络协议。传输模块如果想要作为一个接收者预定发送者就必须实现TransportRecv和/或TransportWrite。

上层的传输模块过滤接收到的数据并产生特定的输出,比如ICE传输莫款能处理所有的ICE相关的数据并且将不会把ICE数据分组发送给会话模块,因为会话模块只期待接受RTP数据。会话模块将丢弃所有的非RTP和非RTCP分组。

客户端程序应根据自己的需要来构建传输栈。应用使用高层的传输模块来初始化RTP回话,通常来说一个应用只用一个传输模块。以下代码展示了它是怎么工作的。

var localPort = 5220var local, _ = net.ResolveIPAddr("ip", "127.0.0.1")var remotePort = 5222var 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

Go实现的RTP栈——GoRTP介绍