全文7732字
包括概要、SRT协议、RIST协议三部分
概要
近些年来,互联网行业出现了几波和音视频相关的热潮:VR、短视频、直播等。除了VR因技术成熟度问题,还在蓄势待发,短视频和直播持续热度不减,以各种方式进入新的行业应用领域。视频直播方向,RTMP仍是最流行的上行传输协议,但RTMP的局限性也越来越凸显:
业界出现了一些新的上行传输方式:SRT、RIST、基于WebRTC的推流、基于fmp4的推流(DASH-IF Live Media Ingest Protocol)等。腾讯云支持SRT协议直播推流,客户反馈相比传统的RTMP,SRT对推流卡顿问题有明显改善[1]。本文重点介绍SRT的功能特性、适用的场景以及后续改进提升的方向,并简要介绍下RIST协议。
SRT协议继承自UDT协议,包括协议设计和代码库。UDT是基于UDP的文件传输协议,最初是针对高带宽、高延迟场景(如远距离光纤传输)设计,用于弥补TCP的不足。关于UDT协议的详细介绍见Experiences in Design and Implementation of a High Performance Transport Protocol, Yunhong Gu, Xinwei Hong, and Robert L. Grossman 2004][2]。Haivision将UDT用于流媒体传输,加入了针对流媒体传输场景的优化特性,如端到端固定延迟等,改造成了SRT协议。SRT协议标准目前还处于草稿阶段[3]。Haivision在2017年开源了libsrt项目[4],并成立SRT联盟,迄今为止已有500多成员。腾讯云是SRT联盟成员之一[5]。
SRT最突出的特性是端到端固定延迟(Fixed end-to-end latency)。一般的传输协议,从一端send()到另一端receive()所占用的时间是波动的,SRT抹平了网络的抖动,可以保证从srt_sendmsg()到srt_recvmsg()的时间基本恒定。srt_sendmsg()给数据打一个时间戳,在接收端检查时间戳,决定什么时候可以把数据交给上层应用。核心思想并不复杂:buffer抗抖动,根据时间戳保持固定延迟。具体实现还考虑了time drift问题。
端到端延迟约等于配置的SRTO_RECVLATENCY + 1/2 RTT0,RTT0是握手阶段计算得到的RTT。配置的latency要足够补偿RTT的波动,同时考虑丢包重传次数。
固定端到端延迟由TSBPD(Timestamp-based packet delivery)开关控制,是否允许丢包由TLPKTDROP(Too late packet drop)控制。前者受后者影响,只有允许丢包,才能保证固定延迟,否则网络情况较差时,到达的数据包会超过配置的延迟。在同时开启TSBPD和TLPKTDROP时,超时的包不再重传,因为根据固定延迟设计,发送过去也会被接收端丢弃。固定延迟意味着要么准时送给上层应用,要么被动或主动丢弃过期的数据包。
传输层的固定延迟可以简化接收端消费者的缓冲设计。以播放器为例,播放器一般有多级缓冲,IO模块内或IO到demux有缓冲,解码后到渲染也有缓冲队列,而核心的缓冲模块一般放在demux后解码前,原因是可以计算缓冲数据的时长。解码后到渲染前也可以计算时长,但解码后的数据量大,不适合缓冲较长时间数据,不能控制缓冲水位。IO模块做到固定延迟缓冲,播放器可以省去IO到demux、demux到解码的缓冲模块,只需要简单的数据管理。多级缓冲设计延迟大,IO模块的缓冲区是整个播放器缓冲的一小部分,丢包恢复能力弱。当把缓冲区交给传输模块管理后,丢包恢复能力增强。
弱网抗性
SRT支持ARQ和FEC两种抗弱网机制。另外,Link bonding中的broadcast模式也能提高数据传输的可靠性。
SRT的ARQ设计同时使用了ACK和NACK两种机制。接收端在两种情况下会发送ACK:
轻量ACK是针对高码率场景考虑的:高码率下,10 ms对应的包太多了,ACK不及时则发送端不能释放已发送的数据。
除了通常的ACK、NACK包之外,SRT还有ACKACK包:
用于测量RTT时,可以把ACK看做ping,ACKACK看成pong。
接收端有两种情况会发送NACK:
周期性NACK可能导致一个包不只一次被重发,另一方面保证了低延迟的特性。
SRT抗随机丢包能力强,但高丢包率场景带宽占用比较高。用FFmpeg做SRT client和server,通过NetEm配置多种丢包率:0%、10%、20%、50%、70%,模拟弱网环境。视频码率约5 Mbps,25 fps。
可以看到,丢包70%的情况下,接收端仍然可以获得稳定的帧率。另一方面,丢包率20%时,带宽占用已经是视频码率的两倍。以上实验数据表征带宽充足时高随机丢包的场景;生产环境还需要考虑更恶劣的情况,即可用带宽不足的场景。
除了固定延迟的特性,抗随机丢包也能起到降低延迟的作用。TCP协议因为拥塞控制,在出现丢包时降低发送速度,且重发比较慢,导致数据在发送端累积,延迟增大。下面是对比高RTT加1%随机丢包场景的延迟。因为用来测试的server端不支持SRT下行,所以只在上行模拟1%丢包。
RTT在250 ms ~ 400 ms,波动较大。
Ping:time=321.291 mstime=291.814 mstime=362.499 ms
首先是RTMP上行加RTMP下行的端到端延迟测试:
可以看到,在视频时间戳1分24秒,延迟在2.3秒左右,而到了2分16秒时,延迟达到16秒。而通过RTMP over SRT,延迟可以稳定在0.5秒左右。
SRT file模式有拥塞控制,live模式只有Pacing控制,没有拥塞控制。但libsrt提供了丰富的统计信息,应用层可以根据统计数据调整视频采集和编码,避免拥塞。从直播系统的实时性角度来说,只做传输层的拥塞控制没法保证系统的低延迟,也不能应对传输带宽始终小于视频码率的极限情况。
SRT的Pacing是根据最大发送带宽来计算发包的时间间隔。最大发送带宽由三种策略确定:
几种配置有优先级,例如配置了max_bw,则忽略input_bw,overhead等配置,组合关系见下图:
Mode / Variable | MAX_BW | INPUT_BW | OVERHEAD |
---|---|---|---|
MAXBW_SET | v | - | - |
INPUTBW_SET | - | v | v |
INPUTBW_ESTIMATED | - | - | v |
注意:live模式SRT的默认配置是max_bw 1Gbps。当应用往SRT写数据的速度不够均匀时,max_bw过高导致Pacing控制起不到效果,瞬间发送大量数据出现丢包率上升问题。理解并合理配置这三个参数非常重要。
SRT支持现状
SRT面向广电领域,需要技术人员手动测试网络条件后再做参数调校。参数配置复杂,缺少自适应特性,难以用一组配置应对多变的网络环境。简化配置 + 自适应策略是SRT的一个优化方向。
例如,当前固定延迟参数latency是以时间单位来配置的。配置latency应当考虑网络的RTT,但RTT是运行时才知道的。如果能以RTT作为单位,配置latency = N * RTT,将大大降低配置难度,适应不同网络条件。
Configure Latency as a Multiple of RTT
Future Improvement
If SRT can estimate RTT from handshakes, then it could configure the effective latency as a multiple of this value, instead of some pre-defined amount of milliseconds. E.g., you could say I want my end-to-end latency be 2×RTT, and after the connection you could find out the actual latency negotiated.
Also something for the future.
详细讨论见:github issue: Negotiated SRT link latency is unknown due to 1/2 RTT addition[6]。
当前缺少拥塞控制,只有简单的配置输入码率、输出带宽上限等方式,在传输带宽小于视频码率、视频码率变化大、网络波动等场景表现不理想。SRT应当具有基本的拥塞控制策略,再与视频编码相结合来应对拥塞。
SRT不限定容器格式,但loss模式依赖容器格式有resync机制,基本只剩下TS一个选项。而TS存在封装层冗余高问题,原因有多方面:固定4字节TS头,padding,固定码率时的空包等。
Lossless模式容器格式有几个选项,除了TS外,还可以使用flv、mkv、fmp4。
RTMP over SRT使得传统基于RTMP的上行SDK 可以无缝迁移。优点是平滑接入现有的RTMP推流系统,但有些地方需要额外注意:
RIST协议2017年提出,至今(2021年)发布了两个profile,2018年发布simple profile[8],2020年发布main profile[9]。
simple profile继承RTP协议,与RTP协议兼容:在RFC 3550 RTP[10]基础上,RIST新增的内容包括:
RIST保留了RTP的组播模式,但因为组播的特殊性,目前只适用于局域受控的网络环境。
在simple profile基础上,main profile新增如下特性:
未来展望
在广电领域,RIST和SRT处于竞争状态;在互联网领域,RIST还有如下问题待解决:
目前,腾讯云已支持SRT上行
扫码可查看相关文档
参考资料
[1] 腾讯云SRT协议推流;
https://cloud.tencent.com/document/product/267/53955
[2] Experiences in Design and Implementation of a High Performance Transport Protocol, Yunhong Gu, Xinwei Hong, and Robert L. Grossman,2004;
https://ieeexplore.ieee.org/document/1392952
[3] SRT标准草案;
https://datatracker.ietf.org/doc/html/draft-sharabayko-srt-01
[4] libsrt开源项目;
https://github.com/Haivision/srt
[5] SRT联盟;
https://www.srtalliance.org/members/
[6] Negotiated SRT link latency is unknown due to 1/2 RTT addition;
https://github.com/Haivision/srt/issues/2016
[7] LIVE mode transport deadlock;
https://github.com/Haivision/srt/issues/1722
[8] RIST simple profile,2020年修订版;
https://vsf.tv/download/technical_recommendations/VSF_TR-06-1_2020_06_25.pdf
[9] RIST main profile;
https://vsf.tv/download/technical_recommendations/VSF_TR-06-2_2021-04-26.pdf
[10] RFC 3550 RTP;
https://datatracker.ietf.org/doc/html/rfc3550
[11] RFC 4585 Extended RTP Profile for Real-time Transport Control Protocol (RTCP)-Based Feedback (RTP/AVPF);
https://datatracker.ietf.org/doc/html/rfc4585
[12] RFC 8086 GRE-in-UDP Encapsulation;
https://datatracker.ietf.org/doc/html/rfc8086