SSRC:32 bits,该字段用来确定数据的发送源。这个身份标识应该随机生成,并且要保证同一个 RTP Session 中没有重复的 SSRC。虽然 SSRC 冲突的概率很小,但是每个 RTP 客户端都应该时刻警惕,如果发现冲突就要去解决。
CSRC list:0 ~ 15 items, 32 bits each,CSRC list 表示对该 payload 数据做出贡献的所有 SSRC。这个字段包含的 SSRC 数量由 CC 字段定义。如果有超过 15 个 SSRC,只有 15 个可以被记录。
RTP Session 多路复用在 RTP 中,多路复用由目标传输地址(address:port)提供,不同的 RTP Session 有不同的传输地址。
独立的音频和视频流不应该包含在同一个 RTP Session 中,也不应该通过 payload 类型和 SSRC 来区分不同的流。如果用同一个 SSRC 发送了不同的数据流,会引入如下问题:
假设 2 个音频流共享了一个 RTP Session,并且用了同一个 SSRC,如果其中一个要改变编码,这就导致了 payload 类型的改变,但是协议中没有提供方法来让接收者知道具体是哪个音频流改变了编码。
一个 SSRC 只有一个对应的时序和序列号,如果多个流有不同的时钟周期的话,就需要不同的时序。而且还不能用序列号来确认是哪个流丢包了。
RTCP 发送者报告和接收者报告只描述了时序和序列号而不包含 payload 类型数据。
Mixer 无法将不兼容的两个流合并。
如果一个 RTP Session 中包含了多个媒体流后就会失去如下优势:
使用不同的网络路径或者分配网络资源
只接收某一种媒体数据(网络较差时只接收 audio)
接收方对不同的媒体类型做不同的处理
不同的流使用不同的 SSRC 但是仍然用同一个 RTP Session 发送确实可以解决前三个问题,但是仍然无法解决后两个问题。
预设可能对 RTP 头的改动现有的这些 RTP 报文头对一般应用来说已经足够了。如果有需要,头字段可以根据预设进行一些修改,但仍要保证检测和统计功能的正常使用。
RTP 头拓展RTP 提供了一个拓展机制,让上层应用可以将自定义的信息存储在 RTP 报文头。如果上层应用收到了无法识别的头部拓展数据,它们会忽略它。
值得一提的是,这个头部拓展是有一些限制的。如果附加信息只对某些 payload 格式才有意义,那么最好还是别把这些信息放到头部拓展中,而是放到 payload 部分。
如果 RTP Header 中的 X 位设置为 1,那么 Header 后必须跟着一个不定长度的拓展块,紧跟着 CSRC list(如果有的话)。拓展部分的头部包含一个 16-bit 的数据来描述拓展块包含多少个 32-bit 字(不包括拓展部分的头部)。因为 RTP 头部后面只能连接一个拓展块,考虑到有些应用可能会有多种类型的拓展块,所以拓展块的头 16-bit 留给开发者去自定义一些参数。 RTP 控制协议
同一个 Session 所有参与者会周期性地发送控制报文,RTP 控制协议就是通过这种方式进行的,和 RTP 数据的传播一样采用了组播的机制。下层协议必须提供数据包和控制报文的多路复用功能,例如使用独立的 UDP 端口分别传输数据和控制报文。RTCP 协议具有如下四大功能:
最主要的功能是反馈数据分发的质量。这也是 RTP 作为一个传输协议来说最关键的功能,而且它和流量控制,拥塞控制息息相关。反馈信息可能会直接影响自适应编码的控制。发送反馈报告给所有的参与者可以让它们评估遇到的数据分发问题是个人问题还是全局问题。通过 IP 组播这样的分发机制,像网络提供商这样的机构即便不加入到这个 RTP Session 中也能收到反馈信息,它们会扮演一个第三方监测者的角色去确认数据分发问题。这个反馈的功能无论是 RTCP 的发送者还是接收者都会进行报告。
RTCP 还会给每个 RTP source 带一个不变的传输层身份识别符(CNAME),因为 SSRC 可能会中途改变(程序重启),所以接收者需要这个 CNAME 来持续追踪每个与会者。而且,接收者可以通过 CNAME 来将同一个与会者的所有数据流联系在一起,比如同步音频和视频。单个媒体内部的数据同步也需要 NTP 和 RTP 时间戳,这些数据都在数据发送者发送的 RTCP 报文中。
因为前两个功能需要所有的与会者都发送 RTCP 报文,所以需要适当的控制报文发送的频率以保证 RTP 协议可以在大量客户端一同加入时也能正常工作。通过每个参与者都广播控制报文的方式,每个人都能独立地计算出参与者的总数。