对于语音通信而言,语音码率较低,添加适当冗余是对抗网络丢包的常见方式。冗余方式有多种,包括REDFEC等都是冗余的一种,如果冗余份数较多,可以采取交织的方式实现。RFC 3350是RTP的基础标准协议,RFC 2198是冗余数据RTP封装的标准协议,RFC 5109是添加FEC数据的RTP封装标准协议。

RTP格式(RFC 3350)

文档地址:RTP: A Transport Protocol for Real-Time Applications

RTP(Real-time Transport Protocol, 实时传输协议)是互联网上常见的处理媒体数据流的网络协议,包括单播和多播等多种场景下的网络环境中媒体数据的传输。RTP是一种应用层协议,一般使用UDP作为底层协议实现数据传输,但并不强制底层协议的选择。RTP不提供任何机制来保证实时的传输和服务质量保证,而是由底层的服务来完成。也就是说,它不保证可靠传输和按序传输,不假定下层网络是否可靠,不限制按照顺序传送数据包。

RTP一般与RTCP同时出现,端口号相邻。一般而言,RTP负责传输数据,RTCP用于传输控制信息,比如提供数据传输质量的反馈。RTCP为每个RTP源提供一个固定的识别符CNAME。当SSRC因重启或者冲突发生改变时,可以更加CNAME跟踪参与者;或者用CNAME关联一系列相关RTP会话中来自同一个成员的多个数据流,如用来同步音频和视频。注意需要控制RTCP流的快速增长,一般不超过总占用带宽的5%。

RTP头格式如下:

 0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

其中,主要字段有:

  • V,version,2比特,RTP版本标识,定义了两个版本。第一个RTP草案版本使用1标识,在vat音频工具的最初实现中使用0标识。
  • P,padding,1比特。如果设定padding,在报文末端会包含一个或多个padding字节,这不属于负载playload。最后一个字节的padding有一个计数器以标识需要忽略多少个padding字节(包括自己)。一些加密算法可能需要固定块长度的padding。
  • X,extension,1比特。如果 X=1,则在 RTP 报头后将有且仅有一个扩展报头。
  • CC,CSRC count,4比特。CSRC count标识了定长头字段中包含的CSRC identifier的数量。
  • M,marker,1比特。由具体协议解释其意义,用来在比特流中标记重要的事件,如音视频帧边界。
  • PT,payload type,7比特。payload type设置RTP负载的格式,由应用程序解释该字段含义。接收方必须忽略未知的playload type数据包。
  • sequence number,16比特。序列号,每发送一个RTP数据包,序列号加1,接收端可以据此检测丢包和重建包序列。
  • timestamp,32比特。时间戳,反映了RTP数据包中第一个八位字节的采样时间。时间戳的初始值应当是随机的,类似序号。时钟频率依赖于负载数据格式,因此时间戳增量依赖于当前数据格式和策略。如果RTP数据包周期性产生,那么将使用采样时钟确定的标称采样时刻,而非读取系统时间。举例而言,对于固定采样率的音频,时间戳时钟可能会在每个采样周期增加1;如果音频应用程序从输入设备读取覆盖160个采样周期的块,则对于每个这样的块,时间戳将增加160,无论该块是在分组中传输还是作为静默丢弃。
  • SSRC,Synchronization source,32比特。同步源,接收方可以将一个同步源的包放在一起进行重放。SSRC是一个随机值,在特定的RTP会话中是全局唯一的。
  • CSRC,Contributing source,0~15项,32比特。若一个 RTP 流的源,对由 RTP 混频器生成的组合流起了作用,则它就是一个作用源。

RED格式(RFC 2198)

文档地址:RTP Payload for Redundant Audio Data

RTP本身不包含任何的质量保证,因此面对网络扰动时表现较差,因此在通信过程中增加冗余数据,即使存在丢包,也可以在一定程度上恢复。RFC 2198主要针对音频数据。

  1. 每个包必须携带一个主包(主编码数据),以及一个或多个冗余编码数据;
  2. 冗余信息可以有多种形式,但每一个冗余块必须有一个编码类型标识;
  3. 可能存在变长编码,因此每一个数据块都存在长度标识;
  4. 每个编码块都有自己的时间戳,对于冗余块可以参考与主包的时间戳差值。

