低延时直播流媒体传输技术评谈

还是那句话,通用协议保证的是可用性,通用协议从不为特长而生。若目标是制造特长,就不能受限于通用协议的约束。

“低延时“直播流媒体传输,包含特长,若重新设计传输协议,它需要满足:

  • 传输控制分离,单向尽力传输。
  • 无状态编解码,无状态协议。
  • 天然柔性降级,天然无级变速。

上周的文章中提到流媒体传输须在流畅度和清晰度之间做trade-off:
https://zhuanlan.zhihu.com/p/472675631
延时是主动引入buffer的结果,故未加入trade-off。buffer同时利好流畅度和清晰度,延时与流畅度和清晰度均正相关,延时即高清和低卡顿的代价。

但直播场景下,超低延时是刚需,不宜用buffer换流畅度和清晰度时,该如何?

超低延时意味着超小buffer,便必须流畅度清晰度二选一了。

我建议取流畅度而舍清晰度,这带来更好的体验,同时也是直播互动所必须。方法就是柔性降级,即主动降低清晰度,即容忍丢包。

丢包不重传,就不会主动引入额外延时,拥塞排队被动延时可由小buffer平滑,如此事竟成。

可若不知我在说什么,便容易提出以下问题:

  • 说起容易做起难,不是每个包都可以丢的。
  • 不能丢的包丢了不重传,解码解密怎么办?
  • I帧(关键帧)丢了怎么办?
  • 花屏,黑屏,严重马赛克还不如卡顿。
  • 若乱序出现报文空洞,等还是不等?

分别解决这些问题又将陷入泥潭。包括视频编解码在内的流媒体协议,只要有状态,这些问题将无解。

P帧在I帧后才有意义,这就是状态。如果P帧,I帧乱序,或者I帧丢失,传输层必须恢复,如此柔降级性便不易行。

难点在于状态。故假设一个无状态世界,任何报文均可自描述,任何报文虽丢失而不重传,数据单向传输而不求回馈,事情就简易到了极致,buffer是唯一的调杆,无关丢包,无关卡顿:

  • buffer小了,buffer延时小,乱序容忍度低,拥塞排队容忍度低。
  • buffer大了,buffer延时大,乱序容忍度高,拥塞排队容忍度高。

buffer一定,达到buffer延时便不再等,直接解码播放,若乱序报文此后到达,直接丢弃。此过程无关丢包,反正丢包也不重传,这个过程亦无关卡顿,因为不会卡顿,唯一相关的是清晰度,链路丢包率高与清晰度负相关。

若使能拥塞控制,反馈则为必须,但反馈信息中仅体现接收数据包数量信息,万万不掺杂矢量信息,以免再次误入TCP那杂糅的歧途。

然而这个无状态世界毕竟是想象,它如何构建?

仅举一例,抛砖引玉,可做如下尝试:

  • 将时间序列的帧转换成空间序列的包。
  • 随机乱序传输空间序列中的每一个包。
    在这里插入图片描述

每包均包含I帧及其后P帧数据的一部分,只要有足够包到达,便可恢复画面,不会花屏,又由于随机传输,不会局部马赛克,丢包只影响全局清晰度。代价仅是一个I帧到其后最后P帧的帧重组buffer的延时(比I帧~last P帧延时稍微多一点点,时间用于将空间序的包重组成时间序的帧)。

此举将可彻底去除抗抖buffer(Yes,理论上连buffer都不用了!但现实中还是需要极小的可调buffer应对10ms量级的网络抖动,buffer既满,packet能来多少是多少,马上递送packets进行帧重组,然后按当前码率pacing播放)。若此段有长久静默,则可压缩,都静默了,还传输什么数据。

再补充几句。丢包率的高低仅影响像素的密度而不影响均匀度,帧像素的均匀性质使预测丢失像素成为可能且简单易行,平滑曲线勾勒即可:
在这里插入图片描述
此举可用最小代价最大限度弥补丢包损失的清晰度。

有趣吗?有趣。

网络传输本质是有损的,若要无损,须协议自行保证。然而要点是,真的需要无损吗?明确最终目标后,可能并不需要无损。传输并不是目标,什么是?数据的受体说了算。

