RTC业务中的视频编解码引擎构建

Wesley13
• 阅读 606

RTC业务中的视频编解码引擎构建

正文字数:6146  阅读时长:9 分钟

视频编解码技术一直是视频内容应用中的核心业务,基于各个平台和各个渠道的视频内容采集与分发都涉及到视频编解码技术的介入。在RTC业务场景下,如何构建高效快速的视频编解码引擎,如何对现有的编解码技术进行优化改进,如何在公有协议基础上实现私有协议,如何重写编解码框架等问题都值得关注。我们邀请到了网易云信 音视频算法工程师 何鸣 为大家详细介绍网易云信RTC业务场景下的编解码技术优化与实践,以及未来的发展方向。

文 / 何鸣

整理 / LiveVideoStack

RTC业务中的视频编解码引擎构建

大家好,我是来自网易云信的何鸣,目前主要负责网易云信G2音视频框架中视频编解码引擎的开发与优化工作。

本次分享的内容主要有以下三个方面:

RTC业务中的视频编解码引擎构建

1

视频编解码器技术背景

RTC业务中的视频编解码引擎构建

通过实时通讯,或者是高清直播的方式为用户提供视频内容,视频内容每天都在网络中产生并收发,这些视频内容都是被压缩过的,这个压缩过程就是要实行编解码技术,现在除了少部分的电影拍摄场景可能会用到原始视频流,大部分视频都是经过编解码压缩过后的视频内容。所以,视频编解码技术在视频内容的产生 与分发过程中至关重要。

RTC业务中的视频编解码引擎构建

接下来我们讨论下来,视频编解码技术究竟运用在什么地方呢?像一个视频序列当中,常见的YUV视频中,一个像素点就需要1.5个字节的数据来存储像素点。如果涉及到360P、720P、4K这样的视频的话,数据量是呈指数级的上升,到4K时每秒需要传输数据达到了759MB。与之对比,5G的传输带宽1Gb/s换算成字节表示的话,就是125MB/s。这样的传输带宽是远远不能满足于我们对高清视频内容的要求,所以就需要视频编码技术对视频进行压缩处理。

我们现在常用的视频编码技术是预测器+量化器+熵编码器的一个基本框架,其中量化器的话需要进行反量化操作,下方我们会详细介绍这三部分各起到什么作用。基于这三部分框架,我们将视频重新划分为I帧、B帧和P帧,具体在哪些内容会遇到这些帧,接下来也会详细介绍。

1.1 预测器

RTC业务中的视频编解码引擎构建

首先我们说预测器,预测器我们划分为帧内预测和帧间预测,在帧内预测中,以HEVC角度预测为例,最新的技术发展VVC技术也只是将角度的方向增加了更多,预测的内容更加丰富,但总的来说还是角度预测、DC预测、平面预测。

帧内预测指预测内容全部来自本帧内,它的像素点是由它的当前块重建出来的,所以预测方式所需要的参考方式全部来自当前帧,故称作帧内预测。

与之对应的帧间预测,就需要构建参考帧信息,通过参考帧中寻找到的块来补偿当前块,当前块与参考块之间的运动关系,我们称为运动矢量。在传输时需要将运动矢量传输到解码端,通过解码出运动矢量,在解码帧中重新构建当前块。这样仅仅通过传输一些运动矢量信息,就可以快速构建当前块,所以帧间预测是提高压缩效率的主要办法。现在根据新技术,比如Affine技术可以对一些块的平移、旋转、缩放进行预测。或者我们直接使用缩放对块进行预测,最新的有些论文中也提到对预测方式的改进。此外,构建多参考帧可以在其中选择多个参考帧作为对当前预测帧的候选,这样我们可以选出更好的块来预测当前块。

作为视频编解码技术中的预测器技术,它也是在不断的发展中,从最开始的H261、H263到最近的VVC技术,我们每代标准也是丰富了预测器技术。

1.2 量化器

RTC业务中的视频编解码引擎构建

先简单看一下Lena图经过DCT变换和反变换后的区别,从肉眼上看我们对变换和反变换是看不出差别的,但我们中间的频域图的能量大部分集中在0附近,且能量特别大的信息是比较少的。我们对这部分信息可以通过量化器进行量化,生成量化系数,对原图的信息压缩就达到了,所以量化有压缩数据的功能。在实际编解码应用过程中是通过预测器预测之后,将残差图经过变换之后再送量化器生成量化系数。所以量化器是在预测器的基础上进一步提高压缩率。

1.3 熵编码器

RTC业务中的视频编解码引擎构建

