语音通信是实时通信,一定要保证实时性,不然用户体验会很糟糕。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. PHP 字符串替换

    这是2017上半年的第一篇学习笔记,也是最后一篇,捂脸- 在前几天的工作中,关于"银行卡"页面原型如下,其中,不同银行卡的卡号只保留了最后四位数字可以显示,其他数字均用*字符隐藏了 ...

  2. 【Linux】CentOS7无法使用tab补全功能

    公司新项目在云环境上用CentOS7搭服务器的时候,遇见了无法Tab键自动补齐的情况,上网搜了一下,是因为Centos7在使用最小化安装的时候,没有安装自动补全的包,需要自己手动安装. yum ins ...

  3. Android SQLite 简易指北

    Android SQLite SQLite一款开源的, 轻量级的数据库. 以文本文件的形式存储数据. SQLite支持所有标准的关系型数据库特性. SQLite运行时占用内存非常少(约250 KByt ...

  4. grep命令中文手册(info grep翻译)

    body { font: 13.34px helvetica, arial, freesans, clean, sans-serif; color: black; line-height: 1.4em ...

  5. lnmp架构(第一篇)

    lnmp 架构 第一篇 nginx 源码安装 nginx的安装包:nginx-1.12.0.tar.gz 建议安装前的修改: 在nginx的解压包中修改文件nginx-1.12.0/src/core/ ...

  6. 如何使用 Weave 网络?- 每天5分钟玩转 Docker 容器技术(63)

    weave 是 Weaveworks 开发的容器网络解决方案.weave 创建的虚拟网络可以将部署在多个主机上的容器连接起来.对容器来说,weave 就像一个巨大的以太网交换机,所有容器都被接入这个交 ...

  7. [2017-08-21]Abp系列——如何使用Abp插件机制(注册权限、菜单、路由)

    本系列目录:Abp介绍和经验分享-目录 Abp的模块系统支持插件机制,可以在指定目录中放置模块程序集,然后应用程序启动时会搜索该目录,加载其中所有程序集中的模块. 如何使用这套机制进行功能插件化开发? ...

  8. [2012-06-21]结合find的awk

    源起:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=3754423&page=1&extra=#pid221729 ...

  9. MongoDB环境安装

    ---------------------MongoDB安装环境--------------------- 1.MongoDB下载地址:http://www.mongodb.org/downloads ...

  10. poj3723 MST好题 kruskal

    #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> us ...