增加RTP头扩展或采用新的一个或多个负载类型,即使用PT标识。鉴于使用扩展头会带来很多限制,因此建议采取新增负载类型的方式。在RTP中,冗余头格式如下:

 0                   1                    2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F| block PT | timestamp offset | block length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

其中:

  • F,1比特,标识后面是否还存在其它的块。设置为1表示存在;0表示不存在,该块为最后的头块。
  • block PT,7比特,该数据块的RTP playload type。
  • timestamp offset,14比特,相对于RTP header中时间戳的偏移量,使用unsigned表示。
  • block length,10比特,对应于除了头长度的有效负载长度。

主包头位于整个数据包的最后,PTtimestamp和RTP数据包头相同,格式如下:

0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|0| Block PT |
+-+-+-+-+-+-+-+-+

最后一个头之后就是数据块,存储顺序和头的排序顺序相同。数据块之间不需要填充或者使用其它分隔,一般不需要32位对齐。主要是为了在损失一定的解码时间降低宽带负担。如下包括一个DIV4(8kHz)主包和8kHz的LPC冗余编码包:

0                   1                    2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC=0 |M| PT | sequence number of primary |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp of primary encoding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1| block PT=7 | timestamp offset | block length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0| block PT=5 | |
+-+-+-+-+-+-+-+-+ +
| |
+ LPC encoded redundant data (PT=7) +
| (14 bytes) |
+ +---------------+
| | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
| |
+ +
| |
+ +
| |
+ +
| DVI4 encoded primary data (PT=5) |
+ (84 bytes, not to scale) +
/ /
+ +
| |
+ +
| |
+ +---------------+
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

RED SDP协商

在进行双方的通信协商时,需要通知双方的SDP(Session Description Protocol,会话描述协议)完成信息交互,协议中建议的SDP形式如下:

m=audio 12345 RTP/AVP 121 0 5
a=rtpmap:121 red/8000/1
a=fmtp:121 0/5

其中,121为冗余编码的PT值,0为PCM主编码,5为DVI4第二编码。

一般FEC的RTP格式(RFC 2733)

文档地址:An RTP Payload Format for Generic Forward Error Correction

在网络上,语音质量不佳的主要原因在于高丢包率。也正是基于此,FEC才被考虑解决丢包的问题,为了更好的应用这些纠错码,必须有相关的协议支持。

前置知识

FEC(Forward Error Correction,前向纠错)可以确保信号的长距可靠传输。FEC技术是一种广泛应用于通信系统的编码技术。以典型的分组码为例,在发送端通过将k比特信息作为分组进行编码,加入(n-k)比特的冗余校验信息,组成长度为n比特的码字。码字通过信道到达接收端之后,如果错误在可纠正的范围之内,通过译码就可检查并纠正错误的比特,从而抵抗信道带来的干扰,提高通信的可靠性。校验位长度(n-k)与信息位长度k的比值,称为编码开销。开销越大,FEC的理论极限性能越高,但性能的提高并不是线性增加的,开销越大,增加的性能提升就越小。

RFC 2733

RFC 2733定义了一种传输实时媒体的一般性的RTP负载格式,一般性意味着:

  1. FEC协议独立于其保护的媒体数据,该媒体数据可以是音频、视频或者其它;
  2. 具有足够的灵活性以支持不同的FEC机制;
  3. 自适应设计,使得FEC技术修改但不影响传输的信令;
  4. 支持许多不同的传输FEC包机制。
基本原理

RFC 2733负载格式支持基于异或校验算法的FEC机制。发送端在媒体流中取出一些包,并对其负载、RTC头中的组件进行异或操作,得到包含FEC信息的RTP包,产生的FEC包可以在接收端恢复与这个FEC包关联的任何一个包。实际使用中,是时延以及恢复能力之间的一种平衡。

