专栏首页音视频技术拆解SRT:新UDP视频传输协议

拆解SRT:新UDP视频传输协议

本文来自Twitch视频工程师Alex Converse在San Francisco Video Technology Meetup 2019 的分享。其分享集中于SRT协议的起源,以及如何在颇具挑战的网络上基于UDP传输实时视频。讲师也介绍了UDT、open source、SRT联盟和SRT的技术概述,最后分析了SRT数据包、SRT数据包缓冲区和Nak数据包如何容忍packet loss及处理延迟这些问题。

文 / Alex Converse

译 / Adrian Ng

大家好,我是Twitch的视频工程师,今晚我的演讲主题是SRT协议的内幕。在过去,我看过许多关于支持SRT功能的软解的精彩演讲以及它的各种潜能。但是今天,我将掀开幕布,看看SRT协议背后的东西。

此SRT(Secure Reliable Transport)非彼SRT(SubRip Subtitle:它是一种字幕格式),这个视频传输协议可以在具有挑战性的网络之下进行直播。它基于UDP的单播(一对一的形式),注重contribution而不是delivery。此外,它也带来亚秒可调的constant latency。

这么说吧,可调(tunable)意味着你可以配置协议并调整延迟,可以在数据包的丢失与延迟中做出权衡(trade-off)。一旦开始广播的时候,延迟即被锁定,所以不会因为不同的网络的情况而累积更多的延迟,同时,该系统也提供content encryption。

为什么我觉得SRT有趣?我们知道RTMP是公共互联网上直播视频的事实标准;但RTMP已经存在了很长一段时间,其标准在2012年最后一次更新过后就被放弃了。新的Codec标准诸如HEVC或AV1一般都没有RTMP标准支持。退一步来说,即使有人在RTMP中hack了这些Codec的支持,在移动网络上RTMP仍然工作的不大好。

SRT作为RTMP潜在替换技术的一种,最近正获得不错的增长势头。SRT联盟现在有250多名成员,而在最近的一些展会上,似乎每个展位都具有 SRT 联盟成员或 SRT-Ready贴纸。

SRT功能在VLC,Gstreamer和Ffmpeg中基本开箱即用,对于 OBS Studio 等工具则有些patches正在流程中。SRT 的源于一个称为 UDT 的旧协议。UDT在2001年创建,仍然在Source Forge上有网页,但UDT的设计目标是在公共网络上以最短时间传输大型的文件。

UDT开发者向IETF提交过几份草案去描述UDT工作原理。总共有四份草案,最终的IETF草案是在2010年发布的。之后,UDT的主要开发者继续在此协议工作了3年,其实现的最终版本停留在了2013年。

Haivision,一家编码器供应商,采用UDT且将它由file protocol变成一个live video协议。在2013年,他们首次在 IBC大会上使用了UDT,主要是为了演示HEVC的编码器。

过了四年,他们觉得自己的自定义协议可能不是创建interoperable ecosystem的最好方式。因此在2017年,他们开源了SRT。

Haivision 与Wowza 联合创建了SRT联盟,以促进发展及开发SRT。

2018年初,他们发布了SRT的v1.3.0更新版本。这是自最初的开源以来,对protocol最大型的修改。同时,其版权协议改成了MPL(Mozilla public license);重新把文件传输模式加了回来。

在2018年,他们也发布了SRT Technical Overview(SRT技术概述),但实际上更像规范(specification)。该文档共有89页,与此对应的RTMP Spec则是52页。该文档描述了各种细节信息,即使是一些竞争对手也承认SRT规范做得非常不错。

从高层看,SRT使用的一个双向UDP socket,它可以通过同一个socket复用数据和控制流。因为没有使用TCP,SRT自行实现了可靠性、有序性和拥塞控制。SRT使用 selective retransmit的方式处理数据包丢失,另外了基于标准加密原语(standard primitives)(而不是DTLS)构建了其独特的 “unique”加密系统,

SRT Data Payload支持可分片的有效负载(payload)。在实践中,我仅仅看过它与MPEG transport stream一起使用。整个传输流引入SRT包,每个传输流包都有自己的同步字节和传输流头。我确信这些sync byte 用以对抗丢包以及重新同步。

在1500-byte Ethernet MTU情况下,如果你试图放入188-byte的数据包,会发现并没有足够的空间可以容纳8个TS包,这也是使用7个TS包的原因。与此同时,这也可以给SRT Header留出足够的空间。

上图概述了SRT数据包的布局。初起是UDP header, 还有UDT header,实际上SRT header改自UDT header。

