视频压缩解决方案厂商On2 Technologies公司现已推出最新的视频压缩格式On2 VP8。On2 VP8是第八代的On2视频,能以更少的数据提供更高质量的视频,而且只需较小的处理能力即可播放视频,为致力于实现产品及服务差异化的网络电视、IPTV和视频会议公司提供理想的解决方案。 对更高效视频压缩格式的需求显着 高清电影和电视节目的下载与发送如今已是司空见惯的事情,再加上价格廉宜的高清网络摄像头,我们预计高分辨率的用户自创内容将迅速增长,而高品质的视频通信解决方案也将被广泛采用。 虽然数据传输速度在不断提高,但带宽的成本和可用性仍将是控制实施成本的主要障碍,因为视频服务使用的带宽比任何其它IP应用都要大。根据思科公司 (Cisco) 最近出版的白皮书显示,到2012年,IP流量将超过半个皆字节 (zettabyte, ZB),其中视频占所有消费应用流量的近90%。2012年,单是互联网视频预计每月就产生10 艾字节 (exabyte, EB) 的数据。
On2 VP8加入了40多项的创新技术,在压缩效率和性能方面超越了目前市面上的所有其他视频格式。这些创新技术包括: * 基于虚拟参考祯的高级预计编码 * 基于宏块级的多线程技术 * 改进的局域参考编码 * 增加复杂度的先进上下文熵编码 * 稀疏目标区域的自适应回路滤波 On2 VP8在质量和性能方面超越H.264、VC-1和Real 视频 随着On2 VP8的推出,On2 视频现已大幅超越所有其它商用格式的压缩性能。例如,主要的H.264实现方案需要两倍的数据才能提供与On2 VP8相同质量的视频 (基于客观峰值信噪比 (PSNR) 测试结果)。 此外,On2 VP8比特流的解码只需要极少的处理周期,故用户无需拥有最新、最高级的PC机或移动设备也能够享受到On2 VP8的视频质量。
在这里我尝试回答的问题是这些: 1. VP8有多好? 从压缩的角度说这种文件格式能比H.264更好吗?以及一个优秀的VP8编码器能击败x264吗?On2声称VP8比H.264好50%,但是On2经常说出这种他们自己都无法提供有效证据的荒谬声明,所以这样一个数字几乎可以断定是不正确的。比如说VP7,曾被认为比H.264好15%并且快很多,但事实是它既没有H.264质量好也没有它快。 2. On2的VP8实现怎么样?和标准本身多好无关,这是说具体实现是否优秀,或者说On2的VP8实现会和VP3一样,发布了一个根本无法使用的糟糕实现,将希望寄托于开发者团体去修正他们。让我们祈求VP8不要这样吧,Theora的修补花了6年啊! 3. VP8真正意义上免专利的可能性有多少?即使VP8比H.264差,但免专利显而易见是一个很有用的特性。但是就像我在之前的文章中提到的,Google的声明并不能保证它就是免专利的。微软在几年前发布VC-1时曾做过类似的事,但是发布后没几个月,一堆公司就在他上面不断地申请专利,没过多久专利的数目就足以形成专利池了。 我们从VP8的核心特性展开分析。我们主要通过和现存视频格式的比较来分析。谨记在心的是编码器和标准是两码事,完全有可能一个优秀的编码器是建立在一个糟糕的标准之上的,反之亦然。这就是为什么一个非常优秀的MPEG-1编码器能击败一个惨不忍睹的H.264编码器。 编码器:预测->变换+量化->熵编码->除块滤波 解码器:熵解码->预测->反量化+反变换->除块滤波
预测是指任何用于猜测帧内某一区域内容的尝试。 这可能包括基于本帧已知像素预测而来(这种方法叫修复inpainting),或者通过前某帧运动补偿(Motion compensation)而来。预测通常包含着一些附加信息,比如用于告知解码器运动矢量(motion vector)的信号就在运动补偿这种预测中使用。
帧内预测是当不需要其它帧参考时猜测某一块使用的方法。VP8的帧内预测基本上是从H.264标准照搬过来的:子块(subblock)预测模式基本上和H.264的i4×4模式完全一致;并且,整块预测模式和i16×16模式一致。色度的预测模式从经验上说也和H.264一样。H.264 High profile中定义的i8×8模式没有出现在VP8中。另一个区别在于H.264的平面预测模式在VP8中被替换成了TM_PRED,这是一个非常含糊的近似模拟。就特定的预测模式而言,VP8和H.264有细微的差别,但是他们都和H.264有着一样的名字。 老实说,我对这点很失望。当然,H.264的帧内预测是优秀的,但显而易见在过去的7年帧内预测这种技术也改进了不少,并且我认为粗俗的照抄是像Real(见RV40)这种公司守备范围内的事。我曾热切的期望On2能弄出些哪怕是只有一点创造性的东西出来。但另一个比这些都重要的问题的是,H.264的空域帧内预测是被专利保护的,而且我不认为On2能仅用一些预测模式上的舍入变化就能逃离专利的魔爪。我希望看到Google能对此正名,他们必须提供一个很好的解释,说明他们为什么不会被卷入专利纠纷。 帧内预测模式的评价:对H.264稍作修改的照搬,也许比H.264更差,因为缺乏i8×8模式。
帧间预测是借助于其它过往帧为参考猜测某一块内容的方法。帧间预测一般而言由两个主要部分组成:参考帧和运动矢量。参考帧是一用于复制像素到预测帧,并根据复制块与当前处理块的偏差形成运动矢量的过往帧。VP8支持最多3个参考帧:时间轴上的前一帧,“alt ref”帧和“golden frame”。就运动矢量而言,VP8支持和H.264很相近的可变大小宏块分割方式。就子像素精度而言,VP8支持1/4像素精度运动矢量,使用的是6阶插值滤波器。简而言之: VP8参考帧:最多3个 H.264参考帧:最多16个 VP8分割类型:16×16,16×8,8×16,8×8,4×4 H.264分割类型:16×16,16×8,8×16,可变子分割(每个8×8的块可再被分割成8×8,8×4,4×8或者4×4)。 VP8色度MV的推算:每个4×4的色度块的MV使用相同位置亮度MV的均值得到(与MPEG4-ASP相同)。 H.264色度MV的推算:色度块的MV直接使用亮度块的MV。 VP8插值滤波器:1/4像素,6阶亮度,混合4/6阶色度。 H.264插值滤波器:1/4像素,6阶亮度(分层滤波器),双线性色度 H.264有但VP8无:B帧,权重预测 H.264有着明显优于VP8并自由度更高的参考帧结构。8×8子块的再分割基本无用,所以VP8在此处的省略基本不会造成影响。色度MV的推算比H.264更准确,但比H.264稍慢。从实际使用上说,这个区别从速度和压缩率来说都是近似于0的,因为8×8的亮度分块是很少用到的,(并且我在此假定在VP8中也一样)。 VP8的插值滤波器可能会比H.264稍好,但是肯定实现起来更慢,从解码器和编码器两方来说。一个分层的滤波器允许编码器能预计算所有可能的半像素位置的值并且当需要的时候能快速的计算出1/4像素位置的值,而一个非分层的滤波器则无法做到,这就将导致非整数像素运动估计的速度非常慢。并不是所有的非分层滤波器都是糟糕的 – 分层滤波器在所有的H.265提案中都对抛弃了 – 对VP8而言这只是一个从性能角度来说相比于H.264的内在劣势。另外,在色度上使用高达6阶的滤波器,在我看来,是完全没必要和没用的。 VP8缺少的B帧是一个致命缺陷。B帧能在非常小的速度损失下提高10-20%甚至更多的压缩率,他们在VP8中的缺席可能会比这篇文章中提到的其它所有问题影响的压缩率之和还要严重。但这并不是完全出乎意料的,On2从没有在之前的任何一种视频格式中使用B帧。并且他们可能会因为使用B帧导致严重的专利问题,即使On2看上去似乎在照搬其它被专利重重保护下的H.264特性时没有任何问题。对权重预测的不支持也将在一定程度上影响压缩率,特别是对渐变场景。 对帧间预测的评价:类似于H.264的宏块分割结构。糟糕的预测帧结构。更复杂,略优于H.264的插值滤波器。基本上劣于H.264,如果不考虑因为B帧缺乏带来的对压缩率的严重影响。
在预测之后,编码器将预测帧和实际帧的差值(残差)送入变换和量化。变换是用解相关的方式使数据更易于压缩。量化是一个实际损失信息的步骤,所谓的压缩也就在此处实现:变换的输出值会经过舍入,大部分参数都将变成0,只留下少数整数参数。
对于变换来说,VP8再一次的使用了一个类H.264方案。每个16×16的宏块被分成16个4×4的DCT块,每一个使用一个精确位数的DCT近似进行变换。之后,每个变换块的DC分量被提出成另一个4×4的组,之后对这个4×4的组进行Hadamard变换。OK,到此这不是一个类H.264方案,这就是H.264。但是,VP8的变换方案和H.264有三点不同。 首先8×8变换被完全去除了(这和i8×8模式被去除相对应)。其二是变换本身,H.264使用了一个极其精简的DCT,它是如此的不像DCT以至于经常被人用HCT(H.264 Cosine Transform)代指。这个精简的变换大概能导致1%的压缩率损失,但是大幅精简了变换的运算,它可以完全用加、减和右移一位这三个操作来实现。VC-1使用了一个更精确的版本,它依赖于几个简单的乘法(比如17,22,10等)。VP8使用了一个特别地,不必要地精确版本,使用了非常大的乘法(20091和35468)。回想On2之前在VP3的所作所为,这种实现方法的出现并不惊讶。 第三个不同之处在于Hadamard层级变换还作用于一些帧间预测块中,而不仅仅是i16×16这一种帧内预测模式。具体来说,它也作用与p16×16块中。这是一个非常好的想法,特别是考虑到较小的变换大小(以及对于小范围变换时解相关DC值的需求)。我并不是非常确定我同意将层级变换只限定在p16×16块内,看上去似乎只要经过很少的修改,这样的变换也会对其他运动分块有用。另外,与H.264不同的是,层级变换只作用于亮度块而不作用于色度块。 总体上,VP8的变换方案绝对比H.264弱。缺乏8×8的变换,特别在高分辨率场合,会严重影响对细节的保持。变换本身也非常没有必要的慢,虽然基于位移的变换方案可能会逃过专利问题。其中一个优秀的想法是将层级DC变换应用到帧间预测块中。 对变换的评价:接近于H.264,更慢,略微准确的4×4变换,对亮度DC变换的改进(但是没有对色度的支持)。没有8×8变换。总之,劣于H.264。
对于量化而言,核心的处理方式对于所有类MPEG视频格式都是一样的,VP8也不例外。量化上各种不同标准区分自己的方法就是改变量化阶系数。这里面主要的方法又有两种:基于帧的偏移,其作用于所有或者一部分系数;以及基于宏块的偏移。VP8主要使用的是前者,其方案相比于H.264的自定义量化矩阵而言可伸缩性差了很多。VP8的方案允许分别调整亮度DC分量,亮度AC分量,色度DC分量等诸如此类的对应量化器。后者(基于宏块的量化器选择)从理论上可以利用“分割图”的功能实现,尽管这种实现方式需要相当的技巧并且不是非常高效。 VP8在这里犯得一个致命错误在于没有把基于宏块级别的量化作为VP8的核心特性支持。利用基于宏块级别量化的算法一般被称为“自适应量化”,这种量化对视频主观质量的影响是绝对非常关键的。我在x264里的基于方差的自适应量化算法实现,到现在为止,仍然是x264历史上最大的单个主观质量增长补丁。编码器的评价一次又一次的证明,没有自适应量化的编码器完全没法与具备的编码器相提并论。 因此,想让自适应量化在VP8上成为可能,对每个有可能被用到自适应的量化器定义一个分割图并对每个宏块的分割图索引进行编码就成了华山一条路。显然这是很没效率且很笨拙的实现方法,哪怕不是最优的MPEG风格delta量化器系统都是一个更好的选择。此外,对于每帧最多4个量化器而言,VP8最多只支持4张分割图。 对量化的评价:当需要进行视觉心理优化(psy-optimization)时,缺乏可简化开发整合良好的自适应量化的VP8会让人头疼不已。总之,比H.264差远了。
熵编码是将其它过程产生的信息,如DCT系数、预测模式、运动矢量等等,整合在一起并无损压缩成最终输出文件的过程。VP8使用的算术编码器在一定程度上与H.264相近,但有几点关键区别。首先,它以一个乘法运算取代了范围/概率表。再者,它完全是非自适应的,与H.264中对解码的每位都去调整概率值不同,VP8的概率值在一帧内事恒定的。与之相对的,编码器会定期地在帧头部的部分语法结构中发送更新后的概率值。编/解码到关键帧重置概率值。 这种实现方法并不奇怪,VP5和VP6(以及可能VP7)都使用了非自适应的算术编码器。到底这样的编码器会给压缩率带来多少影响是未知的,因为从H.264或者VP8的设计中去想办法衡量这个并非易事。更重要的是,我有此疑问的一个原因是:让算术编码能够自适应只需要在解码器端加上一个简单的查表运算,这不会有非常大的性能影响啊。 当然,算术编码并不是熵编码的唯一部分:一个算术编码器仅仅是把0和1转换成输出的码流。而生成这些0和1的过程和为编码器选择适合的概率值使用是同等有趣的问题。因为这是视频标准中非常复杂的一个部分,我在此仅对我觉得特别值得提出的部分做一些评论。 运动矢量编码包含两部分:根据相邻运动矢量来预测以及压缩预测值与实际值之间的差值。VP8的预测方案显得有点奇怪,更糟糕的是,标准中对这部分没有任何英语解释,只有写的很让人摸不着头脑的C代码。我只能根据我对它的理解来说明了:VP8根据相邻运动矢量来选择算术编码语境(context),然后决定选择哪个预测运动矢量,或者决定是否编码矢量的差值。 此方案的问题在于,和VP3/Theora类似(虽然不是一样糟糕),它严重倾向于重复使用过去的运动矢量。这是非常危险的因为,就像Theora的开发者发现的一样(在最今的Theora 1.2得到了一部分解决),任何编码器因为节省码率而选择了一个并不是“真正”的运动矢量的行为都有劣化主观质量的可能后果。从最基本的效率来说,在这我不敢确定VP8和H.264何者更好。 压缩差值的方法和H.264接近,除了当编码非常大差值时VP8会稍优于H.264(类似于FFV1的类哥伦布算术编码)。 帧间预测模式的编码使用基于临近块的模式作为算术编码的语境。这或许比H.264使用的过时的方法要好。在这点上,H.264的糟糕设计一直让我很惊诧。 残差编码比运动矢量的编码更难理解,因为只有一堆高度优化、高度模糊的C代码作为参考。和H.264的CAVLC一样,它基于当前块的左侧以及上部块非零系数的个数作为语境。此外,它考虑了这些非零参数的数值,并且和H.264的CABAC一样,会根据已解码的系数更新语境。 另一件值得一提的事是VP8使用的数据分割方案。此方案与VP3/Theora的实现非常相近,包括将每个语法元素放入码流中其自己的部分中。这个问题的不幸之处在于这种方式非常难在硬件上实现,它极大地增加了内存带宽的需求。我已经从一个硬件开发者那听到了关于VP8这部分特性的抱怨。 对熵编码的评价:我对此不是特别确定,可能在某些方面更好,可能在其他方面更糟,在剩下的部分或许只是奇怪。根据我的预感,VP8或许在这方面会比H.264略微胜出;非自适应的算术编码显然会带来一些严重的性能影响。VP8也可能同时会有硬件实现的问题。
环内滤波器是在解码或者编码完一帧后使用的,对某一帧做一些附加处理,一般在基于DCT的视频格式中是用作除去块效应。不同于后处理,除块滤波不仅仅是因为视觉上的原因,它还能改善后续帧的预测精确性。因此,除块滤波的操作在解码端和编码端必须完全一致。简单的说,VP8的环内滤波和H.264类似,但是有几点不同。首先它有两种模式(能在编码器中选择):快速模式和普通模式。快速模式比H.264要简单,但是普通模式比H.264要复杂。其次,当在宏块之间滤波时,VP8的滤波器会选择比宏块内滤波更长的滤波模式。H.264也这么做了,但H.264只对帧内预测帧的边缘采用这种方式。 第三,VP8的滤波器忽略了H.264滤波器内大部分关于自适应强度的机制。它唯一的自适应来自于它对没有DCT系数的p16×16块不滤波。这可能就是VP8环内滤波器会产生大量模糊的罪魁祸首:它将一遍又一遍的对宏块的所有部分进行滤波哪怕这个宏块在帧间没有任何变化(只要该宏块的其它某些部分改变了)。H.264的实现,与之相比,则根据DCT系数是否在给定要处理边缘的两侧存在、运动矢量的差值和此边缘两侧参考帧的差值来自适应地调整滤波强度。当然,跳过这些强度判断和计算节省了解码时间。 对环内除块滤波的评价:从压缩率的角度,因为缺少自适应强度机制而显然的比H.264差,特别是使用“快速”模式时,虽然可能会大幅提高编解码速度。我担心的是这种滤波的结果是过度的模糊了画面。