语音通信是实时通信,一定要保证实时性,不然用户体验会很糟糕。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及软件实现关键点的更多相关文章

  1. 视频流传输协议RTP/RTCP/RTSP/HTTP的区别 (转)

    用一句简单的话总结:RTSP发起/终结流媒体.RTP传输流媒体数据 .RTCP对RTP进行控制,同步.之所以以前对这几个有点分不清,是因为CTC标准里没有对RTCP进行要求,因此在标准RTSP的代码中 ...

  2. 【转载】 IP实时传输协议RTP/RTCP详解

    http://www.chinaitlab.com/cisco/RIP/832426.html 1.简介 目前,在IP网络中实现实时语音.视频通信和应用已经成为网络应用的一个主流技术和发展方向,本文详 ...

  3. IP实时传输协议RTP/RTCP详解

    1.简介 目前,在IP网络中实现实时语音.视频通信和应用已经成为网络应用的一个主流技术和发展方向,本文详细介绍IP协议族中用于实时语音.视频数据传输的标准协议RTP( Real-time Transp ...

  4. TCP、UDP、RTP(RTCP)异同与区别

    OSI七层模型OSI 中的层            功能                                                        TCP/IP协议族 应 用层   ...

  5. 【转】TCP、UDP、RTP(RTCP)区别

    转自:https://www.cnblogs.com/imystr/p/4026639.html OSI七层模型OSI 中的层            功能                        ...

  6. RTP/RTCP、TCP、UDP、RTMP、RTSP

    OSI中的层 功能 TCP/IP协议族 应用层 文件传输,电子邮件,文件服务,虚拟终端 TFTP,FTP,HTTP,SNMP,SMTP,DNS,RIP,Telnet 表示层 数据格式化,代码转换,数据 ...

  7. 流媒体传输协议(rtp/rtcp/rtsp/rtmp/mms/hls)转

    常用的流媒体协议主要有HTTP渐进下载和基于RTSP/RTP的实时流媒体协议两类.在流式传输的实现方案中,一般采用HTTP/TCP来传输控制信息,而用RTP/UDP来传输实时多媒体数据. 1 实时传输 ...

  8. RTP RTCP在音视频传输与同步方面的使用

    转自:http://blog.csdn.net/kof98765/article/details/17733701 1 音视频实时传输 1.1 Jrtplib库介绍 本系统采用开源库Jrtplib进行 ...

  9. SIP SDP RTSP RTP RTCP webrtc

    rfc1889  rfc2326  rfc3261  rfc3550  rfc3856  rfc6120. SIP SDP RTSP  RTP RTCP,就像他们出现的顺序一样,他们在实际应用中的启用 ...

随机推荐

  1. spring的Java配置入门(Spring Boot学习笔记之一)

    spring的Java配置 1.创建maven项目 使用idea创建maven项目,这里顺便提一下,idea真的比eclipse好用,早点熟悉吧.然后就是maven是java项目管理最主流的工具,自己 ...

  2. atoi()函数(转载)

    atoi()函数 原型:int  atoi (const  char  *nptr) 用法:#include  <stdlib.h> 功能:将字符串转换成整型数:atoi()会扫描参数np ...

  3. prop解决一个checkbox选中后再次选中失效的问题

    //问题点 初始状态复选框没有全选, 点击全选按钮调用checkAll方法, 实现了全选, 然后点击全不选按钮, 实现了全不选, 然后再次点击全选按钮, 结果却木有全选, 再反复点击木有任何反应. d ...

  4. jmeter+ant+jenkins 搭建接口自动化测试

    一.jmeter  我用的jmeter3.2   jmeter要运行,必须本地有java环境,所以需要配置jdk什么的,自行配置 二.ant 安装ant 第一步:下载ant  http://ant.a ...

  5. 移动端车牌识别ocr系统

    移动端车牌识别ocr系统优点: 1.识别速度快:高度优化的车牌定位和识别算法,识别时间≤50毫秒(200万图片). 2.识别率:白天识别率≥99.7%:夜间识别率≥98%. 3.识别速度:单张图片识别 ...

  6. JAVA定时任务实现的几种方式

    近日项目开发中需要执行一些定时任务,比如需要在每天凌晨时候,分析一次前一天的日志信息,借此机会整理了一下定时任务的几种实现方式,由于项目采用spring框架,所以我都将结合spring框架来介绍. 一 ...

  7. String.equals()方法

    public boolean equals(Object anObject) {     if (this == anObject) {         return true;     }      ...

  8. Java环境的搭建

    一.JDK的下载 JDK又称Java SE,可以从Oracle公司的官网上https://www.oracle.com/index.html下载. 1.打开Oracle官网.将光标移到[Menu]-[ ...

  9. R0~R16寄存器作用(转)

    R0-R3     用作传入函数参数,传出函数返回值.在子程序调用之间,可以将 r0-r3 用于任何用途. 被调用函数在返回之前不必恢复 r0-r3.如果调用函数需要再次使用 r0-r3 的内容,则它 ...

  10. css入门基础知识

    一.CSS常用选择器 /*CSS注释*/ /*CSS修改页面中的所有标签必须借助选择器选中. 选择器中可以写多对CSS属性:每个属性名与属性值之间用:分隔,多对属性之间,必须用;分隔 选择器{ 属性1 ...