第一bit是0,表示的是数据包,之后是packet sequence number,它是从握手过程中确定的random value开始的,随后每一个packet值都会增加1。该值用于标识数据包、packet acknowledgement和数据包丢失消息。有个message number, message number从0算起,会在我的视频中每增加一条消息时候加一,但看起来没什么用,怎么回事呢?

我们可以看见一个微秒单位的时间戳,这是发送端的运行时间(elapsed time)。在接收端,它将这个packet从SRT的缓冲区中播放到下游的TST MUX RN 视频解码器中。这个实时视频的片段与顺序总会是“1 1 0”。1 1 指的的是独立编号,而消息编号是针对跨多个数据包分段的信息。但在实时视频模式下,我们只需要尽可能多地填充TS,我们称之为standalone message。

Ordering flag下的两个标志是encryption和retransmission flags;如果出现了什么问题,ordering flag可以将其信息无序交付。Encryption flag会提醒你正使用的key,而retransmit flag会告诉你这是否是第一次发送还是一个重复的步骤。Retransmitted packets 通常会保留原始序列号,原始信息号和原始时间戳。

SRT的核心理念是发送方和接收方都同意延迟缓冲时间,并且他们试图在数据包开始流出接收方时同步其内容。目前VLC支持现成的SRT,OBS也有了SRT的patch,发送方所创建的数据包,同时会将其放在延迟缓冲区,因为在网络中,该包到达接收方需要一段时间。

发送方不断生成数据包,接收方最终获得数据包。发送方再不断地生成,接收方也继续接收。如此往复。

这里展示了一个不妙的情况,上图的packet 3已被丢失,到目前为止,没人发现了数据的差错。本来期待packet 3,竟然收取了packet 4,它随即生成negative acknowledgement packet,将packet 4 放入缓冲区,为packet 3 留下一个空位(hole)。

发送方继续分发packet,直到下一个packet送达。突然间sender得到NACK,它发现接受者丢失了packet 3,因为它把之前发送的数据包都保存在了buffer,结果,发送方重新发送数据包3,它继续生成数据包;接收方继续接收数据包。注意,此时发送者的buffer现在已装满了数据包。

Packet 1被吐出,直接被丢掉。接收端终于收取到packet 3,它马上填补之前的空洞(hole),操作恢复正常。接收端buffer最终填满了指定的packet,随后把packet 1给了 TS deuxers 和解码器。

这是协议概述中Nak的表示图。首先有SRT header,因为它是一个控制包所以1开头,最后是丢失包的列表。

每一个丢失list包含一个或多个条目。每个条目要么是一个single packet,要么是一个范围(range),你可在一条消息内说丢失了packet 5、9以及11直到15的所有包。

除了negative acknowledgment,SRT也有positive acknowledgment。接收器每10毫秒发送一次acknowledgment。每一次收到 ACK,发送者立即确认ACK以响应之前的ACK,你可以据此估算往返时间。如果确认之间的数据速率超过64个数据包,则接收器将发送lightweight acknowledgement。此Ack不会被重新确认,也不包含Ack所接受的元数据类型。

RTT有点不寻常,因为似乎没有办法在不启动新广播的情况下调整延迟缓冲区的大小,所以对于广播场景有些限制。

以上是acknowledgement packet所显示的Ack/AckAck包。最重要的是最后接收到的packet包序列号,当然还有的是往返时间,往返时间的方差,缓冲统计available size和packets,数据包接受速率及数据接收速率。在lightweight Ack,你只需得到序列号,Ack的acknowledgment将会显示它正在确认的Ack,以便于你知道在正确的时间戳做出扣除。

我们都知道握手(handshake)非常简单。在这个GIF中,Bill Maher 不断地误读Snoop Dogg (史努比.狗狗)的手势,Snoop Dogg也不断地尝试配合Bill,这场景是body language misinterpretation的一个例子,我认为它适合隐喻SRT handshake的过程。

SRT在sender和receiver之间有四次handshakes(因为后向兼容,所以所有版本都支持)。V4 和V5的rendezvous handshake (汇合握手)比较特殊,不在这次讲解。

V5 以及v4最大的区别在于数据包交换的数量。v4共有四次往返;在v5只有两次往返。

图中是packets的布局,其核心思想是左边的v4使用了未修改的UDT包加上SRT扩展,接着是一个包含所需延迟和初始序列号的SRT握手包,其后的密钥素材用于对于数据有效载荷进行加密,右边的v5则更将这些信息smush (合拼) 到一个包中(指V5直接修改了原始UDT包的布局)。

之后,我们将看到两方尝试v5握手,发起方创建handshake induction packet (握手感应包)。