为了能正常恢复,发送方还需要在负载格式中携带信息,包括哪些媒体包用来生成FEC包。接收端可以不了解纠错码的细节,使用FEC,发送端具有较大的灵活性并可根据网络环境进行自适应的编码,而接收端仍能正常恢复。FEC包在生成后立即发出,接收端即使不支持FEC也不影响媒体流的正常接收。但是也存在一些FEC纠错码,不传输原始媒体流,只使用FEC流,这样做的缺点在于所有接收者都必须支持FEC。

FEC包可以不与媒体包在同一个RTP流中发送,以一个单独的流进行发送,或者作为以各种冗余编码发送(如RFC 2198)。当作为单独流发送时,FEC包具有独立的序列号空间,但时间戳从对应的媒体包获得,单调递增。FEC包流支持任何固定差值的包头压缩机制,对接收端来说,如果没有丢包,则忽略FEC包,如果出现丢包,则FEC联合收到的关联生成的媒体包组,完全恢复丢失媒体包。

通用FEC方案

定义函数\(f(x,y,...)\)对包\(x,y,...\)等的异或操作,被叫做奇偶校验包。为简单起见,奇偶校验包就是输入的各个输入包按位异或得到的,而使用奇偶校验包对数据包进行恢复是通过产生这些校验包的一组数据包完成,这一组数据包必须是线性无关的。

举例而言,若两个数据包产生一个校验包。原始数据包\(a,b,c,d\),发送端产生数据包如下,时间从左至右:

   a        b        c        d               <-- media stream
f(a,b) f(c,d) <-- FEC stream

如果数据包\(b\)丢失,则可以通过\(a\)和\(f(a,b)\)恢复。

  • 方案一

       a        b        c        d        e        <-- media stream
    f(a,b) f(b,c) f(c,d) f(d,e) <-- FEC stream

    方案一类似于上面的示例。但是在发送数据包\(b\)之前发送\(f(a,b)\)。该方案会增加发送端延迟,但允许对连续两个数据包突发丢失的恢复。

  • 方案二

       f(a,b)  f(a,c)  f(a,b,c)  f(c,d)  f(c,e)  f(c,d,e)  <-- FEC stream

    原始数据包并不是必传的,在方案二中仅仅发送FEC数据包。该方案允许所有单数据包和一些连续数据包的丢失恢复,但开销略低于方案一。

  • 方案三

       a         b          c                    d     <-- media stream
    f(a,b,c) f(a,c,d) f(a,b,d) <-- FEC stream

    该方案允许从连续一个、两个或三个数据包丢失中恢复。

通用FEC的RTP格式

如果FEC作为独立流发送,媒体数据包格式与传输不受影响;如果作为冗余编码发送,参考RFC 2198将媒体数据作为主数据包,次编码传输FEC包。

通过在RTP负载中放置FEC头和FEC有效载荷来构造FEC包:

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| RTP Header |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| FEC Header |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| FEC Payload |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

音视频 RED 与 FEC 的 RTP 格式封装

