rtp over rtsp(tcp)
rtp over udp与rtp over rtsp(tcp)的区别:
-
RTP OVER UDP
- tcp连接进行rtsp信令交互;
- 创建新的udp套接字来发送rtp包;
- 创建新的udp套接字来发送rtcp包;
-
RTP OVER RTSP(TCP)
- tcp连接进行rtsp信令交互;
- 复用rtsp的tcp连接发送rtp和rtcp包;
rtsp/rtp/rtcp
rtp/rtcp包,每包前面都加上4个字节。
字节 | 描述 |
---|---|
第一个字节 | ‘$’标识符(0x24,固定) |
第二个字节 | 通道(channel)。一般情况下偶数是rtp通道,奇数是rtcp通道 interleaved=0:视频流 RTP; interleaved=1:视频流 RTCP; interleaved=2:音频流 RTP; interleaved=3:音频流 RTCP; |
第三个和第四个字节 | rtp包的大小 |
# 说明1
第一个字节‘$’主要用来区分rtsp。
# 说明2
第二个字节主要用来区分rtp和rtcp, 通道是在rtsp的setup过程中, 客户端提供给服务端的。
rtsp中setup信令传输示例:
- UDP传输
# C->S
SETUP rtsp://192.168.1.100:8554/live/track1 RTSP/1.0
CSeq: 5
Transport: RTP/AVP;unicast;client_port=51950-51951
Session: xxx
# S->C
RTSP/1.0 200 OK
CSeq: 5
Transport: RTP/AVP;unicast;client_port=51950-51951;server_port=21342-21343
Session: xxx
- TCP传输
# C->S
SETUP rtsp://192.168.1.100:8554/live/track0 RTSP/1.0
CSeq: 6
User-Agent: LibVLC/3.0.14
Transport: RTP/AVP/TCP;unicast;interleaved=0-1 # 0: rtp通道 1: rtcp通道
# S->C
RTSP/1.0 200 OK
CSeq: 6
Transport: RTP/AVP/TCP;unicast;interleaved=0-1
Session: xxx
补充
关于创建传输端口
开发rtsp服务端时,在处理tcp或udp端口组装时略有不同,如下代码所示:
// 此部分参考ireader库中示例代码
if(RTSP_TRANSPORT_RTP_TCP == transport->transport)
{
UINT8 interleaved[2];
if (transport->interleaved1 == transport->interleaved2)
{
interleaved[0] = session->channel++;
interleaved[1] = session->channel++;
}
else
{
interleaved[0] = (UINT8)transport->interleaved1;
interleaved[1] = (UINT8)transport->interleaved2;
}
// ...
snprintf(rtsp_transport, sizeof(rtsp_transport), "RTP/AVP/TCP;interleaved=%d-%d", interleaved[0], interleaved[1]);
}
else if(transport->multicast)
{
unsigned short port[2] = { transport->rtp.u.client_port1, transport->rtp.u.client_port2 };
char multicast[65] = {0};
if(transport->destination[0])
{
snprintf(multicast, sizeof(multicast), "%s", transport->destination);
port[0] = transport->rtp.m.port1;
port[1] = transport->rtp.m.port2;
}
else
{
snprintf(multicast, sizeof(multicast), "%s", GetCRtspConfig().GetConfigString(RTSP_UDP_MULTICAST_ADDR_PARAM).c_str());
port[0] = (unsigned short)GetCRtspConfig().GetConfigInt(RTSP_UDP_MULTICAST_PORT_PARAM);
port[1] = (unsigned short)GetCRtspConfig().GetConfigInt(RTSP_UDP_MULTICAST_PORT_PARAM) + 1;
}
// ...
snprintf(rtsp_transport, sizeof(rtsp_transport),
"RTP/AVP;multicast;destination=%s;port=%hu-%hu;ttl=%d",
multicast, port[0], port[1], 16);
}
else
{
unsigned short port[2] = { transport->rtp.u.client_port1, transport->rtp.u.client_port2 };
//...
snprintf(rtsp_transport, sizeof(rtsp_transport),
"RTP/AVP;unicast;client_port=%hu-%hu;server_port=%hu-%hu%s%s",
transport->rtp.u.client_port1, transport->rtp.u.client_port2,
port[0], port[1],
transport->destination[0] ? ";destination=" : "",
transport->destination[0] ? transport->destination : "");
}