背景技术
在例如视频会议、网络会议、TV广播和视频电话的若干应用中采用运动画面的实时传输。
然而,因为通常通过使用8个比特(1字节)表示画面中的每个像素来描述数字视频,所以表示运动画面需要大量的信息。这样的未压缩的视频数据导致大的比特量,并且由于有限的带宽而导致无法通过常规的通信网络和传输线来实时传送这样的未压缩的视频数据。
因此,支持实时视频传输需要很大程度的数据压缩。然而,数据压缩可能损害画面质量。因此,已经进行了很大的努力来开发允许通过带宽受限的数据连接来实时传送高质量视频的压缩技术。
在诸如MPEG-*、H.26*和SMPTE-VC-1的多种视频解码/编码标准之间,若干算法能力是常见的。去块化滤波和运动估计/补偿是视频编码所需要的一般算法的两个典型示例。
在视频画面的块样部分上执行编码。宏块包括用于亮度(luma)以及用于色度(chroma)的若干子块。
已经证明基于块的编码/解码很有效。然而,缺点之一是重建的图像可能包括与用于预测和残差信号编码的块相对应的可视伪像。该现象通常被称为块化(blocking)或块化伪像。
减少块化伪像的一种方法是在编码循环中集成去块化滤波器,这是在规范ITU-T Rec.H.264|ISO/IEC 14496-10 AVC中的优选解决方案。这种编码集成解决方案是非常占用处理器时间的,因为它对于与块边缘相交的每个像素线需要测试过程,以使得平滑。
虽然去块化滤波器本身并不复杂,但是在滤波过程期间,滤波算法需要存取被重建画面帧的几乎每个像素。因此,去块化运算非常占用处理器时间。
对于HD格式的视频编码提高了对于存储器和数据处理的要求,并且需要与计算密集能力相结合的有效和高带宽的存储器组织。由于这些多个要求,必须找到灵活的并行处理方式来以成本有效的方式满足这些要求。
为了有效地支持去块化滤波算法和其他复杂可编程功能(在多种标准中,在要求上可能有所变化),处理器本身可能要求高的并行度和很高的时钟速率以满足要求。可能难以为商业产品以成本效率的方式开发该能力的处理器。
在许多情况下,去块化滤波是在编码过程和解码过程(特别是对于如在HD的情况下的高分辨率图像)中的主要瓶颈之一。
当在每个宏块上发生滤波时,其中首先执行垂直边缘的水平滤波,并且接下来执行(水平边缘的)垂直滤波,在移到下一个宏块之前,必须对每个宏块进行两个方向的滤波。
通常在带有基于DSP的处理器的视频端点中的定制硬件上安装视频编解码器。然而,近来,在具有SIMD处理器环境的通用处理器中安装视频编解码器变得更加普遍。当在典型的通用处理器中实现时,每个宏块通常必须从RAM向在CPA中的寄存器加载两次,一次用于垂直去块化滤波,一次用于水平去块化滤波,并且可能以若干效率低和小的步骤来转置(transpose)每一个宏块。因为涉及加载远距离存储器参照,所以这在计算上特别有要求。
具体实施方式
本发明提供了一种实现去块化滤波器以减少在通用处理器中的视频图像中的伪像的方式,该方式特别适合于在规范ITU-T Rec.H.264|ISO/IEC 14496-10 AVC中描述的现有技术方法,下面描述其基础。
在H.264/AVC中,在编码循环中应用自适应去块化滤波器。这表示对于滤波的图像执行进一步的预测。滤波器被设计为移除尽可能多的块化和量化噪声,并且仍然保留尽可能多的图像内容。分离量化噪声和画面内容通常是个挑战。这就是为什么滤波器是高度内容适应的,并且因此在计算运算上是复杂的。
在图1中,示出了在两个画面块之间的边缘。字母c和d表示在边缘每侧的两个相邻像素位置,并且其他字母表示最接近这两个首先提及的像素的4个水平像素位置。根据H.264/AVC,可以基于像素中的每一个的值并且基于边缘本身的特性来修改像素b、c、d、e。该修改用于均衡上述伪像。因此,仅当伪像有可能发生时才执行这种修改。
对于所有的线a、b、c、d、e、f执行类似的滤波运算。在下面的描述中,将在没有编号0-7的情况下使用这些字母。
根据H.264,对边缘定义强度值(Str)。这种强度值反映伪像是否有可能在两个块之间发生,并且取决于检测到下面的情况中的一个或多个:
在边界每侧上的两个块中的任何一个是否是帧内编码的,即,基于在当前画面中已经编码的块来编码的。
在边界每侧上的两个块中的任何一个是否包括非零转换系数。
用于预测在边界每侧上的块的运动向量的大小是否超过特定阈值。
而且,向每一个4x4块指配量化参数(QP)。表示边缘的QP是表示2个块的QP的最大值。
使用若干QP相关的阈值参数:
α(QP)
β(QP)
γ(QP,Str)
α、β和γ在图2和图3中所示的查找表中找到。图1示出了用于确定α、β的查找表,并且图3是用于确定γ的查找表,γ是限幅值。这里,索引A和索引B表示QP,并且bS=1、2、3分别与上面列出的判据c、b、a相对应。因此,确定判据a、b、c也陈述了边界特性。
基于这些值,执行主测试以确定是否要执行去块化滤波。
仅在下述情况下执行滤波:
|c-d|<α(QP)并且|b-c|<β(QP)并且|d-e|<β(QP)
如果上面的陈述成立,则计算德耳塔Δ:
Δ=(b-4c+4d-e)/8
然后,在范围(-γ,γ)内对该德耳塔值进行限幅。作为限幅的示例,如果量化值是32,并且边界的特性符合与bS=2相对应的判据b,则该表指示γ是2。这暗示应当在区间{-2,2}内对德耳塔进行限幅。即,当德耳塔大于2时,对德耳塔指配值2,当德耳塔小于-2时,对德耳塔指配值-2,并且当德耳塔位于{2,2}内时,德耳塔保持不变。
然后,使用德耳塔来计算修改值:
c′=c+Δ
d′=d-Δ
执行另一个测试以判定是否也要校正b:
|a-c|<β(QP)
如果这成立,则计算值δ:
δ=(2a-4b+c+d)/2
然后将该值进一步限幅到范围(-γ′,γ′)内,其中,γ′是γ的略微修改。然后通过δ来计算b的修改:
b′=b+δ
对于e而言,测试和计算是类似的:
|c-f|<β(QP):
如果这成立,则计算另一个值δ:
δ=(2f-4e+c+d)/2
然后,将该值进一步限幅到范围(-γ′,γ′)。然后,通过δ来计算e的修改:
e′=e+δ
本发明涉及在SIMD环境中(特别是对于具有128位向量寄存器的处理器)实现去块化滤波算法等。SIMD概念是一种改善其中需要执行高度重复运算的应用的性能的方法。严格地说,SIMD是一种对于多条数据同时执行相同运算的技术。
传统地,当编程应用并且需要在大的数据集上执行单个运算时,使用循环来对数据集中的每个元素做重复,并且执行所需要的过程。在每个重复期间,在单条数据上执行单个运算。这是所谓的单指令单数据(SISD)编程。SISD通常实现起来简单,并且在以后的时间可迅速地查阅编程者的意图和方法。
然而,诸如这样的循环通常效率很低,因为它们可能必须重复几千次或甚至几百万次。理想地,为了提高性能,需要减少循环重复的次数。
一种减少重复的方法被称为循环展开,这采用在循环中执行的单个运算,并且在每次重复中将其执行多次。例如,如果循环先前执行单个运算并且进行10,000次重复,则可以通过在每个循环中执行4次该运算并且仅具有2500次重复来改善其效率。SIMD概念通过下述方式来更进一步展开循环:将多个动作并入每一个循环重复中,并且同时执行它们。通过SIMD,不仅可以减少循环迭代的次数,而且还可以将所需要的多个运算减少为单个优化的动作。
SIMD通过使用所谓的“封装向量”来实现。类同传统的编程向量或阵列,封装向量是包含多条基本数据的数据结构。然而,与传统的向量不同,SIMD封装向量然后可以被用作特定指令的参数(例如,算数运算),然后对向量中的所有元素同时执行该特定指令。因此,可以被加载到向量的值的数目直接影响性能;一次处理的值越多,完成完整数据集就越快。
当把值存储在封装向量中并且通过SIMD运算在其上发生作用时,它们实际上被移到其中发生并行处理的特殊CPU寄存器或寄存器变量的集合。这些寄存器变量的大小和数目由所使用的SIMD具体实现来确定。
决定SIMD具体实现的实用性的其他方面是指令集。指令集是SIMD具体实现提供的通过封装向量使用的一系列可用运算。这些通常包括:用于有效地向向量存储值并且从向量加载值的运算;算数运算(加、减、除、平方根等);逻辑运算(与、或等);以及比较运算(大于、等于等)。SIMD具体实现提供的运算越多,开发者执行所需要的功能就越简单。当以汇编撰写代码时,可以直接获得SIMD运算,然而在诸如C语言的高级编程语言中不是这样。
根据例如H.264/MPEG-4AVC的去块化滤波在每一个宏块上发生,其中,首先执行垂直边缘的水平滤波,随后执行水平边缘的垂直滤波。在移到下一个宏块之前,必须进行对于每个宏块的两个方向的滤波。在现有技术的软件实现的去块化中,通常将每个宏块从RAM加载到CPU寄存器变量两次,一次用于垂直滤波,一次用于水平滤波,因为这涉及加载远距离存储器参照,所以在计算上要求高。
本发明提供了一种仅要求每一个宏块一次加载的方法。所包含的步骤基本上如下:加载宏块——转置宏块——执行水平滤波——转置宏块——执行垂直滤波——存储宏块。
以这种方式,通过对于转置的宏块实际执行垂直滤波以执行水平滤波,针对每个宏块仅有一次加载和一次存储,并且垂直和水平滤波的实现变得相同。本发明的另一个益处是:通过利用向量和指令级并行的优点,利用比在去块化滤波计算中通常使用的更高级的处理器能力。本方法与所有其他公知的方法不同之处在于转置了整个宏块。通过使用在现代处理器中可获得的增强的计算资源,完整的宏块转置(如在例如F.Franchetti and M.Püschel“Generating SIMD Vectorized Permutations”In Proceedings of International Conference on Compiler Construction(CC)2008中描述的)是相对低成本的,并且所提出的方法变得特别有效。
Franchetti和Püschel描述了一种高度有效的方法,该方法采用通过向量洗牌(vector shuffle)指令实现的最小数目块移动运算来转置8x8矩阵。根据本发明的算法过程被泛化为用于亮度宏块的单个16x16转置和用于两个色度宏块的2x8x8转置。在现代处理器中,单个寄存器通常可以保存16个像素,因此,根据本发明的优选选择是计算使用16字节的指令同时对于U和V色度宏块的转置。
现代处理器包含通常包含越来越多数目的执行单元,这些执行单元常常保持空闲。在根据本发明的去块化滤波器的实施方式中,因为按照采用单指令多数据(SIMD)指令和指令级并行(ILP)的最大优点的方式来构造算法,所以所有的执行单元在大多数时间保持繁忙。
本发明的一个独特之处在于它的目标是在最佳地采用ILP的优点的环境中的执行,其中,相信其他公知的实施方式试图并行化更通用的算法。
在图4和图5中所示的流程图描述了一个亮度宏块(图4)和两个色度(图5)宏块(MB)的去块化滤波(DF)。
现在参考这些流程图,在高层描述本发明的一个实施例。首先,使用有效的16字节对齐加载来将宏块加载到16字节对齐的寄存器变量矩阵。然后,使用最小数目的块移动运算通过SIMD指令来有效地转置该矩阵。然后对于转置的宏块执行水平滤波。而且,矩阵被转置回其原始定向。使用如上所述的用于水平滤波的相同算法来执行垂直滤波。最后,将宏块存储回RAM中。
另外,表示用于计算下方的下一个宏块的水平重叠(片1)的区域以及表示用于计算右方的下一个宏块的垂直重叠(片2)的区域分别被转置和存储到存储器以供以后使用。
如上所述,在当前一代的x86微处理器中存在的单指令多数据(SIMD)指令允许在多达16个数据集上同时执行单个共同的运算。例如,当在处理器的SIMD寄存器内正确地格式化数据时,可以在16个独立的数据集上计算加法运算,同时获得16个结果,如图6中所示。执行该运算的时间成本与使用在通用寄存器上的通常的处理器指令对于单个数据集执行单个加法运算相同。
实际的处理成本发生在要对其运算的数据集的准备中。在执行水平边缘的垂直滤波的情况下,因为SIMD提供了用于使用单个指令来线性地加载16个字节的指令,能够使用单个低执行成本加载指令来加载输入数据的单一线上的所有值。
根据本发明的算法采用下述事实:处理器提供足够的寄存器空间来存储作为亮度宏块或两个色度宏块的精确大小的整个16x16的数据集。通过执行将16个线性对齐的值16次连续读入16个SIMD寄存器变量(每一个能够存储16个值)中,为运算设置的整个数据集可以被存储在处理器SIMD寄存器变量内,并且可以在没有任何存储器相关的延迟的情况下进行运算。在此,可以应用转置算法来对齐在寄存器变量内的垂直边缘,因此可作为SIMD处理的期望的内部方向的水平边缘而对其处理。在再一次存储值之前,应用第二转置运算,以将边缘重新定向到其原始位置。
替代方式可以是以更高的指令计数为代价选择性地单独加载和定位每一个像素值,以产生相同的结果。另外,因为必须还将同一数据集用于在另外定向上的处理,所以该过程在理论上是整体冗余的,因为转置运算以宏块的去块化滤波的完全匹配来渲染数据。
如已经指出的,为了把用于水平行的高性能的向量化的算法同样地应用于采样的垂直列,必须转置采样矩阵,使得把各垂直列重新对齐为各水平行。这种过程就是转置(transposition)步骤。图7和图8表示数据集,其中,采样数据的每个行被存储在单个向量寄存器变量中。图7示出当对垂直列运算时,因为采样的单个列在整个16个向量寄存器变量上布置,没有理想地定向数据集。在作为转置表示的图8中所示的示图表明了在转置该数据集之后定向对于SIMD指令如何理想,因为每列现在被存储在单个向量寄存器变量中。结果是,可以发生同时的跨列运算,现在已经为这个目的准备了数据。
虽然其他实施方式选择部分地“在运行中”转置宏块以准备SIMD友好滤波,但是本发明在一个有效步骤中转置宏块,这还便于在寄存器变量中内部存储宏块并因此使得不必加载宏块两次。显然,这还导致了水平和垂直滤波的相同实施方式,这是本发明的主要益处,因为仅垂直滤波已经被看作是SIMD友好的。
随着在视频会议中使用的源帧的分辨率提高,变得越来越难以在没有大性能损失的情况下有效地加载和存储宏块。例如,对于1080p,在16x16像素中的第一和最后字节之间的距离是~30K字节。一次一个地加载这256个字节显然不是有效的,即使所使用的存储器占用少于在现代处理器中可获得的64K字节的L1数据高速缓存。相反,根据本发明的过程使用有效的16字节对齐的加载来在16字节的大块中加载数据。
现代处理器通常可以每一个时钟周期执行2或3个16字节指令,特别是如果在同一区域中把多个独立指令组合成组。因此,处理器的异常执行核心可以以任何顺序执行独立的16次连续的16字节加载。因为独立的指令可以隐藏彼此的延迟,所以整体延迟降低。
虽然独立地加载256个字节的采样因为不需要转置运算而可能看起来有益,但是SIMD友好和高速缓存友好的执行的优点足够大,整个16x16矩阵转置的代价相比之下变得可忽略。
注意,术语寄存器变量不必然指在处理器硬件中的一个物理寄存器。可以例如以汇编代码和所谓的固有函数二者来实现本发明。例如,Intel C/C++编译器固有等价物是特殊的C/C++扩展,其允许使用C函数调用和C变量的句法而不是硬件寄存器。不保证希望在寄存器中插入的固有函数中的变量被插入实际硬件寄存器中,但是地被相应地处理并且等同地有效,如同被真的插入。术语寄存器变量因此可以被解释为物理硬件寄存器以及如同被真的插入硬件寄存器中来处理的寄存器变量。
存在与本发明相关的多个优点。除了更有效和对齐的加载之外,它还要求更少的加载——16次而不是256次。SIMD环境还提供同时加载——16次连续的16字节加载,而不是多个单次“块化”加载。因为重新使用高度有效的垂直滤波器,所以这都导致减少了对于存储器访问的需要,提高了宏块转置性能,并且提高了水平滤波性能。
在一个方面,本发明被实现为一种用于在16字节SIMD寄存器处理器环境中执行的视频编码或解码过程中对于在宏块之间的边界相邻像素执行去块化滤波运算的系统。这样的系统可以包括用于执行在上面的说明书中描述的方法的步骤的装置。这样的装置可以由包括在计算机中的处理装置来提供,该计算机例如在视频会议系统中使用的计算机。该处理设备可以被配置为执行计算机程序。该计算机程序可以包括指令,该指令使得当该处理设备执行该指令时该处理设备执行所公开的方法。该计算机程序可以确实地被包含在计算机中的存储器中或诸如磁光或固态数字存储介质的存储介质上或在可以例如在局域网、广域网或全球通信网络中的网络元素之间传送的传播信号上。