音视频RTP数据包封装的更多相关文章

  1. TCP/IP协议栈与数据包封装+TCP与UDP区别

    ISO制定的OSI参考模型的过于庞大.复杂招致了许多批评.与此对照,由技术人员自己开发的TCP/IP协议栈获得了更为广泛的应用.如图2-1所示,是TCP/IP参考模型和OSI参考模型的对比示意图. T ...

  2. 音视频处理之PS封装的介绍与使用20180928

    1.PS封装介绍MPEG2-PS是一种多路复用数字音频,视频等的封装容器.PS是Program Stream(程序流或节目流)的简称.程序流将一个或多个分组但有共同的时间基准的基本数据流(PES)合并 ...

  3. 各种RTMP直播流播放权限_音视频_数据花屏_问题检测与分析工具EasyRTMPClient

    之前的一篇博客<网络摄像机IPCamera RTSP直播播放网络/权限/音视频数据/花屏问题检测与分析助手EasyRTSPClient>,我们介绍了RTSP流的检测和分析工具EasyRTS ...

  4. 音视频处理之FFmpeg封装格式20180510

    一.FFMPEG的封装格式转换器(无编解码) 1.封装格式转换 所谓的封装格式转换,就是在AVI,FLV,MKV,MP4这些格式之间转换(对应.avi,.flv,.mkv,.mp4文件). 需要注意的 ...

  5. linux TCP数据包封装在SKB的过程分析

    在linux中 tcp的数据包的封装是在函数tcp_sendmsg开始的,在函数tcp_sendmsg中用到skb = sk_stream_alloc_skb(sk, select_size(sk, ...

  6. OSI互联数据包封装与解封装过程

    当我们在七层协议最上层,主机A想和其它主机通信, 比如telnet到主机B,各层都为数据打包后再封装上自己能识别的数据标签,现在我们只说四层以下的通信过程. .当一个高层的数据包到达传输层,由于tel ...

  7. EasyPusher RTSP直播之RTP数据包格式解析

    -本篇由团队成员Fantasy供稿! RTP包头格式 码流总体结构 h264的功能分为两层,视频编码层(VCL)和网络提取层(NAL).H.264 的编码视频序列包括一系列的NAL 单元,每个NAL ...

  8. Android IOS WebRTC 音视频开发总结(八十六)-- WebRTC中RTP/RTCP协议实现分析

    本文主要介绍WebRTC中的RTP/RTCP协议,作者:weizhenwei ,文章最早发表在编风网,微信ID:befoio 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID ...

  9. Android IOS WebRTC 音视频开发总结(八十七)-- WebRTC中丢包重传NACK实现分析

    本文主要介绍WebRTC中丢包重传NACK的实现,作者:weizhenwei ,文章最早发表在编风网,微信ID:befoio 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID ...

随机推荐

  1. Devexpress TextAnnotation

    private void BindData() { chartControl1.AnnotationRepository.Clear(); chartControl1.Series.Clear(); ...

  2. vijos1059 积木城堡[n年浙江省队第X轮](背包的方案总数 or 01背包)

    描述 XC的儿子小XC最喜欢玩的游戏用积木垒漂亮的城堡.城堡是用一些立方体的积木垒成的,城堡的每一层是一块积木.小XC是一个比他爸爸XC还聪明的孩子,他发现垒城堡的时候,如果下面的积木比上面的积木大, ...

  3. scandir 使用示例

    int filter_fn(const struct dirent * ent) {     if (ent->d_type != DT_REG)         return 0;     r ...

  4. WPF制作子窗体的弹出动画效果

    创建一个WPF应用程序WpfApplication1,新建个窗体DialogWin <Windowx:Class="WpfApplication1.DialogWin" xm ...

  5. 尝试跑一跑Scut

    前段时间都在用 IIS+WCF+Redis+MSSQL 的框架做服务器,前段时间看到了 Scut 的开源框架,整个架构还是蛮干净整洁的... 今天抓来跑一跑. 按照教程安装好所有的环境,版本是6.7. ...

  6. WebApp 里Meta标签大全

    1.先说说mate标签里的viewport: viewport即可视区域,对于桌面浏览器而言,viewport指的就是除去所有工具栏.状态栏.滚动条等等之后用于看网页的区域.对于传统WEB页面来说,9 ...

  7. 循环神经(LSTM)网络学习总结

    摘要: 1.算法概述 2.算法要点与推导 3.算法特性及优缺点 4.注意事项 5.实现和具体例子 6.适用场合 内容: 1.算法概述 长短期记忆网络(Long Short Term Memory ne ...

  8. linux之间免密操作

    为了方便分布式集群操作,主机master需要免密操作两个节点slave1和slave2(slave1和slave2在对应机器已经修改hosts文件) 操作步骤: 首先测试连接slave1操作: [ro ...

  9. python创建数组的方法

    一 直接定义法: 1.直接定义 matrix=[0,1,2,3] 2.间接定义 matrix=[0 for i in range(4)] print(matrix) 二 Numpy方法: Numpy内 ...

  10. Java虚拟机-JVM各种参数配置大全详细

      usr/local/jdk/bin/java -Dresin.home=/usr/local/resin -server -Xms1800M -Xmx1800M -Xmn300M -Xss512K ...