RTP协议详解

本文详细介绍了RTP协议的基本概念,包括其实时传输特性、与RTCP的配合使用、会话过程及jrtplib库的应用。RTP用于多媒体数据的传输,提供时间戳和序列号等功能确保数据的有序播放。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

流媒体协议详解_步基的博客-CSDN博客

目录

流媒体协议详解_步基的博客-CSDN博客

1 RTP概述

2 RTCP

3 RTP会话过程

4 jrtplib库


1 RTP概述

全名是Real-time Transport Protocol(实时传输协议),对应文档RFC3550。也包含配套协议RTCP(Real-time Transport Control Protocol,即实时传输控制协议),提供服务质量。RTP基于UDP,分组传输,接收端数据包往往有延迟和乱序。在发送端,存在丢包;为降低延迟,往往对传输数据进行预处理(降低质量和高效压缩)。在接收端为了恢复时序,采用了接收缓冲;而为了实现媒体的流畅播放,则采用了播放缓冲。使用接收缓冲,可以将接收到的数据包缓存起来,然后根据数据包的封装信息(如包序号和时戳等),将乱序的包重新排序,最后将重新排序了的数据包放入播放缓冲播放。

        视频会议同时使用了音频和视频会议,将分别在不同的RTP会话中传送,每一个会话使用不同的传输地址(IP地址+端口),并且每个会话对应的RTCP包都使用规范化名字CNAME(Canonical Name)。与会者可以根据RTCP包中的CNAME来获取相关联的音频和视频,然后根据RTCP包中的计时信息(Network time protocol)来实现音频和视频的同步。

        翻译器和混合器都是RTP级的中继系统。翻译器用在通过IP多播不能直接到达的用户区,例如发送者和接收者之间存在防火墙。当与会者能接收的音频编码格式不一样,比如有一个与会者通过一条低速链路接入到高速会议,这时就要使用混合器。在进入音频数据格式需要变化的网络前,混合器将来自一个源或多个源的音频包进行重构,并把重构后的多个音频合并,采用另一种音频编码进行编码后,再转发这个新的RTP包。从一个混合器出来的所有数据包要用混合器作为它们的同步源(SSRC,见RTP的封装)来识别,可以通过贡献源列表(CSRC表,见RTP的封装)可以确认谈话者。
 

                                                              图1 RTP协议

                                                           图2 RTP协议头

版本号(V):2比特,用来标志使用的RTP版本。

填充位(P):1比特,如果该位置位,则该RTP包的尾部就包含附加的填充字节。

扩展位(X):1比特,如果该位置位的话,RTP固定头部后面就跟有一个扩展头部。

CSRC计数器(CC):4比特,含有固定头部后面跟着的CSRC的数目。

标记位(M):1比特,该位的解释由配置文档(Profile)来承担.

载荷类型(PT):7比特,标识了RTP载荷的类型。

序列号(SN):16比特,发送方在每发送完一个RTP包后就将该域的值增加1,接收方可以由该域检测包的丢失及恢复包序列。序列号的初始值是随机的。

时间戳:32比特,记录了该包中数据的第一个字节的采样时刻。在一次会话开始时,时间戳初始化成一个初始值。即使在没有信号发送时,时间戳的数值也要随时间而不断地增加(时间在流逝嘛)。时间戳是去除抖动和实现同步不可缺少的。

同步源标识符(SSRC):32比特,同步源就是指RTP包流的来源。在同一个RTP会话中不能有两个相同的SSRC值。该标识符是随机选取的 RFC1889推荐了MD5随机算法。

贡献源列表(CSRC List):0~15项,每项32比特,用来标志对一个RTP混合器产生的新包有贡献的所有RTP包的源。由混合器将这些有贡献的SSRC标识符插入表中。SSRC标识符都被列出来,以便接收端能正确指出交谈双方的身份。

2 RTCP

主要功能是:服务质量的监视与反馈、媒体间的同步,以及多播组中成员的标识。在RTP会话期 间,各参与者周期性地传送RTCP包。RTCP包中含有已发送的数据包的数量、丢失的数据包的数量等统计资料,因此,各参与者可以利用这些信息动态地改变传输速率,甚至改变有效载荷类型。RTP和RTCP配合使用,它们能以有效的反馈和最小的开销使传输效率最佳化,因而特别适合传送网上的实时数据。

从图 1可以看到,RTCP也是用UDP来传送的,但RTCP封装的仅仅是一些控制信息,因而分组很短,所以可以将多个RTCP分组封装在一个UDP包中。RTCP有如下五种分组类型。

上述五种分组的封装大同小异,下面只讲述SR类型,而其它类型请参考RFC3550。

