本文为「Dev for Dev 专栏」系列内容,作者为声网资深视频算法负责人 戴伟。
01 视频编解码标准的历史和现在
1990 年左右 H.261 标准的制定,开启了视频编解码标准化的历程。经过 30 多年的努力,视频的编码效率得到了极大幅度的提升。在下图中,我们大致列举了一下所有的视频编码标准的制定组织和发布时间。
我们可以发现,到目前为止,视频编码领域主要还有三大组织在制定标准。他们分别是制定 H.26x 系列的编解码标准的 ITU-T 和 MPEG 联合的组织,制定 Avx 系列的编解码标准的以 Google 为首的 AOM 联盟以及制定 AVSx 系列的编解码标准的中国专家组。
在这些标准中,目前世界上应用最为广泛的标准,是 ITU-T 和 MPEG 联合制定的 H.264、H.265 以及 Google 制定的 VP9 和他们后面的 AV1 这四个编解码标准。其中 H.264 已经有将近 20 年的历史,其编码效率已远远低于最新制定的 H.266 等编解码标准,但是由于支持他的设备极其广泛,所以它目前仍然是支持度最高的一个编解码标准。
下图是 Bitmovin 连续 4 年的一个编解码器使用调查问卷,我们可以发现,除了 H.264 之外, H.265 也是一个支持度相对较高的编解码标准,而 VP9 和 AV1 也有一定的增长势头。总体来说,H.26x 系列的编码标准,由于其广泛的公司参与和支持,会更加容易得到硬件芯片的实现。但是从 H.265 以来,其专利费的不清晰也成为了他们推广的一大阻力。反之,AV1 从制定初期就定下了免专利费的目标,发展过程中也得到了越来越多的公司支持和加入,我们相信 AVx 系列的支持度也会以一个较为惊人的速度不断发展。
视频编解码标准的首要目标是在保证画质的前提下尽可能的压缩视频文件大小,节省存储和传输成本。这个目标也很好的切合了视频初期的使用范围,即一开始的 VCD,DVD 以及后期互联网兴起之后的视频点播网站等。但是,随着 RTE 的不断发展,视频领域涌现出了不少新的需求,而这些新的需求,又会反过来促进编解码的进一步发展。那么,RTE 的时代下,又涌现出了哪些新的需求呢?
02 RTE 时代下对编解码标准提出新的需求
RTE 里的视频应用场景和普通应用场景最明显的区别,在于对视频的端到端延时要求。普通的视频点播因为没有互动的需求,所以基本不关注延时的问题。而在 RTE 场景中通常会涉及到大量的交互与互动,因此对延时有着极高的要求,一般要求至少是在 300ms 以内。并且因为超低延时的限制,导致编码的输出码率对网络带宽的变化要更为灵敏。
另外,因为 RTE 是实时的应用场景,所有产生的视频可以认为是即编即用的,这也是和普通视频场景的一个极大区别。因为在普通的视频场景中,视频的播放次数远远大于视频的压缩次数,这也是所有编解码标准中尽力控制解码器复杂度的原因。而在 RTE 的领域,如果不考虑特殊的录制等需求,所有的视频都是编码一次,播放有限次的。
在这两个大前提下,视频的编码和传输在 RTE 的领域里就催生了几个很重要的问题:
1、在码率波动的情况下如何保证画质的稳定
在传统的视频编码的场景中,一般是先给定一个固定的码率,然后整个视频以这个不变的码率作为目标进行编码。在这种场景下,编码器可以相对容易的控制整个视频画质的稳定。然而在一个实时传输的系统中,网络带宽是实时变化的,可能前一秒还是一个通畅的网络状况,下一秒就由于网络拥塞而导致目标码率突降。
例如我们现在正在以 1.2Mbps 的码率编码一个 720P 15fps 的视频,突然由于网络的原因,当前可用的带宽下降到了 300kbps,此时,如果编码器依然还以 720P 15fps 的方式去编码这个码流,会体验到非常严重的主观画质下降的问题。
另外,在带宽波动的状态下,如何保证画质的平稳过度,也是一个非常重要的问题,当带宽从 1.2Mbps 突降到 300kbps,然后又慢慢爬升回 1.2Mbps 的时候,如何保证这期间画质的稳定,也是对用户体验的一大考验。
2、如何在丢包的情况下保证视频的流畅度
在传统的互联网点播场景中,一般都会有 2 – 3 秒的播放缓存时间。如果遇到网络丢包的情况时,延时可能会到5秒以上。这些延时在真正的观看体验中除了延迟变大的那一刻,其他时候基本是无感知的。然而,在 RTE 的场景中,因为有着实时互动的要求,对端到端的延时有着极高的要求,过高的延时会直接导致使用体验的恶化。
在低延时的前提下,解码器并没有太多的时间来等待传输过程中丢失的包。所以在丢包率较高的场景下,很容易出现有几帧,甚至连续几帧无法在接收端完整收到的情况。如果没有一个很好的抗丢包的策略,那么很可能后续的视频帧都会由于找不到对应的参考帧而无法解码。
为了让视频能够重新解码,一般需要编码器重新发一个 IDR 帧。而 IDR 帧因为可以独立解码,不依赖前面的帧是否可解,导致他的帧大小是一般的 P 帧的 2 – 3倍以上。这么大的帧在丢包率较高的网络条件下,会有更高的概率无法被完整的收到,进一步加剧视频的卡顿率,导致较差的用户体验。
3、如何提升低码率下的视频质量
**RTE 场景中挑战性最大的就是如何在弱网场景下依然保证不错的用户体验。**在传统的编解码标准中,当给定码率很低的时候,只能通过使用一个很大的量化步长来尽可能的丢弃图像信息来达到低码率的目的。然而这种做法会引入很严重的块效应,极大的影响了我们的主观体验。
在 RTE 的场景中,我们可以通过一系列的方法来提升主观的画质。在发送端可以有包括降帧率、降分辨率等方法,其中降帧率并不需要重启编码器,而降分辨率则一般需要重启整个编码器,丢弃掉之前的所有编码信息。在接收端则可以通过超分等方法进行画质的图像提升等。
但是这些方法在码率特别低,QP 特别大的时候,都无法很好的将损失的画质给弥补回来,反而可能会引入额外的主观画质问题。例如超分的画面如果有这很严重的块效应,那么超分出来的画面会在很大程度上依然保留这些块效应的边界,甚至可能会在在这些边界上引入更严重的 artifacts。
03 新编解码标准的技术展望
在说了这么多 RTE 场景下对视频编解码的新需求之后,我们再来谈一谈这些新需求会促生视频编解码的一些什么新的技术展望。
1、动态分辨率适配
在传统的编解码标准中,一旦编码开启,整个过程中的分辨率是不能变化的。如果想变化分辨率,有几种方法可以选择:
①使用多条流编码不同分辨率,并且在对应位置进行流切换的方式来达到分辨率变化的目的。
②使用 SVC 技术来进行动态分辨率的切换。
两种方法比较起来,我们可以看到方法 1 的架构比方法 2 要简单很多,整体的业务逻辑也会相对简单清晰。
但是因为方法 ①的多条流之间是互相独立的,所以在上行发送的时候,这些流会占据较多的上行码率;方法 ② 里因为流是互相依赖的,所以它的上行码率比方法 ①起来会少一点。但是,对于接收端来说,如果接收端观看的都是小分辨率的视频,那么两个方案对于接收端来说没有区别。但是如果接收端观看的是大分辨率的视频,那么方法 ② 的总体码流因为流之间的信息冗余,会比方法 ① 的单流要高出 10%左右的码率。
所以上述两种方法,都有各自的优缺点。而我们所说的动态分辨率适配技术,即在编码过程中动态变化编码的分辨率,然后再解码的时候通过上采样的技术全部都采样到相同的分辨率,很好的吸收了前两种方法的优点。
我们可以发现,在 AV1 中已经提出了一种编码过程中超分辨率的方法。即在编码 1280x720P 的时候,如果遇到带宽等问题需要降低分辨率进行编码,它会以 640x720P 的分辨率来编码当前帧,然后再解码的时候再通过一个确定的方式将画面超分回 1280x720P。
AV1 的这个设计,当时是考虑到硬件缓存的限制,所以只在水平方向进行缩放,垂直方向并没有进行缩放。
然而,仅仅水平方向的二分之一的缩放,对降低码率并不能起到非常大的作用,将来的编码器应该可以支持更多方向,更大比例的缩放,来达到动态降低码率的目标。
2、可配置的 in-loop filtering
传统的编解码标准里只规定了解码的整个流程,包括流程中用到的各种系数,都用一个文档规定的十分明白。这么做的主要目的,是在于确保无论什么时候,什么设备编码出来的码流,只要符合这个标准,都可以随时随地被按照这个标准设计的解码器正确解码出来。本质上,它还是为了编码一次解码无数次的目的而设计的。这种设计方法有一个比较明显的问题,即他们的 in-loop filtering 的可调参数太少了,不能在所有的场景下得到最优的效果。
在 RTE 的场景下,我们其实并不需要考虑太多一个小时后别人想看的话怎么办这种问题,我们更需要关注的是在互动的过程中如何得到最佳的用户体验。那么我们就可以将这些滤波的系数都改成可配置的。例如在户外场景我们可以使用一套专门为了户外训练的模型,在室内场景我们可以使用一套专门为了室内训练的模型,屏幕共享的时候使用一套专门为了字体优化过的模型。甚至在以后遇到新场景时,再训练一套这个新场景下的模型。
更进一步说,我们可以将和编解码相关的后处理,作为一个新的 in-loop filtering 模块,做到编解码的流程中去。这样就可以进一步提升参考帧的质量,提升压缩的效率。
这样的话,我们就可以在各种各样的场景下,得到更佳的用户体验。
3、更适应网络的丢包容错机制
在传统的视频编解码标准的制定过程中,并没有考虑过太多的各种网络丢包时如何进行错误恢复的方式,也并没有规定进行错误恢复的方式和方法,而是把这个能力交给了每一个开发者来定义。这个在某种程度上为开发者提供了非常大的错误恢复方案的灵活性,但是这么做的代价,就是所有的错误恢复都是只能在解码之后才能进行操作。从另外一个角度来说,也限制了编码器获得更高编码效率的空间。所以在 RTE 的场景中,我们需要一套 in-loop error concealment 的方法,来最大化的提升编码效率。
此外,在 syntax 的层级,传统的视频编解码算法也并没有什么特殊处理的方法,我们还需要再 syntax 的层次对网络的丢包场景进行进一步的适配,充分考虑各种丢包的情况进行处理,达到最高的编码效率。
04总结
在 RTE 的应用越来越广泛的今天,由于 RTE 的场景有其特殊的要求,传统的编解码标准不能够很好的适应 RTE 的场景的要求。我们相信随着 RTE 的应用越来越广泛,那么新的编解码标准在制定的时候,就不可避免的需要考虑 RTE 的新需求,创造出一个新的 RTE 的视频编解码标准。
(正文完)
关于 Dev for Dev
Dev for Dev 专栏全称为 Developer for Developer,该专栏是声网与 RTC 开发者社区共同发起的开发者互动创新实践活动。
透过工程师视角的技术分享、交流碰撞、项目共建等多种形式,汇聚开发者的力量,挖掘和传递最具价值的技术内容和项目,全面释放技术的创造力。