标题：RTP/RTCP
简介
专用术语实时传输协议RTP（Realtime Transport Protocol）：是针对Internet上多媒体数据流的一个传输协议, 由IETF(Internet工程任务组)作为RFC1889发布。RTP被定义为在一对一或一对多的传输情况下工作，其目的是提供时间信息和实现流同步。RTP的典型应用建立在UDP(User Datagram Protocol,用户数据包协议)上，但也可以在TCP（Transfer Control Protocol,传输控制协议）或ATM（Asynchronous Transfer Mode,异步传输模式）等其他协议之上工作。RTP本身只保证实时数据的传输，并不能为按顺序传送数据包提供可靠的传送机制，也不提供流量控制或拥塞控制，它依靠RTCP提供这些服务。
实时传输控制协议RTCP（Realtime Transport Control Protocol）：负责管理传输质量在当前应用进程之间交换控制信息。在RTP会话期间，各参与者周期性地传送RTCP包，包中含有已发送的数据包的数量、丢失的数据包的数量等统计资料，因此，服务器可以利用这些信息动态地改变传输速率，甚至改变有效载荷类型。RTP和RTCP配合使用，能以有效的反馈和最小的开销使传输效率最佳化，故特别适合传送网上的实时数据。
RTCP主要有4个功能:  流程图（1）用反馈信息的方法来提供分配数据的传送质量，这种反馈可以用来进行流量的拥塞控制，也可以用来监视网络和用来诊断网络中的问题；
（2）为RTP源提供一个永久性的CNAME（规范性名字）的传送层标志，因为在发现冲突或者程序更新重启时SSRC(同步源标识)会变，需要一个运作痕迹，在一组相关的会话中接收方也要用CNAME来从一个指定的与会者得到相联系的数据流（如音频和视频）；
（3）根据与会者的数量来调整RTCP包的发送率；
（4）传送会话控制信息，如可在用户接口显示与会者的标识，这是可选功能。
工作流程
RTP协议从上层接收流媒体信息码流（如H.263），装配成RTP数据包发送给下层，下层协议提供RTP和RTCP的分流。如在UDP中，RTP使用一个偶数号端口，则相应的RTCP使用其后的奇数号端口。RTP数据包没有长度限制，它的最大包长只受下层协议的限制。RTP会话和流的两级分用一个RTP会话(Session)包括传给某个指定目的地对(Destination Pair)的所有通信量，发送方可能包括多个。而从同一个同步源发出的RTP分组序列称为流(Stream),一个RTP会话可能包含多个RTP流。一个RTP分组在服务器端发送出去的时候总是要指定属于哪个会话和流，在接收时也需要进行两级分用，即会话分用和流分用。只有当RTP使用同步源标识(SSRC)和分组类型(PTYPE)把同一个流中的分组组合起来，才能够使用序列号(Sequence Number)和时间戳(Timestamp)对分组进行排序和正确回放。
由于实时数据的独有性，不同实时客户可以共用一个RTP实时服务线程和一个RTCP实时服务线程，这样可以大大减小服务器的负担，而每个文件客户由于请求的文件不同，相应地对速度和开始时间的要求都可能不同，所以需要有自己独有的RTP文件服务线程和RTCP文件服务线程。
RTP服务线程负责把实时数据流发送给客户，RTCP服务线程根据RTP线程的统计数据，产生发送方报告给客户。RTP线程和RTCP线程之间通过一段共享内存交互统计数据，对共享内存必须设置互斥体进行保护，防止出现错误读写。在这种方式下，服务器可以根据每个用户的不同请求和具体情况方便地提供不同的服务。
RTP 时间戳的处理
时间戳字段是RTP首部中说明数据包时间的同步信息，是数据能以正确的时间顺序恢复的关键。时间戳的值给出了分组中数据的第一个字节的采样时间(Sampling Instant)，要求发送方时间戳的时钟是连续、单调增长的，即使在没有数据输入或发送数据时也是如此。在静默时，发送方不必发送数据，保持时间戳的增长，在接收端，由于接收到的数据分组的序号没有丢失，就知道没有发生数据丢失，而且只要比较前后分组的时间戳的差异，就可以确定输出的时间间隔。
RTP规定一次会话的初始时间戳必须随机选择，但协议没有规定时间戳的单位，也没有规定该值的精确解释，而是由负载类型来确定时钟的颗粒，这样各种应用类型可以根据需要选择合适的输出计时精度。
在RTP传输音频数据时，一般选定逻辑时间戳速率与采样速率相同，但是在传输视频数据时，必须使时间戳速率大于每帧的一个滴答。如果数据是在同一时刻采样的，协议标准还允许多个分组具有相同的时间戳值。
RTP协议没有规定RTP分组的长度和发送数据的速度，因而需要根据具体情况调整服务器端发送媒体数据的速度。对来自设备的实时数据可以采取等时间间隔访问设备缓冲区，在有新数据输入时发送数据的方式，时间戳的设置相对容易。对已经录制好的本地硬盘上的媒体文件，以H.263格式的文件为例，由于文件本身不包含帧率信息，所以需要知道录制时的帧率或者设置一个初始值，在发送数据的时候找出发送数据中的帧数目，根据帧率和预置值来计算时延，以适当的速度发送数据并设置时间戳信息。
RTCP的一个关键作用就是能让接收方同步多个RTP流，例如：当音频与视频一起传输的时候，由于编码的不同，RTP使用两个流分别进行传输，这样两个流的时间戳以不同的速率运行，接收方必须同步两个流，以保证声音与影像的一致。为能进行流同步，RTCP要求发送方给每个传送一个唯一的标识数据源的规范名(Canonical Name），尽管由一个数据源发出的不同的流具有不同的同步源标识(SSRC)，但具有相同的规范名，这样接收方就知道哪些流是有关联的。而发送方报告报文所包含的信息可被接收方用于协调两个流中的时间戳值。发送方报告中含有一个以网络时间协议NTP(Network Time Protocol)格式表示的绝对时间值，接着RTCP报告中给出一个RTP时间戳值，产生该值的时钟就是产生RTP分组中的TimeStamp字段的那个时钟。由于发送方发出的所有流和发送方报告都使用同一个绝对时钟，接收方就可以比较来自同一数据源的两个流的绝对时间，从而确定如何将一个流中的时间戳值映射为另一个流中的时间戳值。服务器的算法服务器软件模型主要有两种，即并发服务器和循环服务器。循环服务器(Iterative Server)是指在一个时刻只处理一个请求的服务器。并发服务器(Concurrent Server)是指在一个时刻可以处理多个请求的服务器。事实上，多数服务器没有用于同时处理多个请求的冗余设备，而是提供一种表面上的并发性，方法是依靠执行多个线程，每个线程处理一个请求，从客户的角度看，服务器就像在并发地与多个客户通信。 
由于流媒体服务时间的不定性和数据交互实时性的请求，流媒体服务器一般采用并发服务器算法。本文构建了一个基本的流媒体服务器，能够同时响应多个用户的请求，把本地硬盘流媒体文件或实时数据流(H.263格式)发送给用户。在应用中，把客户分为请求实时数据的实时客户和请求文件数据的文件客户两类。主要算法为： 
(1)打开设备，分配资源。当设备准备好时，创建一个RTP实时服务线程和一个RTCP实时服务线程。 
(2)创建一个UDP套接字并将其绑定到所提供服务的地址之上。 
(3)反复调用接收模块，接收来自客户的RTCP报告，根据其类型做出响应。对新实时客户的请求，把客户地址添加到实时服务的客户列表中，对新文件客户的请求，则创建一个新RTP文件服务线程和一个新RTCP文件服务线程;对已经在服务中的客户则根据RTCP报告的内容调整服务。 
RTP实时服务线程1：初始化客户列表和RTP首部。 
RTP实时服务线程2：从设备读取媒体数据，把数据发送给实时服务列表中的客户。 
RTP实时服务线程3：更新RTP首部和统计数据。 
RTP实时服务线程4：计算延时，重复第二步。 
RTCP实时服务线程1：初始化RTCP首部。 
RTCP实时服务线程2：发送发送方报告给实时服务列表中的客户。 
RTCP实时服务线程3：计算延时，重复第二步。 
RTP文件服务线程1：初始化RTP首部。 
RTP文件服务线程2.：从文件读取媒体数据，把数据发送给客户。 
RTP文件服务线程3：更新已发送数据的统计信息，为生成发送方报告做准备。 
RTP文件服务线程4：计算延时，调整发送速度，正常情况下开始重复第二步。 
RTCP文件服务线程1：初始化RTCP首部，发送一个源描述(SDES)报文给客户。 
RTCP文件服务线程2：根据已发送数据的统计信息生成发送方报告，发送给客户。 
RTCP文件服务线程3：计算延时，正常情况下开始重复第一步。
RTP/RTCP实现（C++）
对于wifi手机来说呢，RTP协议用来传送编码后的语音，RTCP协议用来传送控制信息，公司的RTCP附带了一些语音统计信息和jitter buffer的统计信息用来防止语音抖动。