熵编码器依赖香农的第一定律,由于第一定律规定了编码一旦有损信源编码时,我们有一个固定的码长。明确编码器是一种信源编码,信源编码要尽可能去压缩码流,将压缩过的码流送到信道中,通过信道传输后再用解码器还原出来。所以熵编码器中我们主要涉及到无损编码功能,像我们现在常用的哈夫曼编码、指数哥伦布编码或者游程编码这种可以提高压缩效率。但在最新编码器技术中,基于上下文模型的算术编码对压缩率提高是极大的,它对于大概率、小概率符号生成不同的码率,极大的压缩信息量。变换器和预测器生成的信息会送到熵编码器后进行进一步的压缩再送入信道中。

2

视频编解码引擎工程化

上述部分我们主要简单介绍了一下编码器的技术背景,但我们要实现商业编码器相当于工程化,这些技术是远远不够的。

RTC业务中的视频编解码引擎构建

我们在实现商业编码器还面临以上几点难题。首先,实时性能,我们现在通过直播或点播这类业务,观众对于30fps、60fps这种实时应用要求非常高,像低分辨率的360P或720P要求30fps,但如果是高分辨率1080P、4K对时间尺度上fps要求也会提高,基本上是60fps。除了实时性的要求,现在对高清内容的要求也越来越多,比如1080P、2K、4K甚至8K的支持。即使做到实时高清性也要保证低延迟,因为实际的网络环境是极其复杂的,我们会遇到窄带或者弱网传输,我们要保证这种网络环境下,视频的流畅传输。最后一部分希望视频可以在更多的平台上分发,所以对于CPU的占用越小越好,能够适用编解码器,对于硬件的兼容性要友好。

RTC业务中的视频编解码引擎构建

为了解决这些问题,我们在工程化中要解决这些问题,比如说码控技术,一些快速算法、快划分技术的提升,指令集优化、视频前后处理技术以及私有协议的构建。下面会依次介绍各个部分的内容。

2.1 码控技术

RTC业务中的视频编解码引擎构建

我们一般会用CQP测一下算法,CQP即恒定QP值,他会给编码器中每个块设定一样的QP值,根据QP值分配每个CU的码率,决策出最好的模式。这种情况下,有个码率不固定的问题,所以主要用于模型测试。如果做商用在带宽有限的情况下,我们会使用一些控制码率的技术,比如说CBR/ABR技术。对于VBR和CRF,这两种码控技术对码率控制还不是那么好,VBR对于码率压缩效率比较高,在相同编码质量下,编码质量比较高,图像呈现比较好。实时直播情况下,更多用到的是ABR和CBR,这种技术好多商业编码器对它们并没有做很大区分,ABR/CBR提前设定好一个码率,根据码率估计每个CU的码率进行动态调节,最后使码率固定在一个范围内,不会超发和少发的情况出现。

为了实现商业编码器的码率控制,我们在技术领域首先做到的是AQ技术,AQ的Q即QP值,AQ即Adaptive QP值,动态调节QP。对于实时编码器,一般都是1-pass的情况下,在编码前需要估计每个CU的码率,在编码过程中也会根据已编码率动态调节QP。在AQ技术基础上,又实现了一个CTU行级码控,针对调节每个CTU行的码率控制,如果前面CTU编的比较少,后面就多编点,如果前面CTU编的多后面就少编点码率。帧级码控道理是一样的,现在帧级码控基本是几帧一起,作为平均的码控,码率波动控制在可控范围内。上线之后,这些码率通过VQC技术去检测控制,检测到网络状况,下发码率、帧率、分辨率。这种情况下,即有时候我们仅仅调节码率,在720P情况下编出来很差,不如360P,就得去调分辨率,或者怎么降分辨率也不能降低码率,就要降低帧率,这样调节这三个量,可以提高视频的流畅度。码控技术对于商业编码器的重要性是无可言比的,主要工具实现后,如果没有好的码控技术调控,输出的码率是没法达到商业编码的标准,所以码控技术对商业编码器是非常重要的环节。

2.2 块划分技术

RTC业务中的视频编解码引擎构建

除了码控,我们也讨论了块划分技术,上图举例了MPEG系列的编码器块划分图。在最开始AVC的块划分中,只有BTQT两种块划分。到后来HEVC中块划分 最大块是64×64,最小块是8×8,还有不同的PU划分以及非对称的矩形划分。到VVC时出现了三叉划分,最大块达到了128×128。

