FFMPEG之RTP协议(实时传输协议)01
FFMPEG之RTP协议(实时传输协议)01
1 RTP与RTCP控制协议
1)RTP协议功能:
用于网络上实时传输音视频数据的标准数据包格式,例如流媒体、视频会议、电视服务等等。
2)RTP为何需要RTCP配合使用:
RTP可以提供低延时的数据传送服务,但无法保证数据包到达客户端时仍然保持着发送时的顺序,所以要依靠RTCP来完成流量控制和拥塞监控。
3)RTP为何需要与***?
在OSI七层模型中,RTP协议运行在传输层,其他底层协议也可以和RTP协同工作。RTP数据包被UDP通过封装头形成UDP包。
RTP本身未包含任何服务质量保证机制,因此RTP无法保持接收到的数据域传送顺序相同,也不去验证底层网络所提供的服务是否可靠。RTP通过在数据包中添加***,使得接收方能够在收到数据包后通过检测***对数据包重新排序,以达到有序的目的。
4)RTP为何需要时间戳?
在流媒体数据传输时,人们通常面临这同一个严峻的问题,那就是数据传送到客户端的时间点时无法预测的,但是,流媒体的传送要保证数据能够在合适的时间传送目的地以完成数据正确的回放。
因此,RTP协议中为了控制实时数据流传输而包含时间戳、***等结构。时间戳在流媒体传送的过程中扮演了重要的校色,为客户端提供了重要的数据。在发送RTP报文时,发送端在数据包里放置了用于记录采样时间的数据,称为时间戳,数据包经网络到达接收端后,接收端则需要从数据包中提取出该数据端,依照它来恢复原始的数据次序。RTP只是传输层协议,并不负责同步。RTP将这部分功能留给应用层来完成,已达到简化数据处理、提高运行效率的目的。
RTP的数据单元是用UDP分组来承载的,当然并不是简单地将一个RTP数据单元封装在UDP分组中,而是把一帧数据分割后放入多个UDP分组中传送,本属于同一帧数据的UDP分组将具有完全一样的时间戳。
5)为何要使用RTCP:
在RTP会话期间,RTCP协议的作用主要是传送监控数据传送正确率的交换控制信息。在会话期间,与会者们将会发送一些相关的统计信息给其他用户,例如已发送的数据包的数量和无法传送的数据包的数量,这些信息的发送通常每隔相同的时间进行一次,在会话进行过程中周期性完成。
服务器将解析这些数据,并据此提高或降低数据的发送速率,也有可能换用其它类型的有效载荷。这些改变将是动态进行的。RTP配合RTCP运行,通过返回控制信息和减小带宽消耗提升传输效率,从而保证数据传输的时延最小。
6)RTCP的主要4个功能:
RTCP主要有4个功能:通过反馈分配数据的传送质量来进行拥塞控制、监视网络和诊断网络中的问题;由于SSRC(同步源标识)并不会一成不变,当网络拥塞发生时或者与会者程序发生变化时SSRC多会随之更新,我们需要为RTP源提供额外的传送层标志;调整RTCP包的发送速度,以保证数据包能顺利到达接收端,因此需要依据参与者的数据来进行调整;传送会话控制信息。
2 RTP的文件头格式
RTP报文由两部分组成:报头和有效载荷,头部共12个字节。
版本号(V):2bit,用来标志使用的RTP版本。
填充位(P):1bit,如果该位置位,则该RTP包的尾部就包含附加的填充字节。
扩展位(X):1bit,如果该位置位的话,RTP固定头部后面就跟有一个扩展头部。
CSRC计数器(CC):4bit,SSRC后的CSRC的数目。
标记位(M): 1bit,该位的解释由配置文档(Profile)来负责。
载荷类型(PayloadType): 7bit,标识了RTP载荷的类型。详细将下标。
***(SN):16bit,每发送一个 RTP 数据包,***增加1。接收端可以据此检测丢包和重建包序列。
时间戳(timestamp): 4byte,记录了该包中数据的第一个字节的采样时刻。在一次会话开始时,时间戳初始化成一个初始值。即使在没有信号发送时,时间戳的数值也要随时间而不断地增加。时钟频率依赖于负载数据格式,并在描述文件(profile)中进行描述。
同步源标识符(SSRC):32比特,同步源就是指RTP包流的来源。在同一个RTP会话中不能有两个相同的SSRC值。该标识符是随机选取的 RFC1889推荐了MD5随机算法。
贡献源列表(CSRC):0~15项,每项32比特,用来标志对一个RTP混合器产生的新包有贡献的所有RTP包的源。由混合器将这些有贡献的SSRC标识符插入表中。SSRC标识符都被列出来,以便接收端能正确指出交谈双方的身份。
7位的载荷类型如下:
RFC3551:
3 代码实现RTP头格式
#pragma pack(1)//1位字节对齐
//变量:数字表示位与操作,结构体字节的大小按照平时的方法计算即可
typedef struct RTP_FIXED_HEADER{
/* byte 0 */
unsigned char csrc_len:4; /* expect 0 */
unsigned char extension:1; /* expect 1 */
unsigned char padding:1; /* expect 0 */
unsigned char version:2; /* expect 2 */
/* byte 1 */
unsigned char payload:7;
unsigned char marker:1; /* expect 1 */
/* bytes 2, 3 */
unsigned short seq_no;
/* bytes 4-7 */
unsigned long timestamp;
/* bytes 8-11 */
unsigned long ssrc; /* stream number is used here. */
} RTP_FIXED_HEADER;