工人们思维定势非常重,只要网络丢包,似乎非重传不可,工人们会否定这种思维定势,说重传甚至保序也是万不得已,不然呢?有些数据包真的不能丢,丢了流就卡死了!好一个循环论证。

流卡死不正因为协议非要保证可靠传输吗?根源在协议有状态啊!若数据包之间互不依赖,丢包便悄无声息。最终解释权永远在数据的受体,不在协议。

工人们也并非死磕不能丢包,工人们的意思是丢包也要自己丢,感知到网络拥塞了,主动丢几个P帧以图减缓。但这并非真正丢包,丢包是一种链路行为,随机,且不可预测。诸直播传输技术经理都在大肆宣讲这种主动丢包的柔性策略,只可惜这并非真正的柔性,沾边儿,但未竟全功,还差那么几步。

诚然,QUIC已经允许真正丢包:
https://datatracker.ietf.org/doc/html/draft-ietf-quic-datagram-00
但依然不是无状态。你会看到诸如 max_datagram_frame_size 样式的条件参数,但凡有条件,必然有状态。

要理解上述,若总往TCP,QUIC上靠,上述便统统是歪门邪道。WebRTC也依然基于反馈,RTP,RTCP亦如此。传输就是传输,不需反馈。正因TCP在最初时刻让“要让发送端知道接收端已收到”的ACK机制深入了人心,此后这种可靠传输思想才终被围绕。纯粹传输不需反馈,若接收端真需要某个数据包但却没有收到,接收端会主动向发送端索要。(注意此段与NACK的区别。)

抬杠是要抬杠的,谁给了我勇气去批判TCP可靠传输的精义?对于块传输,如文件,实在是不能丢包,但不能丢包的块传输允许乱序传输后重排序,总之依然不是TCP那一套。

文件传输亦可接收丢包,正如手抄和印刷难免失真一般,计算机网络传输亦是一种拷贝的动作,为何就不允许失真的,计算机强调精确无损,实属违背了信息的本质。

TCP在被认为适用于交互传输和块传输,交互传输最初果不其然就是Telnet,需可靠且保序,可块传输必须保序就是强加约束了,我想和当时主机内存受限相关。故TCP只适合Telnet(以及SSH等)等交互式操作。否则,只展现了TCP的可用性。

遗憾的是,QUIC继承了TCP的几乎全部,并加强了它可靠和保序的效率,结局于本末倒置。

上中学时,有一次因为要解一道数学题没回家吃午饭,我最好的朋友不断催促我回家吃饭,理由是“这顿饭不吃,一辈子都补不回来。”,待我把题目解答,已过饭点,就错过了那顿饭,我被朋友的话吓坏了,一直耿耿于怀,我不晓得一辈子补不回来那顿饭意味着什么,我一直很恐慌,总觉得失去了非常重要的东西。过了好多年,我才领悟,过去的饭当然补不过来,可为什么要去补那顿午饭呢?参加工作后,不吃某顿饭是经常的事,也就再没了负担。生活是为了生活,一日三餐从来不是目的。

错把手段当目标并对手段虔诚,工人做工之大忌。我是写C的,是写Go的,我善用扳手,我是抡锤的。

最后,TCP就是无视trade-off的怪胎,想雨露均沾,万万不可能。一切都要trade-off,故再展示下图以示TCP之怪:
在这里插入图片描述

流媒体传输,特别是直播,其复杂性大多数来自于丢包恢复和buffer管理,这实在不可思议。大量复杂的FEC,数据包冗余,ARQ策略出炉,只为应对丢包。跟不少工人,经理都经常聊,聊的最多的也是丢包,重传这些,工人们不能接受数据包就这么丢了,非要重传恢复它不可,可事实上决定能不能丢包的是数据的受体。大部分的复杂来自于不必要,但工人们很难承认这一点,工人们往往以构建复杂系统为己任,我并不认同,所以我表达一下自己的看法,写了本文。

浙江温州皮鞋湿,下雨进水不会胖。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值