语音传输之RTP/RTCP/UDP及软件实现关键点
语音通信是实时通信,一定要保证实时性,不然用户体验会很糟糕。IETF设计了RTP来承载语音等实时性要求很高的数据,同时设计了RTCP来保证服务质量(RTP不保证服务质量)。在传输层,一般选用UDP而不是TCP来承载 RTP包。下图给出了这三个协议所在的协议层次。
本文先简单讲一下这三个协议(网上好多文章都讲,这里主要讲关键点),然后讲软件实现注意点。
1,RTP
RTP全称是Real-time Transport Protocol(实时传输协议),它是IETF提出的一个标准,对应的RFC文档为RFC3550。一般用其承载实时性要求很高的数据形成RTP包,在语音通信中,把PCM数据编码后得到的码流作为RTP的payload。下图是其包头结构。
这里主要讲一些关键点:
a) 包头的版本信息等都是用几个比特位来表示的,共两个字节,在软件实现时要用位域的形式表示。在大小端情况下有不同的表示方式,主要是在一个字节里大小端表示时位置要互换,具体如下图RTP头数据结构定义。
b) RTP包都是以网络序/大端的形式在网络中传输,这样就有一个网络序主机序互转的过程。
c) M 位即Mark位,表示语音的开始,在通话刚开始的第一个语音包,M位要置1。如果 VAD使能,从VAD包切到语音包时,第一个语音包M位也要置1。
d) 在通话刚开始的第一个语音包中,sequence/timestamp/SSRC等都要是随机值。在后续的包中,SSRC代表通话的一方,在整个通话过程中都要保持不变。Sequence要每次加一。Timestamp要依据采样率以及帧长每次加本帧内采样的点数值,比如8000 Hz采用率,帧长为20ms, 每次timestamp要加160。
软件实现RTP协议时,先要初始化(主要是包头字段的初始化)。发送方把每一帧PCM数据编码后得到码流,将其作为RTP的payload,同时填充好包头中的字段,然后通过UDP socket发送到网络中去。接收方通过UDP socket收到RTP包,解析包头得到payload type/sequence等信息,同时也得到payload,然后将它们送给下一个模块处理。
实现完RTP后要检查实现的是否正确,抓包看是主要的方式。抓到包后把UDP转换成RTP后就可以看相关信息了,主要看格式是否对以及包头中的字段的值是否对。如果格式不对,抓包工具(wireshark)会提示。
2,RTCP
RTCP全称是Real-time Control Protocol(实时控制协议),它也是IETF提出的一个标准,对应的RFC文档为RFC3551,它的主要功能是:服务质量的监视与反馈、媒体间的同步。在RTP会话期间,各参与者周期性地(一般是5秒,应用层可以配)传送RTCP包,RTCP包中含有已发送的数据包的数量、丢失的数据包的数量、数据包到达的平均时间间隔等统计信息。
RTCP协议处理机定义了五种类型的报文,它们完成接收、分析、产生和发送控制报文的功能,如下表所示:
其中SR用来使发送端周期的向所有接收端用多播方式进行报告。RR用来使接收端周期性的向所有的点用多播方式进行报告。当参加者既发又收时就发SR,只收不发时就发RR。SDES给出会话中参加者的描述,包括参加者的规范名(CNAME)。BYE用来关闭一个数据流。APP能够定义新的分组类型。前四种类型经常用到,APP类型很少用到,我是没用过。
这五种类型中SR应用最频繁,就以它为例来讲,其他类型可以举一反三。它的封装结构见下图:
同RTP一样,这里也主要讲一些关键点:
a) 与RTP类似,RTCP包头中一些值也用比特位表示,实现时也要用位域表示,也有大小端的问题。
b) 算length时,计算公式是length = size/4 -1。其中size是SR包的真实大小(单位是字节)。
c) 算周期内丢包率(fraction lost)时,是以定点小数形式表示,即 fraction lost = (周期内丢包数 << 8) / 周期内期望接收包数.
d) 算DLSR时,是以1/65536秒为单位。
软件实现RTCP协议时,一般是几种类型的RTCP包组成组合包,所以一般先要判断要发几种类型的包。当处于SendReceive模式时,要发SR/SDES包,如果要停止通话,还要发BYE包;当处于ReceiveOnly模式时,要发RR/SDES包;如果要停止通话,还要发BYE包。RTCP中有RTP包的统计,所以实现RTCP前要先在RTP中把相关的统计做好,同时还要做好sequence number的管理等。实现RTCP时发送方先要实现SR或者RR包,然后是SDES包,如果是停止通话,还要加上BYE包。实现每种RTCP包时是把相应的字段值填好,然后再把包头填好。这些包都实现后拼在一起形成组合包,然后通过UDP socket发送到网络中去。接收方收到RTCP组合包后也是一个包一个包的去解析,然后把相应的信息报告给上层。
实现完RTCP后同样要检查实现的是否正确,抓包看同样是主要的方式。抓到包后把UDP转换成RTCP后就可以看相关信息了,主要看格式是否对以及包中相应的字段是否对。如果格式不对,抓包工具会提示。
个人觉得实现RTP相对简单,RTCP相对复杂一些,它是基于RTP的,有对RTP的各种统计,有对RTP sequence number的管理等。同时还要理解RTCP中为什么要设计这些字段以及它们的计算方法。这些都搞清楚了也就不难了。
3,UDP
UDP 全称是User Datagram Protocol(用户数据报协议),属于传输层协议(跟TCP在同一层),提供面向事务的简单不可靠信息传送服务,在IETF中对应的RFC文档为 RFC 768。至于为啥用UDP而不用TCP来传输实时性要求较高的数据,个人觉得主要有以下几点:TCP的重传机制(这时最主要的原因),TCP的包头较大浪费了带宽,TCP不支持组播。
实现时主要是调用系统提供的socket API。具体到linux上,我做过两种实现,一种是在user space里(这也是绝大多数使用者用的方法),另外一种是在kernel space里,用kernel 提供的socket API做。不管是user space还是kernel space里实现,主要是掌握socket API的使用,都是些套路,这里就不详细讲了。UDP的socket创建好后给RTP、RTCP用(RTP、RTCP各用一个socket,各有一个port号,一般RTP用的是偶数, RTCP的port号是相对应的RTP的port号加一)。
语音传输之RTP/RTCP/UDP及软件实现关键点的更多相关文章
- 视频流传输协议RTP/RTCP/RTSP/HTTP的区别 (转)
用一句简单的话总结:RTSP发起/终结流媒体.RTP传输流媒体数据 .RTCP对RTP进行控制,同步.之所以以前对这几个有点分不清,是因为CTC标准里没有对RTCP进行要求,因此在标准RTSP的代码中 ...
- 【转载】 IP实时传输协议RTP/RTCP详解
http://www.chinaitlab.com/cisco/RIP/832426.html 1.简介 目前,在IP网络中实现实时语音.视频通信和应用已经成为网络应用的一个主流技术和发展方向,本文详 ...
- IP实时传输协议RTP/RTCP详解
1.简介 目前,在IP网络中实现实时语音.视频通信和应用已经成为网络应用的一个主流技术和发展方向,本文详细介绍IP协议族中用于实时语音.视频数据传输的标准协议RTP( Real-time Transp ...
- TCP、UDP、RTP(RTCP)异同与区别
OSI七层模型OSI 中的层 功能 TCP/IP协议族 应 用层 ...
- 【转】TCP、UDP、RTP(RTCP)区别
转自:https://www.cnblogs.com/imystr/p/4026639.html OSI七层模型OSI 中的层 功能 ...
- RTP/RTCP、TCP、UDP、RTMP、RTSP
OSI中的层 功能 TCP/IP协议族 应用层 文件传输,电子邮件,文件服务,虚拟终端 TFTP,FTP,HTTP,SNMP,SMTP,DNS,RIP,Telnet 表示层 数据格式化,代码转换,数据 ...
- 流媒体传输协议(rtp/rtcp/rtsp/rtmp/mms/hls)转
常用的流媒体协议主要有HTTP渐进下载和基于RTSP/RTP的实时流媒体协议两类.在流式传输的实现方案中,一般采用HTTP/TCP来传输控制信息,而用RTP/UDP来传输实时多媒体数据. 1 实时传输 ...
- RTP RTCP在音视频传输与同步方面的使用
转自:http://blog.csdn.net/kof98765/article/details/17733701 1 音视频实时传输 1.1 Jrtplib库介绍 本系统采用开源库Jrtplib进行 ...
- SIP SDP RTSP RTP RTCP webrtc
rfc1889 rfc2326 rfc3261 rfc3550 rfc3856 rfc6120. SIP SDP RTSP RTP RTCP,就像他们出现的顺序一样,他们在实际应用中的启用 ...
随机推荐
- Pyspark的HBaseConverters详解
作者:Syn良子 出处:http://www.cnblogs.com/cssdongl/p/7449682.html 转载请注明出处 最近在折腾pyspark的HbaseConverters,由于资料 ...
- node.js学习系列(一)
node.js 百度百科简介 Node.js 是一个 Javascript 运行环境(runtime).实际上它是对 Google V8 引擎进行了封装.V8 引 擎执行 Javascript 的速 ...
- 堆排序—Java
堆排序: 一棵完全二叉树,如果父节点的值大于等于左右节点的值,则称此完全二叉树为小根堆(小顶堆):如果父节点的值小于等于左右节点的值,则次完全二叉树为大根堆(大顶堆). 堆排序是建立在大顶堆或小顶堆的 ...
- 基于.netstandard的权限控制组件
基于.netstandard的权限控制组件 Intro 由于项目需要,需要在 基于 Asp.net mvc 的 Web 项目框架中做权限的控制,于是才有了这个权限控制组件. 项目基于 .NETStan ...
- node.js后台快速搭建在阿里云(二)(pm2和nginx篇)
前期准备 阿里云服务器 node.js pm2 express nginx linux(推荐教程:鸟哥的私房菜) 简介 嗯……我只是个前端而已 在第一部分说完了express篇. 后面继续项目的部署, ...
- Spring Cloud中负载均衡器概览
在上篇文章中(RestTemplate的逆袭之路,从发送请求到负载均衡)我们完整的分析了RestTemplate的工作过程,在分析的过程中,我们遇到过一个ILoadBalancer接口,这个接口中有一 ...
- 【C++小白成长撸】--(续)单偶数N阶魔方矩阵
1 /*程序的版权和版本声明部分: **Copyright(c) 2016,电子科技大学本科生 **All rights reserved. **文件名:单偶数N阶魔方矩阵 **程序作用:单偶数N阶魔 ...
- 【C++小白成长撸】--(续)双偶数N阶魔阵
原理: 把双偶数N阶魔阵均分为(N/4)^2个4阶魔阵(4*4) 每个魔阵的对角线都标为"-1",其余位置标为"0" 从第一个位置(a[0][0])从左到右,从 ...
- OpenSSL中的大数接口与基于其的自用RSA加密接口设计
本文记录了初次接触OpenSSL中的大数模块,重温了RSA加密流程,使用OpenSSL的接口包装成自用RSA加密接口,并且利用自己的接口演示了Alice与Bob通过RSA加密进行通讯的一个示例. 概览 ...
- Web应用程序的开发步骤
Web应用程序的开发步骤 如今已进入了web2.0高速发展的互联网时代,各种互联网的Web应用程序如雨后春笋般出现.那么作为一名Web开发人员,怎样去开发一款优秀的Web应用程序呢?这个问题没有一个简 ...