视频压缩算法通过对视频信号的压缩处理可以极大地降低视频信号的存储和带宽需求,在此基础上尽可能多的获得最佳的图像质量。因此,了解视频压缩算法的基本原理对于嵌入式系统,处理器以及视频应用工具的开发人员来说,是非常必要的,例如在处理器选型以及软件优化的过程中,视频压缩算法的性能开销和存储空间占用就是其中非常关键的因素。
静态图像压缩
视频剪辑也就是我们通常所说的动态图像序列,动态图像序列是由在时间轴上的若干幅静态图片组成的,在动态图像序列中的每一幅图片称之为“帧”。在动态图像的压缩算法中大量的使用了静态图像压缩的算法和技术,例如静态图像压缩标准JPEG。实际上简单的动态图像序列压缩的方法就是将此序列中的每一幅静态图片独立的压缩,忽略掉这些图片在时间上的相关性。在一些视频产品的应用中使用了这种方法,将每一幅图片都用JPEG标准进行压缩,我们称之为“运动JPEG”或者也叫MJPEG。
目前更为先进的视频压缩算法更多的利用了视频序列中连续的静态图像,也就是连续帧之间的时间相关性,利用运动估计和运动补偿算法获得更好的压缩比,当然这些先进的视频压缩算法也同样采用了静态图像压缩里面的一些基本算法,因此我们的讨论就从基于块变换的静态图像算法JPEG开始。
数字图像压缩的基本单元
块变换
在JPEG和大多视频压缩算法中所采用的压缩算法都是“有损压缩”,所谓有损压缩就是指从压缩后的数据中无法完全恢复重构出原始的压缩前图像,有损压缩会丢失掉一部分原始图像的信息,因此,有损压缩算法就需要尽量保证由信息丢失所造成的原始图像和重构图像之间的差异不被人眼所察觉。
对于JPEG和类似的图像压缩算法来说,压缩的第一步需要将图像分割为小块,同时将每个小块进行变换,使之由空域信号变换成为时域信号。这种空域到时域的变换多采用8x8的离散余弦变换(以下称DCT),经过DCT变换之后,8x8的空域像素矩阵变换成为8x8的频域信号矩阵,DCT变换能够完整的保留所有8x8像素块的信息,因此反向离散余弦变换(以下称IDCT)也就能够从8x8频域信号矩阵中完整的恢复原始8x8像素矩阵。DCT变换后的频域信号矩阵中包含原始8x8像素矩阵的低频部分和高频部分,其中低频部分对应图像的重要信息,高频部分对应图像的细节信息,就人眼的特点来说,对于图像低频部分的感知要比对于图像高频部分的感知敏感很多,因此在DCT变换将图像的信息按照其人眼感知的敏感程度分离之后,后续的压缩步骤就是将其低频部分编码更多的比特,从而获得更高的精度,而对其高频部分编码更少的比特数或者不编码比特,从而在保留一定的视觉效果的同时,获得更好的压缩效果。在解码端,再用IDCT变换从频域信号矩阵中恢复出原始8x8像素矩阵。
IDCT变换和DCT变换的运算量基本一致,因此这两种变换对处理器的性能要求也基本类似。一个二维8x8DCT变换和IDCT变换在典型的DSP平台上需要数百个指令周期完成,视频压缩算法的执行中每秒都需要进行大量的DCT和IDCT运算,以一个MPEG4的解码器为例,在解码分辨率为CIF(352x288),帧率为30fps的视频序列时,需要每秒进行71,280次IDCT运算,在TITMS320C55xDSP处理器平台上需要占用40MHz的处理性能(不考虑集成DCT加速器),这大概占用了整个视频解码器应用时处理器性能的30%。
由于DCT和IDCT运算的单位都是很小的图像块,因此相对于帧缓存以及图像压缩应用中的其他数据存储来说,其对存储资源的占用几乎可以忽略不计,正是基于其大运算量,低存储占用的特点,DCT和IDCT运算单元特别适合用专用的硬件加速协处理器来实现。
量化
DCT变换后的结果称为DCT系数,正如上文所说,编码器需要对于DCT系数中的重要的低频分量编码更多的比特,对于DCT系数中的次要的高频分量编码更少的比特,这种对系数的编码方法可以通过两步来实现:首先通过量化过程舍去次要的视频信息,然后利用统计学的方法尽可能少的对剩余的重要信息进行比特编码。
量化过程就是将每个DCT系数向若干预设值进行舍入的过程,例如,DCT系数是值介于-1到1之间的实数,将其用缩放因子20进行缩放,同时将结果舍入到最近的整数,于是DCT系数便量化成为值介于-20到20之间的整数,共有41个,在理想情况下,为每个DCT系数选择合适的量化因子可以使量化后的DCT系数在向右取整的过程中不至于引入明显的量化噪声。
在解码端,采用与编码端相反的反量化过程,就上文所属的例子来说,对量化后的DCT系数进行反量化,用1/20进行缩放,反量化值缩放到-1到1之间,注意此时的反量化值与原始的量化前系数已经不再相等,不过足够接近,以保证IDCT变换以后不会引入明显的视觉差异。反量化大概需要占用整个视频解码器应用时处理器性能的3%-15%,与DCT和IDCT变化类似,量化和反量化对存储器的资源占用可以忽略不计。
编码
压缩的下一个步骤即是对量化后的DCT系数进行比特编码,使之成为传输比特流,为了尽可能少的编码比特数,达到数据压缩的效果,需要利用量化后的DCT系数的一些统计特性。
量化后的DCT系数的值大多是0值,特别是大量的高频DCT系数分量,一种叫做“游程编码”(以下称run-length编码)的技术可以很好的利用DCT系数的这一特点,在这种编码技术中,并不对每个0值系数单独编码,而是将连续的0值(run)进行打包,然后再对这些连续0值系数的个数(length)进行编码。
为了更大程度的利用run-length编码的特点,需要对8x8系数矩阵进行zig-zag扫描,保证先对低频系数分量进行编码,然后再对高频系数分量进行编码,这样做的目的是因为在高频系数分量中出现大量连续0值系数的概率更高。
Run-length编码完成后即进行变长编码(VLC),在变长编码中,每个可能出现的数据值作为一个符号(例如每种可能run-length值作为一个符号),出现概率大的符号值用比特数更少的码字表示,出现概率小的符号值用比特数更多的码字表示,变长码相对于定长码使用的比特数更少,(定长码是一种直接编码方法,例如直接将每个量化后DCT系数编码为其二进制表示),因此变长码在编码一幅图像时所消耗的平均比特数更少。在变长码编码中,哈夫曼编码是一种广泛使用的编码方法,基于每个符号的发生频率,哈夫曼编码可以获得更优的编码效果。
理论上,对一组符号序列来说,变长编码并不是最优的编码方法,相对于变长编码来说,“算术编码”的编码比特数更少,编码效果更好。变长编码为每个符号分配单独的码字,因此每个符号都需要整数个比特个数(即每个符号至少占用1个比特),算术编码将一组符号序列作为一个整体来进行编码,因此并不是每个符号都需要占用比特,因此可以获得更大的压缩率,但是算术编码的运算法杂程度远远大于变长编码,因此只在最近的一些商用视频压缩算法中获得应用,相对于算术编码,在很多应用中,run-length编码和变长编码的组合编码方法相对于算术编码运算复杂程度低,编码效率足够,因此时至今日变长编码仍然在大量的视频压缩协议中广泛应用。
变长编码通过对码字和其长度的查找表实现,完成查找后将码字取出填充进比特流输出,对应的解码端过程称之为变长解码(VLD),最直接的变长解码做法需要对每一个比特都要进行查表操作和判决,相对于变长编码对每一个符号所进行的查表操作来说,这种变长解码的方法运算量更加密集,平均每个比特需要进行11步操作,因此变长解码的处理性能需求是和解码器的解码码率成正比的,对于一些低分辨率和低码率的视频序列来说,变长解码往往占到整个解码器应用时处理器性能的25%。
在一个典型的视频解码器中,上文所描述的这种最直接的变长解码方法需要占用数KB大小的存储空间用于存放查找表,为了获得更高的解码性能,可以采用一次处理一批比特的做法,当然,这种做法需要付出更大存储空间的代价。
变长编码的缺点在于,当编码后的图像或者编码后视频帧的比特流中出现误码时,解码端将无法正确恢复误码后的图像部分,一旦出现误码,解码端就无法识别误码所对应的正确码字的长度,因此也就无法识别下一个正确码字在比特流里的起始位置,也就无法继续解码图像。一种技术可以部分解决这个问题,该技术在编码比特流中预先插入“重同步标志”,重同步标志的插入位置和内容是事先定义好的,因此解码端在解码过程中能够对重同步标志进行正确定位,因此当误码发生的时候,解码器可以从误码位置向后搜索下一个重同步标志,然后可以从这个重同步标志以后解码出后续的图像部分。
此外,在MEPG4视频压缩标准中,还采用了称为“反向变长码”的技术,在反向变长码中,码字的选择保证了其不但能够从普通的正向进行解码,同时也能够从反向进行解码,因此当误码发生的时候,解码端可以向下搜索下一个重同步标志,搜索到了以后,再从重同步标志的位置反向解码至误码位置,因此解码端能够尽可能多的恢复图像数据。
到此为止,上面描述的所有技术都是针对一个独立的8x8的像素块,一幅图像所包含的信息远大于一个8x8像素块所能包含的信息,因此利用相邻块彼此的相关性可以应用更多更有效的压缩方法。
为了利用块与块之间的相关性,可以采用预测的技术,编码器在对DCT系数进行量化之前,可以基于周边块的DCT系数预测当前块的DCT系数,然后对预测值和当前实际值的差值进行量化,而不是直接对当前DCT系数进行量化,由于这个差值往往比较小,因此这项技术可以减少对DCT系数编码的比特数,对于解码端,采用相同的预测方法,然后将从码流解码出来的差值加上预测出来的预测值,就可以重构出实际的DCT系数值,需要注意的是,由于解码端只能够获得那些在当前块解码前已经解码的块的DCT系数,因此编码端必须保证只用到那些在编码当前块之前已经编码的块的DCT系数作为预测值。
对于最简单的情况,只对每个块的第一个系数进行预测,这个系数被称作“DC系数”,它代表DCT系数里的最低频分量,等于所有块像素的均值,其余的系数被称作“AC系数”。这种最简单的做法是基于这样的假设,即当前块的DC系数等于左边相邻块的DC系数,这种做法利用了当前块和左边相邻块的空间相关性,对当前块和前一编码块的DC系数的差值进行编码,被称为“DC系数差分编码”,在JPEG图像压缩标准中得到了广泛的应用。
也有一些更为复杂的预测方法,例如对8x8块的每一行和每一列的第一个DCT系数进行预测,这样的方法被称作“AC-DC预测”,同上面所描述的差分编码的方法相比,这种方法采用了更为复杂的预测方法,首先,对预测值的计算采用了滤波的方法,而不是简单的等于相邻块对应的系数,其次,预测值的产生可能要考虑多个相邻块,预测值可能是基于多个块预测值的组合,同样,编码器会从多个预测块中选出一个来获得最好的预测效果,这样的话编码器就必须在码流中表明哪一个相邻块被选中,这样解码器才能够进行同样的预测过程正确重构DCT系数。
关于色彩
彩色图像通常用几个“色彩层”来呈现。例如,RGB彩色图像包含红色层、绿色层和蓝色层。每一个层包含单一色彩(红色、绿色或蓝色)的整个图像。当这三层重叠或混合后,将组成全彩图。为将彩色图像进行压缩,本文描述的静态图像压缩方法将依次应用到每个色彩层。
视频压缩应用通常使用一种色彩层不对应特定色彩的色彩方案。通常是,一个色彩层包含亮度信息(彩色图像中每个像素的总亮度),两个层包含色彩(色度)信息,色度信息与亮度信息结合起来可以得到每个图像像素特定红、绿和蓝色彩。
这样的色彩方案非常方便,因为人眼对亮度比对色度更敏感,因此色度层的编码和存储图像分辨率都比亮度信息更低。特别是视频压缩算法通常对色度层的垂直和水平编码的分辨率都仅为亮度层的一半。因此,在亮度层中的每个16 x16像素区域内,每个色度层包含一个8x8像素的块。在典型的视频压缩算法中,“宏块”为视频帧中的一个16x16像素的区域,该宏块包含4个8x8亮度块,以及两个对应的8x8色度块。宏块允许采用后面介绍的运动估计和补偿,这两个技术将与上面介绍的色度层次采样结合使用。
增加运动因素
使用上面介绍的方法,像JPEG这样的静态图像压缩算法可以在压缩率为10:1的条件下获得很好的图像质量。最先进的静态图像编码器在压缩率高达30:1下也能获得很好的图像质量。视频压缩算法采用运动估计和补偿可以利用连续视频帧之间的相似性。这样可以使视频压缩算法在压缩率达200:1的情况下获得很好的视频质量。
在某些视频场景下,例如新闻节目中运动图像很少。在这种情况下,每个视频帧中的8x8像素的块大部分与前一帧是相同的,或者接近相同。压缩算法通过运算两个帧之间的差异性可以利用这一事实,利用上面介绍的静态图像压缩方法来对这种差异性进行编码。对于大部分图像块来说,这种差异性很小,与单独对每个帧进行编码相比,这种方法需要的编码数据位非常少。然而,如果摄像机是进行摇摄的或者场景中某个大的物体在移动,那么每个块将不再与前一帧中对应块相同。相反,与前一帧中8x8像素区域相似的块位置发生了偏移,产生了与运动方向对应的一个距离。值得注意的是,每个视频帧通常由两个色度层和一个亮度层组成,如上面所述。很显然,每个层的运动情况是相同的。尽管亮度和色度层的分辨率不同,为利用这种事实,以宏块而不是以三个层中单独的8x8像素块进行运动研究。
运动估计和补偿
运动估计是尝试发现在前一编码帧(称为“基准帧”)中的一个与当前帧中每个宏块紧密匹配的区域。对于每一个宏块来说,运动估计产生一个“运动矢量”。运动矢量是由当前帧中宏块相对于所选择的16x16像素区域的基准帧中位置的水平和垂直偏移组成。视频编码器通常使用VLC来对视频码流中的运动矢量进行编码。所选择的16x16像素区域被用于当前宏模块中像素的预测,使用上面介绍的静态图像压缩方法来进行宏块之间的差异以及所选择区域(预测误差)的运算和编码。绝大多数的视频压缩标准允许在编码器不能发现宏块的足够好的匹配时,忽略这种预测。这时,对宏块本身进行编码,而不是对预测误差进行编码。
值得注意的是,基准帧并不总是连续视频帧中的前一个显示帧。视频压缩算法通常对帧的编码顺序与他们显示的顺序是不相同。编码器可能向前跳过几个帧,对未来的帧进行编码,然后跳回来,对显示序列中的下一个帧编码。之所以这样做,是因为可以利用编码的未来帧作为基准帧向后及时地实现运动估计。视频压缩算法还可以使用两个基准帧—一个是前面已显示的帧,一个是前面已编码的未来帧。这样允许编码器从任意一个基准帧中选择一个16X16像素的区域,或者在前面显示帧的16X16像素区域和未来帧的16X16像素区域之间通过插值方法预测一个宏块。
依赖前一个编码帧来对每一个新帧解码进行修正的一个缺点是,一个帧的传递错误会使每个紧随而来的帧不能重建。为缓解这个问题,视频压缩标准偶尔只使用静态图像编码方法对一个视频帧进行编码,而不需依赖于前一个编码帧。这些帧就成为“内帧”(或I frame,即I帧)。如果压缩码流中的一个帧因为错误而被破坏,视频解码器必须等到下一个I帧,这种方法就不需要基准帧来进行视频重构。
仅仅使用前一个显示的基准帧来编码的帧被称为“P帧”,同时使用前一个显示帧和未来帧作为基准帧进行编码的帧称为“B帧”。在通常的场景中,编解码器编码一个I帧,然后向前跳过几个帧,用编码I帧作为基准帧对一个未来P帧进行编码,然后跳回到I帧之后的下一个帧。编码的I帧和P帧之间的帧被编码为B帧。之后,编码器会再次跳过几个帧,使用第一个P帧作为基准帧编码另外一个P帧,然后再次跳回,用B帧填充显示序列中的空隙。这个过程不断继续,每12到15个P帧和B帧内插入一个新的I帧。例如,图1种给出了一个典型的视频帧序列。
图1:典型的I、P和B帧序列。
视频压缩标准某些时候限制运动矢量的水平和垂直分量,这样在运动估计时每个宏块和所选择的16x16像素区域之间最大可能的距离会远小于帧的宽度或高度。这种限制轻微地减少了对运动矢量进行编码所需要的数据位数,也减少了执行运动估计所需要的运算量。包含在允许的运动矢量中的所有可能的16x16像素区域的基准帧部分被称为“搜寻区域”。
此外,先进的视频压缩标准允许运动矢量具有非整数的值。即,编码器可能估计针对某个指定宏块当前帧与基准帧之间的运动距离不是整数个像素。运动矢量的分辨率为半个或四分之一个像素很常见。因此,为预测当前宏块中的像素,必须对基准帧中的对应区域进行插值处理来估算出在非整数像素位置的像素值。按上面介绍的方法对预测与实际像素值之间的差值进行计算并编码。
运动估计是图像压缩应用中运算量非常大的任务,需要视频编码器80%的处理能力。最简单彻底的运动估计方法是在搜寻区域中评估每一个可能的16x16像素区域,选择最匹配的。通常,利用“绝对差异值之和”(SAD)或“平方差异值之和”(SSD)运算来确定一个16x16像素区域与一个宏块到底有多匹配。通常只对亮度层进行SAD和SSD运算,但是也可以包括色度层。例如,一个48x24像素的相对较小搜寻区域可能包括分辨率为?像素的1024个16x16区域。仅对这样一个区域的亮度层进行SAD运算需要做256次减法、256次绝对值运算以及255次加法运算。因此,还不包括非整数运动矢量所要求的插值处理,要进行最佳的匹配,这样的搜寻区域进行彻底的扫描所需要的运算单个宏块需要785,408次算术运算,这相当于在CIF分辨率(352x288像素),帧率为每秒15帧下,每秒4.6亿次算术运算。
由于这种高运算量,运动估计的实际实现并不适用彻底搜寻。相反,运动估计算法使用各种方法来选择有限数量的备选运动矢量(大多数情况下大约10到100个矢量),只对与这些备选矢量对应的16x16像素区域进行评估。一种方法是在几个阶段来选择备选运动矢量。例如,可能选择5个初始备选矢量,并进行评估。结果用来清除搜寻区域中不可能的部分,对搜寻区域中最有可能的部分进行处理。选择5个新的矢量,并重复这种处理。通过几次这样的过程,就可以得到最佳的运动矢量。
在视频序列中的当前帧和前一帧中针对周边宏块所选择的运动矢量的另一种分析方法是试图预测当前宏块中的运动。根据这种分析来选择一些备选的运动矢量,并只对这些矢量进行评估。
通过选择一个较少的被选矢量而不是对搜寻区域的彻底扫描,运动估计的运算需求可以大大地减少,某些时候超过两个数量级。值得注意的是,在图像质量/压缩率和运算量之间具有一种折衷关系:使用更多的运动矢量允许编码器在基准帧内找到一个16x16像素的区域,这些区域能更好地匹配每一个宏块,这样减少预测误差。因此,增加被选矢量允许预测误差以更少的数据位或者更高的精度进行编码,而代价就是执行更多地SAD(或者)SSD运算。
除了上面描述的两种方法外,还有很多其他选择适当备选运动矢量的方法,包括各种的专有解决方案。大多数视频压缩标准仅仅规定了压缩视频码流的格式以及解码步骤,而对编码过程无定义,因此编码器可以采用各种方法来进行运动估计。
运动估计方法是那些符合相同标准的视频编码器实现之间的最大差异。运动估计方法的选择大大地影响了运算要求和视频质量,因此市场上提供的编码器内的运动估计方法细节常常是严格保守的商业秘密。
很多针对多媒体应用的处理器都提供了加速SAD运算的专门指令,或者专用的SAD协处理器来从CPU转移这种需要大量运算的任务。
值得注意的是,为了执行这种运动估计,除了当前帧以外,编码器必须在存储器中保留一个或两个基准帧。所需要的帧缓存通常都比片上可提供的存储器大很多,在很多应用中都需要额外的存储器芯片。将基准帧存储在片外存储器中导致要求编码器非常高的外部存储器带宽,尽管大的片上缓存有助于大大减少所要求的带宽。
某些视频压缩标准允许每个宏块被分割成两个或四个部分,每个部分有一个独立的运动矢量。与一个运动矢量相比,这种选择需要更多的数据位来对两个或四个部分进行编码。然而,如果增加的运动矢量能更好地预测宏块像素,则对每个预测进行编码所需要的数据位更少,这又是很有益的。
运动补偿
在视频编码器中,运动补偿利用在视频码流中被编码的运动矢量来预测每个宏块中的像素。如果运动矢量的水平和垂直分量都是整数值的话,预测的宏块就仅仅是基准帧中16x16像素区域的一个拷贝。如果运动矢量的任意个分量具有非整数值,则需要用到插值来估计非整数像素位置的图像。然后,对预测误差进行编码,并加入到预测宏块中以重构实际的宏块像素。
与运动估计相比,运动补偿的运算需求小很多。尽管运动估计必须对每个宏块的若干16x16像素区域执行SAD或SSD运算,运动补偿仅对这样的区域进行拷贝或插值处理。由于这样的重要差别,视频解码的运算量比视频编码少很多。而且,在视频解码器中,运动补偿可以依然占用达40%的处理器性能,尽管这个数字对于不同的视频序列、视频压缩标准和解码器的实现来说会有很大的差别。例如,对于很少使用插值的帧的运动补偿工作载荷可能只占解码器的处理性能的5%。
与运动估计相似,运动补偿需要视频解码器在存储器中保存一个或两个基准帧,通常需要外部存储器芯片来实现这个目的。然而,运动补偿比运动估计更少地访问基准帧缓存。因此,存储器带宽要求没有运动估计那么严格,尽管为了在运动补偿功能中获得更佳的处理器性能,依然希望有高的存储器带宽。
减少视频瑕疵
马赛克与环状瑕疵
理想情况是,有损耗的图像和视频压缩算法仅仅丢弃那些视觉并不重要的信息,因此人眼重构的图像和视频序列和原来未压缩的图像或视频是相同的。然而实际上,依然可能出现某些视觉上可见的瑕疵。由于编码器的设计并不完美而出现这种问题,视频内容的编码尤其具有挑战性,或者针对视频序列分辨率和帧率所选择码率太低。后面的这种情况尤其常见,因此很多应用必须权衡视频质量与减少存储和带宽要求之间的矛盾。
视频压缩中“马赛克”和“环状”瑕疵最为常见。马赛克是由于压缩算法将每个帧分割成8像素x8像素的块造成。每个块在重构时都在邻近边缘有一些误差,使得块边缘可见。环状瑕疵是由于编码器在量化高频DCT系数时丢弃太多的信息所致。环状瑕疵的表现为在图像特征的边缘出现失真。
解决马赛克和环状瑕疵的图像滤波器
视频压缩应用通常在解压缩之后采用滤波器来减少上述的瑕疵。这些滤波步骤被称为去马赛克和去环处理。它们都利用了低通FIR(有限脉冲响应)滤波器来隐藏这些可见的瑕疵。去马赛克滤波器应用到图像块的边缘,将每个块的边缘与其相邻的块的边缘进行混合,以此来隐藏这些马赛克瑕疵。去环处理通常使用一个自适应滤波器,该滤波器首先检测到图像特征的边缘。然后对邻近检测边缘的区域进行低通滤波,从而消除环状瑕疵,但是边缘像素本身并没有被滤除,或者很少地被滤除,以避免出现模糊。
这两种滤波器都需要很大的运算量。这些滤波器结合使用会比视频解码器本身占用更多的处理器处理性能。例如,针对ARM9E通用处理器内核进行过优化的一个MPEG-4简单规格、第一级(176x144像素,15fps)解码器在对一个中等复杂度的视频流进行解码时,需要处理器的指令周期运行速率为14MHz。如果增加去马赛克处理,处理器必须运行在33MHz。如果同时要求两种处理,则处理器必须运行在39MHz条件下—几乎是单独视频解压缩算法的时钟速率要求的三倍。
后处理与在线实现的比较
这两种滤波器可以作为一个独立于视频解压缩的单独后续处理步骤用在视频帧上。这种方法为系统设计者提供了针对他们的应用选择最佳的去马赛克和/或去环滤波器的灵活性,或者完全放弃这两种滤波器以降低运算需求。在这种方法中,视频解码器利用每个未滤波的重构帧作为对未来的视频帧进行解码的基准帧,最后的滤波视频输出还需要一个额外的帧缓存。
另外一种方法是将去马赛克和/或去环状瑕疵功能整合到视频解压缩算法中。这种方法某些时候称为“环形滤波”,利用滤波后的重构帧作为基准帧来解码未来的视频帧。这种方法要求视频解码器像编码器那样执行相同的去马赛克和/或去环状瑕疵滤波,以使每个用于编码的基准帧与用于解码的一样。需要在编码器中进行滤波处理增加了对处理器的性能要求,但是可以提高图像质量,特别是当码率很低的时候。此外,当去马赛克和/或去环状瑕疵功能作为一个独立的后续处理步骤实现时需要的额外帧缓存,而整合到压缩算法中则不需要。
色彩空间转换
正如前面所述,视频压缩算法通常利用亮度和色度层来展现彩色图像。不同的是,摄像机和显示器通常将红色、蓝色和绿色光混合来展现不同的颜色。因此,摄像机捕捉到的红、绿、蓝像素必须转换成亮度和色度值以进行视频编码,视频编码器的亮度和色度像素输出必须转换成特定的红、绿、蓝电平进行显示。这种转换方程每个图像像素需要12个算术运算,还不包括用于补偿在视频压缩算法的输入和输出中色度层比亮度层具有更低的分辨率所需要插值运算。对于每秒15帧CIF(352x288 像素)的图像分辨率来说,转换(没有任何插值运算)需要每秒1,800万次运算。这种运算量相当大;如果用软件来实现,色彩转换大约需要视频解码器所需要的处理器周期的三分之一或三分之二。
趋势与结论
视频压缩算法采用了多种技术,例如运动估计、转换和可变长度编码。尽管大多数当前的视频压缩算法共享这些的基本任务,在算法和实现方法上存在大量的变化。例如,在不同的编码器中,甚至即使符合相同的压缩标准,执行运动估计的算术方法和实现方法都可能不同。此外,对于某个信号处理任务来说,最有效的实现方法对于不同的处理器来说也可能有很大的差别,即使每个处理器使用一种相似的算法。最后,某些任务的运算量,如运动补偿,根据不同的视频节目内容变化很大。因此,在某个特定的处理器上,视频编码器或解码器的运算负担很难以预测。
尽管有这些可变性,依然可以很容易地发现几个趋势:
- 运动估计是视频压缩处理中运算需求最大的任务,通常使编码器的运算负担为解码器的几倍。
- 解码器的运算负担通常决定于可变长解码、逆转换和运动补偿功能。
- 运动估计、运动补偿、转换和量化/去量化任务的运算负担通常与每个帧的像素数量和帧率成正比。不同的是,可变长解码功能的运算量与压缩视频码流的码率成正比。
- 在解码后的视频流中应用的后处理步骤,即去马赛克、去环状瑕疵以及色彩空间转换都大大地增加了视频解码应用的运算负担。这些功能的运算负担会很容易地超过视频压缩步骤,与每个帧的像素数量以及帧率成正比。
相比于运算量的预测,视频压缩应用的存储器要求的预测容易得多:在视频压缩应用中,存储器主要取决于用于存储当前和基准帧的大容量缓存。如果压缩方案支持I-和P-帧,只需要两个帧缓存;如果还支持B-帧的话,则需要三个缓存。像去马赛克、去环状瑕疵、色彩空间转换的后处理步骤可能需要另外的输出缓存。这些缓存的大小与每个帧的像素数量成正比。
与像程序存储器、查找表以及中间数据等因素相结合,组成通常视频应用的存储器需求的重要部分,尽管这个部分通常只有帧缓存存储器的几分之一。
实现高度优化的视频编码和解码软件需要彻底地理解本文介绍的目标处理器的信号处理概念。大多数的视频压缩标准不会规定运动估计的方法。尽管基准编码器适合于大多数的标准,深入了解视频压缩算法通常允许设计师利用更多成熟的运动估计方法,并获得更好的结果。此外,全面理解信号处理原理,实现信号处理功能,以及了解目标处理器的细节知识对于有效地将视频压缩算法中的各种任务对应到处理器的结构资源来说是非常重要的。