这种大块小块的划分,大块主要是节省码率,对于更高分辨率的内容,用大块划分的压缩效率非常高。小块更加精细图像细节,用不同形状的块预测当前运动,把具体每个图像中,每个块都会表示出来。对这种复杂的块划分技术,我们在实际编码器上线时,就需要简化各种算法,使得这些块划分能够更快找到最优模式。这个块的算法在块划分预测模式中,应各个编码器各自的情况,也是各自编码器的核心技术。这些技术大家有专利或论文去研究这方面内容,但核心参数在论文中不会公开,需要各家编码实验尝试,控制各个模块的划分技术。只有一个合适的快速划分技术,我们才能在提高压缩率的同时,提高编码器的速度。

2.3 自研编码器框架与快速算法

RTC业务中的视频编解码引擎构建

我们自研的编码器框架在之前也测试过内部开销,我们发现RDO的开销是比较大的,我们是避免去做一些大块RDO,先把主观的黄色部分skip、split、Inter、Intra实现。然后将橙色部分塞进资源的快速算法,在快速算法中有个模块进行分开测试,将快速算法进行上线。在做完这些部分后,做delay RDO,避免复杂的RDO运算,提高编码的速度。通过这种分离式框架,我们方便测试每个快速算法的效果,如果哪个部分出问题需要哪部分的算法,在自己的训练上包括标准训练上,都测试了算法结果。

2.4 视频前后处理技术

RTC业务中的视频编解码引擎构建

接下来介绍视频前后处理技术,我们不仅 聚焦在编码器内部优化,我们还在前后处理上提供了ROI的视频编解码技术。我们通过检测ROI的人脸或者人像区域化,提供去噪算法,动态调节码率,非ROI区域码率降低,ROI区域码率升高,在弱网或背景固定场景下,我们提高了画质。右图的画质图可以明显看出,趋于ROI编码的人脸部分处理更好,非ROI编码上,人脸部分就不如右边清晰。通过截取两帧视频,可以直观感受出它的效果。

RTC业务中的视频编解码引擎构建

在一些场景下,可能没法发送很高分辨率的图像,我们可以通过超分技术提高当前分辨率。上图左边是基础的双线性拉伸的超分,右边是基于深度学习的超分,效果比双线性好很多。在比如下发720P的情况下,可以超分到1080P,给用户提供更清晰的感觉。对于超分我们有自研的深度学习背景框架,在AI的支持下将我们的背景框架落地,把超分实现在我们的端侧。相较于传统的超分效果,我们把编码器的小分辨率图像进行超分后的SSIM、PSNR效果更好。在网络受限的情况下,在端侧给观众的主观体验感更好。

2.5 私有协议的构建

RTC业务中的视频编解码引擎构建

目前主流公开的编解码协议都有专利保护,自己要做编解码引擎其实有一定的专研风险的,其次我们对用户内容的隐私保护,私有协议化提供我们自己的编码器能够互通互解,这样外人没办法解出我们的码流。另一方面私有协议能够提高压缩率,降低视频对CPU开销的影响,通过各方面优化视频编码器。在实现自有协议NEVC的情况下,主要考虑以下几点,首先是专利保护,我们写了一些专利去申请专利保护我们的协议。第二部分是与公有协议的兼容性,解码器要兼容现有主流的AVC、HEVC的码流,这些码流过来我们也能解出来,使得解码器的兼容性更好。另一部分是实现的复杂度,毕竟是商业编码器,要在几个季度工作时间内把协议实现,并上线部署。主要流程是设计文档、工程仿真、撰写专利、工程落地,这部分是我们一个团队共同完成的,这样就把一个成果落地实施了。

RTC业务中的视频编解码引擎构建

NEVC与传统x264相比,速度想当的情况下,压缩质量提高30%,与x265相比下,质量想当但速度是它的50倍,根据编码器的快速算法可以给私有协议划分不同的档次级别。作为商业编码器,在速度方面最快可以达到x265的70/80倍,但质量会变差。

RTC业务中的视频编解码引擎构建

以上是两张主观图,在600kb/s的码率下,720P与x264的对比。可以从图中 看出,人脸这部分NEVC的私有协议人脸仍然是可以比较清晰的编码出来,但x264人脸信息丢失比较严重。左边背景块的纹理信息,x264也没有办法很好的编出来,但在NEVC自有协议下,仍然可以将纹理信息编码清楚。

RTC业务中的视频编解码引擎构建

另外与x265做对比,相近编码速度下,我们对天空的背景、屋顶等细节部分处理都比x265要好得多。包括柱子部分的信息,x265在编码时,暗处信息完全丢失,但在NEVC编码时,可以展示出来。

2.6 基于WebRTC的音视频引擎

RTC业务中的视频编解码引擎构建