其版本号设置为4,但cookie字段并未设置,它将提示初始端在短时间内获得cookie,使得响应端不必处理混乱的数据包,而是需要解析其数据包以将某些内容发送回去;实际上,响应端接收到该包之后,创建一个版本5的induction packet,并设置Cookie。

此时,v4 initiator将忽略v5,并继续填充v4以及重复改cookie。但是,如果initiator是通过v5运行,所以它会在version字段中填写 v5程序,加上SRT handshake extension values包括延迟值等。

Initiator可能在握手的第二个包产生stream ID,首先填充加密握手,然后responder会使用latency value 和cyypto handshake进行响应。

在于Stream ID,这是在handshake的第二个包中所发送的可选标识符,因为第一个包是有可能被抛弃掉的。在此会有个application-specific parameter,用于通知你initiator想干什么。

这与RTMP形成一些对比,在RTMP中,你执行TCP握手和RTMP握手。然后,执行带宽估计之后调用一组RPCs来设置RTMP媒体流。

我之前提到过SRT不使用DTLS。它以自定义方式使用industry standard primitives,可看见它受到到了DVB scrambling的重大影响。DVB是欧洲广播标准,keying material是由共享密码短语生成。随着这些retransmits和密钥旋转,一次有两个密钥有效。你有一个偶数键和一个奇数键,在这两个键中你交替使用哪一个,你就在更新。如果你得到重发,你可以参考旧的密钥。

规范中的小注释说:‘嘿,全数据包加密看起来是最安全的选择,但实际上,加密header在暴力破解时候却有点脆弱。最初的MPEG TS 同步字节,其设计可能是不让你把TS头加密。事实上,我们会尝试使用快速的key rotation来获得更高的加密强度。

你可以使用Wireshark 来分析包,我们会有个加密数据包,有效载荷的第一个字节是12(十六进制)。你可能已知道如果是一个未加密的TS 同步字节,那它将是47(十六进制)。

如果想进一步了解其中的协议,你可以前往SRT GitHub repository,以及technical overview Wireshark的SRT解析器。

如果你想了解更多关于SRT生态系统,或者有关于SRT的产品或信息请前往srtalliance.org。

本文分享自微信公众号 - LiveVideoStack(livevideostack),作者:Alex Converse

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 8个关于SRT的误区

    原文 / https://www.haivision.com/blog/all/8-common-srt-myths-busted/

    LiveVideoStack
  • SRT在B站的落地

    大家好,我是来自哔哩哔哩的郑龙,2012年至2017年我在广播电视行业从事工作,2017年我转型至互联网行业并加入了哔哩哔哩的视频云团队。在视频云团队的三年里,...

    LiveVideoStack
  • 张贤国:视频压缩还远没有达到最优

    LiveVideoStack:张贤国你好,恭喜V265在MSU视频编码大赛取得“客观评分”两项第一、一项第二的成绩。能聊聊过去一段时间V265团队做了哪些工作吗...

    LiveVideoStack
  • Linux和Windows下ping的区别

    Ping 是Windows自带的一个DOS命令。利用它可以检查网络是否能够连通,用好它可以很好地帮助我们分析判定网络故障。该命令可以加许多参数使用,键入Ping...

    用户7656790
  • TCP三次握手详解:传输控制块TCB以及积极和消极的连接建立方式

    TCP协议目的是为了保证数据能在两端准确连续的流动,可以想象两个建立起TCP通道的设备就如同接起了一根水管,数据就是水管中的水由一头流向另一头。然而TCP为了能...

    望月从良
  • 两天研习Python基础(六)控制结构

    [1]Python文档 - 真值检验: https://docs.python.org/3/library/stdtypes.html#truth

    王诗翔呀
  • 德州农工大学开源RLCard:帮你快速训练会斗地主的智能体

    RLCard 是一个用于牌类游戏强化学习研究的开源工具包,其接口简单易用,支持多种牌类环境。RLCard 的目标是在强化学习与非完美信息博弈之间搭建桥梁,推动强...

    机器之心
  • Leetcode 258. 各位相加

    解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。

    zhipingChen
  • Ubuntu 16.04无法切换root权限问题的解决

    在su root时发现无法切换到root权限.显示: /usr/local/bin/zsh 没有文件或目录

    砸漏
  • 全链路适配SRT,腾讯云直播平台再升级

    在今年10-11月份刚过去的英雄联盟S9总决赛中,SRT作为跨洋远距离传输方案,在源流制作环节中承担主线路的角色,稳定支持了总决赛的每一场比赛。目前腾讯视频云已...

    腾讯云视频

扫码关注云+社区

领取腾讯云代金券