我们来到了一个新世纪,属于音视频的世纪,很高兴大家选对了方向,站在了音视频的风口上。移动网络的快速发展,音视频必然成为更方便快捷的沟通方式。就像十几年前的互联网,有一天,音视频也会成为一项基础服务,极大地改变我们的生活方式。
自我介绍一下吧,我叫伍倡辉,07年入职腾讯,做过大数据分析、两人音视频系统、多人音视频系统、PSTN以及直播系统,目前为直播系统总架构师。这次主要分享腾讯在做音视频时的一些相关技术,不是炫耀腾讯技术多牛逼,而是来相互学习,打造行业技术氛围。
独立日2里,男女主角用QQ实现地月通话,且不说植入广告是否欠维和,QQ能上好莱坞大片,我个人还是觉得很自豪的。为什么QQ音视频能上月?有人说这个是通信商解决的问题,只要网络通了就行,其实还真跟音视频技术有一些关系,比如距离远了之后,时延、丢包率都会大很多,怎么处理好是有挑战的。这些都是我们自己心里YY,现在来看看做2人音视频都需要哪些技术吧。
电影里的场景,就是男主角要跟女友视频聊天。
从技术层面表达,就是把上行方摄像头里实时采集的画面,一帧一帧传到对方,在显示器上展示,再把上行方麦克风里的声波,采集传到对方,在外放或耳机里播放。事情听起来很简单,我们来看看腾讯都做了啥。
这是腾讯两人音视频的基本架构,其中任何一块,都可以作为一个课题,深入研究。
视频,我们可以采集摄像头、屏幕等画面,做降噪、缩放等前处理,进入编码。音频可以通过麦克风、或HOOK系统获取系统声音,等等,做降噪、回声抵消、自动增益等前处理,进入编码。编码最主要的算法就是DCT变换,损失掉一些人感知弱的部分,然后经过网络传输。网络传输主要有直连打洞、中转、路由管理等模块。下行客户端主要就是上行客户端的逆过程。
腾讯2人音视频,每天传输量约1P左右。为了方便直观的感受一下,如果是DVD,估计需要21万张来存储。
所以,我们首先要考虑的是压缩传输。就是用编码器来将原始数据压缩,例如H264、silk等等,这些都是压缩算法。压缩算法本身,我们并没有深入研究,这些在一些专门做编解码算法公司里面,已经快做到极致了,我们主要是对其中的参数做一些适配,作一些优缺点互补。
即使压缩传输,一路视频也需要几百k或几兆流量。我们服务器带宽成本,为几万1G,成本很高,所以必须考虑直连。WebRTC里面的直连打洞做得已经很不错了。腾讯的打洞过程也是参考的WebRTC,做了一些小优化,例如用户和就近同运营商的打洞服务器相连,打洞服务器双机走专线提供服务,可以让用户连接打洞服务器的成功率更高。
大家都知道,NAT并不能都成功,或者直连成功了,直连网络也可能很差。因此必须要有中转,那就涉及到多通道的管理上了。腾讯有直连、单中转、双中转、动态路由等通道,能通过历史情况自我学习,再配合现有具体情况灵活控制。
中转机器部署会很广泛,机器量非常庞大,必然涉及到海量集群的机器管理。我们不能全依赖人工解决所有服务器问题,要考虑容灾、柔性、灰度发布、负载均衡、就近调度等等。
用户的网络,什么情况都有,不是我们能控制的。怎么样才能合理的,尽可能的利用用户带宽,就涉及到带宽预测。
即使带宽曲线模拟得再好,不代表网络不丢包。为了减少延时,我们音视频传输用的都是UDP,丢包不能影响音视频使用,所以怎么抗丢包而由延时小就显得很关键。
前两项,业界有很多文章,技术也都比较成熟,这里就不细讲。第三项,是一些慢工细活,暂时不讲,这次主要讲一下后面有腾讯特色的三项技术。
腾讯的接入点,在全球都有很多点。这么多的机器怎么管理呢?这里主要介绍一下腾讯经典的负载均衡算法。上一周,我面试了一个人,他做的系统,用的是最小分配算法,系统跑得很好,因为请求量不大,只是机器利用率低一点而已,浪费也不大。然而在腾讯,服务是海量的,再用这种算法就会出问题了。
这是一个典型的案例。在做群视频的时候,有新同事误用最小分配算法实现负载均衡,结果所有单机负载出现了锯齿状的曲线,后来改为腾讯经典的加权随机负载均衡算法,曲线就平滑多了。最小分配为什么会出现锯齿状曲线?是因为调度系统的单机负载,并不是每次用户接入或退出就实时更新,而是集群机器定时统计上报。前者会使得系统耦合度很高,后者实现更简单。在一个上报周期中,调度系统里记录的单机负载不会变。所有请求都会分配到这个周期里负载最低的机器上。导致单机负载突然暴涨,变成负载最高的机器。然后在未来若干个周期中都不会分配,等待用户自然流失。跌到最低点时又会再分配。
腾讯经典的负载均衡算法,在每次机器负载上报时,会计算每台机器的空余度,然后将所有空余度加起来,例如这里总和为37。
每次用户请求,计算一个1到37之间的随机数,这个随机数属于哪台机器,就选哪台机器。例如这里的随机数为18,就选第4台机器。
这种算法,实现简单,处理用户请求部分只需要几行代码就搞定了:算一个随机数模总空余度,逐台机器减空余度,减到哪台小于0,就选哪台。效率也很高,时间复杂度不到n。分配上,负载轻的,分配概率大,负载重的,分配概率小。从单次分配来看,有概率可能分配到负载较重的机器。但从宏观统计看,整体负载会比较平均。如果新增加一台机器,新机器的负载增加也会是比较平滑的,而不是突然达到负载平衡点。
腾讯经典的负载均衡算法,一般会和其他算法配合,例如就近、容灾等。可以通过权值控制就近接入,使得就近机器分配概率比别的机器大,这样如果某地机器全部故障(例如IDC停电、专线被挖),或负载满,可以自动就近调度到其他接入点,而不需要人工干预。机器故障,也会调整权值,使得分配概率极小。一旦机器恢复,有用户尝试成功,马上就可以激活机器。所以机器故障,不需要人工禁用和启用机器,全自动处理。
接下来分享一下带宽预测。如果用UDP线性增加发送速率,接收速率曲线会是什么样子的?
这是我们实测的效果。为什么会这样呢?主要是路由器要维持公平性。TCP传输是很友好的,当遇到网络拥塞的时候,会自动缩小发送窗口,减少发送量。但UDP是自己实现的,如果UDP不做这么友好,岂不是我发越多,抢占带宽就越多?这样TCP还能传输吗?所以路由器做了一个策略,如果我告诉你网络拥塞,你不减少发送量,我就惩罚你。于是就出现了这样的接收曲线。所以,我们不能尽最大能力的发送数据,必须要预测带宽,保证不要超过带宽(不要长时间超带宽)。我们先看看TCP是怎么做的。
这是TCP的经典拥塞控制算法,现有用得最广泛的算法。可以看到,带宽估计在窗口大小24左右。接近带宽的地方,有很多三角形区域,是用不上的。
QQ音视频带宽预测,一开始做秒高清,在1秒内粗犷的预测一下带宽情况,然后从预测的带宽开始,逐渐增加,达到带宽瓶颈后,回调一个周期,然后持续传输一段时间。如果持续的过程中,路由器继续提示拥塞,会继续向下回调。如果传输没有异常,会隔段时间向上探测带宽是否增加。
这个预测算法究竟怎么样呢?我们来和竞品对比一下吧:
从图中可以看出,在网络限制总带宽以及设置固定丢包率的情况下,QQ的带宽波动都很小,而竞品要么波动大,要么不断往下调传输量。
丢包的原因都有哪些?
我们列举丢包原因,不仅仅是列出来,还要分析其中的规律。
我们发现,左边的这类丢包,丢的比例跟我们数据发多发少,关系不大,而右边这类,发得越多,丢的比例越大。我们称左边的这类叫固有丢包,右边这类叫拥塞丢包。分类也不是目的,而是思考怎么更好的抗丢包。
通常抗丢包有两种方式,FEC和ARQ。FEC是前向冗余,举个例子,发送数据A和B,增加发送一个数据C等于A和B的异或。接收方接到这3个包的任意2个包,异或一下就可以得到第3个包。当然,实际的FEC没这么简单,通常会有比较复杂的矩阵运算。ARQ就是接收方发现丢包后,去发送方请求重传。
FEC传递简单,只需要单向传输就可以支持,延时小,缺点就是丢包率波动大时,抗丢包能力差。ARQ的优点是网络携带率高,但延迟大,当延时大或拥塞丢包的情况,不能使用ARQ。拥塞丢包时,使用ARQ会加大传输量,导致拥塞更严重。
音视频质量评估,是比较麻烦的事情。很多东西都是比较主观的,人的关注点有差异,对视频好坏的判断也就有了差异。业界常见的评分体系有很多,都比较客观。腾讯也有自己的无参考评分,会偏主观一些,是通过对两千多人对不同质量视频主观评价,拟合而形成的。得到通过各种参数评估音视频主观质量的公式,拟合的公式有点庞大,但外界不一定认可,所以对外,我们还是主要用业界常用的评分体系评估,对内才使用无参考评分。
举个例子,我们用POLQA评分来衡量我们的音质:
可以看到,腾讯的音视频,在丢包率30%的情况评分还比较好。从主观体验来说,腾讯的在丢包30%的环境,还能听得清楚说话,而竞品基本听不清楚了。
这些数据是怎么来的?
这就是腾讯的音视频实验室,有专门的隔音音频实验室、网络损伤仪等等。
下一篇为大家带来【多人音视频及直播互动】的详细学习资料,敬请期待。
更多资料可关注官方公众号:编风网(微信ID:befoio)或 WebRTC编风网(微信ID:webrtcorgcn)