RTCP实时传输控制协议(Real-time ControlProtocol)与RTP共同定义在1996年提出的RFC 1889中,是和 RTP一起工作的控制协议。不同类型的RTCP信息包可堆叠,不需要插入任何分隔符就可以将多个RTCP包连接起来形成一个RTCP组合包。
RTCP 组合包介绍
在实际应用中RTCP包如:SR、RR包等,可以做为一个单独包进行发送,也可以和其他包组合在一起发送。
当多个RTCP包组合发送时,服务端需要拆分组合包得到单个包,然后再进行处理。
如下图:RR包和Feedback反馈包组合一起发送。
服务端解析组合包
先看下RTCP 协议,以RR包为例:(mediasoup中解析rtcp逻辑见packet.cpp)
RTCP包前四个字节都是一样的固定头,对应mediasoup中的CommonHeader
/* Struct for RTCP common header. */
struct CommonHeader
{
#if defined(MS_LITTLE_ENDIAN) //小端
uint8_t count : 5;
uint8_t padding : 1;
uint8_t version : 2;
#elif defined(MS_BIG_ENDIAN) //大端
uint8_t version : 2;
uint8_t padding : 1;
uint8_t count : 5;
#endif
uint8_t packetType : 8;
uint16_t length : 16;
};
特别注意一下length字段,这个length不是单个rtcp的实际大小。
该字段的值是RTCP包长度减一,然后以32bit(4个字节)为单位存储,所以单个RTCP包真实大小是(length+1)*4。
mediasoup中对rtcp包解析
Packet* Packet::Parse(const uint8_t* data, size_t len)
{
MS_TRACE();
// First, Currently parsing and Last RTCP packets in the compound packet.
Packet* first{ nullptr };
Packet* current{ nullptr };
Packet* last{ nullptr };
while (len > 0u)
{//首先判断是否是RTCP包
if (!Packet::IsRtcp(data, len))
{
MS_WARN_TAG(rtcp, "data is not a RTCP packet");
return first;
}
auto* header = const_cast<CommonHeader*>(reinterpret_cast<const CommonHeader*>(data));
//获取组合包中单个RTCP包的实际长度
size_t packetLen = static_cast<size_t>(ntohs(header->length) + 1) * 4;
//获取该包的类型,根据不同的包类型,分别解析
switch (Type(header->packetType))
{
case Type::SR:
case Type::RR:
case Type::RTPFB:
case Type::PSFB:
}
//每次向前偏移单个RTCP包的大小,继续解析组合包中的下一个RTCP包
data += packetLen;
len -= packetLen;
}
}
作者:音视频之路
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。