发送端报告分组SR(Sender Report)用来使发送端以多播方式向所有接收端报告发送情况。SR分组的主要内容有:相应的RTP流的SSRC,RTP流中最新产生的RTP分组的时间戳和NTP,RTP流包含的分组数,RTP流包含的字节数。SR包的封装如图3所示。

                                                   图 3 RTCP头部的格式

版本(V):同RTP包头域。

填充(P):同RTP包头域。

接收报告计数器(RC):5比特,该SR包中的接收报告块的数目,可以为零。

包类型(PT):8比特,SR包是200。

长度域(Length):16比特,其中存放的是该SR包以32比特为单位的总长度减一。

同步源(SSRC):SR包发送者的同步源标识符。与对应RTP包中的SSRC一样。

NTP Timestamp(Network time protocol)SR包发送时的绝对时间值。NTP的作用是同步不同的RTP媒体流。

RTP Timestamp:与NTP时间戳对应,与RTP数据包中的RTP时间戳具有相同的单位和随机初始值。

Sender’s packet count:从开始发送包到产生这个SR包这段时间里,发送者发送的RTP数据包的总数. SSRC改变时,这个域清零。

Sender`s octet count:从开始发送包到产生这个SR包这段时间里,发送者发送的净荷数据的总字节数(不包括头部和填充)。发送者改变其SSRC时,这个域要清零。

同步源n的SSRC标识符:该报告块中包含的是从该源接收到的包的统计信息。

丢失率(Fraction Lost):表明从上一个SR或RR包发出以来从同步源n(SSRC_n)来的RTP数据包的丢失率。

累计的包丢失数目:从开始接收到SSRC_n的包到发送SR,从SSRC_n传过来的RTP数据包的丢失总数。

收到的扩展最大序列号:从SSRC_n收到的RTP数据包中最大的序列号,

接收抖动(Interarrival jitter):RTP数据包接受时间的统计方差估计

上次SR时间戳(Last SR,LSR):取最近从SSRC_n收到的SR包中的NTP时间戳的中间32比特。如果目前还没收到SR包,则该域清零。

上次SR以来的延时(Delay since last SR,DLSR):上次从SSRC_n收到SR包到发送本报告的延时。

3 RTP会话过程

        当应用程序建立一个RTP会话时,应用程序将确定一对目的传输地址。目的传输地址由一个网络地址和一对端口组成,有两个端口:一个给RTP包,一个给RTCP包,使得RTP/RTCP数据能够正确发送。RTP数据发向偶数的UDP端口,而对应的控制信号RTCP数据发向相邻的奇数UDP端口(偶数的UDP端口+1),这样就构成一个UDP端口对。 RTP发送过程如下,接收过程则相反。

1)  RTP协议从上层接收流媒体信息码流(如H.264),封装成RTP数据包;RTCP从上层接收控制信息,封装成RTCP控制包。

2) RTP将RTP 数据包发往UDP端口对中偶数端口;RTCP将RTCP控制包发往UDP端口对中的奇数端口。

注意:

1根据RTP包的序列号来排序。

2根据声音流和图像流的相对时间(即RTP包的时间戳),以及它们的绝对时间(即对应的RTCP包中的RTCP),可以实现声音和图像的同步。

3接收缓冲用来排序乱序了的数据包;播放缓冲用来消除播放的抖动,实现等时播放。

4 jrtplib库

初始化

RTPSession sess; 

sess.Create(5000);

//3.11版jrtplib库的Create方法被修改为Create(sessparams,&transparams)
RTPUDPv4TransmissionParams transparams;
RTPSessionParams sessparams;
 sessparams.SetOwnTimestampUnit(1.0/8000.0);/*设置时间戳,1/8000表示1秒钟采样8000次,即录音时的8KHz*/
 sessparams.SetAcceptOwnPackets(true);
 transparams.SetPortbase(portbase);/*本地通讯端口*/

数据发送

//RTP 协议允许同一会话存在多个目标地址

unsigned long addr = ntohl(inet_addr("127.0.0.1"));
sess.AddDestination(addr, 6000);

sess.SetDefaultPayloadType(0);
sess.SetDefaultMark(false);  
sess.SetDefaultTimeStampIncrement(10);

sess.SendPacket((void *)buffer,sizeof(buffer),0,false,8000);

数据接收

sess_client.Poll();                                            //接收发送过来的 RTP 或者RTCP 数据报

sess_client.BeginDataAccess();

if (sess.GotoFirstSourceWithData()) {     //遍历那些携带有数据的源
 do {   
          sess.AddToAcceptList(remoteIP, allports,portbase);
           sess.SetReceiveMode(RECEIVEMODE_ACCEPTSOME);
 
           RTPPacket *pack;         
          pack = sess.GetNextPacket();            // 处理接收到的数据    
           delete pack;   }
 while (sess.GotoNextSourceWithData());
 }

sess_client.EndDataAccess();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

步基

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值