最后我们说一下,怎么把自有编码器寄存到RTC业务中。首先说到RTC,不可避免的提到WebRTC这个音视频引擎,WebRTC作为一个能够提供实时音视频直播和通话的框架,其优点也是很明显的,简单易用、多平台支持、免费开源。但它也有缺点,它自身自带的音视频引擎能力明显不足,还使用了openh264或者VP8等技术是无法满足商用的实施要求的。对多人场景的支持度也不够,当人数过多时对编码接入就比较卡顿,像WebRTC这种P2P最多只能支持8、9个人,如果有服务器P2S支持度就会更高。对于传输质量也没有可靠的保证,也没有对Native应用的开发。我们今天主要解决音视频能力不足的问题,我们将自研编码器集成到RTC中。

2.7 NE-RTC中视频编解码引擎

RTC业务中的视频编解码引擎构建

在我们自己的NE-RTC编解码器中,首先NE-RTC支持4个端,PC端、安卓手机端、MAC端以及IOS端。将编解码引擎放进去肯定需要Video factory中去构建编码实现和解码实现,这部分我们集成了一个软件平台上的编解码引擎,这个引擎通过放到RTC中,调用外部的Code。

这个Code我们也做了一个指令集的优化,目前PC/MAC还是x86加工合作sse\avx的优化,IOS和安卓做了arm的优化。这部分放进去之后,由于私有协议,我们现在能做到的大部分终端会支持,但事实上也不是所有设备都能支持,所以还需要一个白名单控制这部分编解码器的开启。这样我们就通过与服务器的交互,服务器上我们需要对码流NAL的parse,需要知道我们是私有协议还是公有的。另一部分是转码录制,需要在服务器上实现解码和转码的工作,通过转码录制把视频存下来。其次还有Codec信令下发,因为白名单控制现在NE-RTC集成了多套编解码器,通过Codec信令下发控制Codec的切换。所以在服务器上我们实现了这么多工作,支持我们引擎的工作。像这种引擎我们一般做在单侧,比如做在PC、MAC或者安卓和IOS中,剩下做在信令服务器或者媒体服务器上。

RTC业务中的视频编解码引擎构建

我们来看下效果,通过自己demo实现了一个至少在大流放上了私有协议,能够做到高清低延迟,使得整个视频观感以及网络带宽的占比更小。小流上由于分辨率比较低,目前小流用的180P等,小分辨率首先保证流程用的是公有的264编码器,使得CPU占用低,省资源,但目前更多的还是看大流的内容。

3

网易云信的业务与发展方向

接下来会简单介绍一下我们把商业编码器应用到业务或发展中的情况。

RTC业务中的视频编解码引擎构建

商业编码器最重要的是用到自己的通信或者是直播场景中,在线上发现问题,编码器内部可能有些问题在实验中是无法发现的,但在线上搭配我们百万级、千万级用户使用的情况下,可以使得编码器的问题暴露,及时改进,提供更优的编码器效果。进一步也需要参与音视频标准制定,将我们的音视频做到标准化,就可以用现有的音视频框架,构建和改进技术。另一部分是积极的在会议上发表我们的文章,或者在专利上保护我们的技术,让更多人了解我们的技术。更重要的是与高校产生合作,通过高校最新技术改进编解码的技术内容。

Q/A环节:

问:硬解应该无法支持NEVC的吧,是否只能用在封闭系统中?

答: 硬解无法支持,只能支持软解。

问:有没有考虑导入第三方硬编外设?

答: 这个考虑过,在一些机型上会适配硬编硬解,但硬编的功耗会增加。

问:商业化编码器会消耗端上的性能,端上如何选择是用硬编还是软编NEVC?

答: 会用白名单里控制,相同带宽下,软编的NEVC提供更好的画质体验。

问:CRF 码率控制中,CRF比较常用的取值?用什么算法能够更好的评价使用后的质量变化效果?

答: 码控是个很复杂的内容,通过评价来调整码控有很多方法,例如传统的JND模型,或者现在比较流行的深度学习评价方法,都可以改善码控。

问:基于ROI的视频编码网易云信目前有具体应用在哪些场景吗?效果如何?

答: 目前处于自研阶段,后期根据产品情况上线会议或直播场景,效果只展示了部分实验数据,后面上线后会有更多评测数据。

LiveVideoStackCon 2021 ShangHai

我们准备好全新的内容

在上海欢迎您的到来

RTC业务中的视频编解码引擎构建

LiveVideoStackCon 2021 上海站

北京时间:2021年4月16日-4月17日

点击 【阅读原文】了解大会详情

本文分享自微信公众号 - LiveVideoStack(livevideostack)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这