龙广主持人飘飘:H264简介

来源:百度文库 编辑:九乡新闻网 时间:2024/05/01 04:26:37
1.     H.264中的视频压缩技术
一、帧内预测模式
在帧内预测模式下,当前块在被编码之前需要与预测值相减,而这些预测值是从已编码并重构的相邻块得到的。亮度信号的帧内预测分为两种,一种是以4×4 的块为单位,共包括9 种预测方式(图 2.2);另一种是以16×16 的块为单位,共包括4 种预测方式(图 2.3)。色差信号的帧内预测以8×8 的块为单位,也包括4 种预测方式,与亮度信号16×16 的块的预测方式相似。
4×4亮度块的9种帧内预测模式
2.3  16×16亮度块的四种预测方式
其实相邻块的帧内预测模式也有很大的相关性,尤其在4×4预测模式下。令块A、B、E分别为左、上及当前块,位置关系如图 2.5。如果A、B块的帧内预测模式都是1,那么块E的最佳模式也很可能是1。编码器及解码器都需要先计算当前块预测模式的预测值,令这个预测值为A块、B块中较小的模式值。如果这个预测值与当前块的最佳模式一致,则发送的prev_intra4x4_pred_mode标志为1,否则为0。如果为0,则还需要发送一个rem_intra4x4_pred_mode的标志,具体指明采用了哪种模式。注意到此时由于当前块的模式值与预测值不一致,可以先排除掉一种模式。如果当前块的模式比预测值小,rem_intra4x4_pred_mode标志就取当前块的模式值;反之,取当前块的模式值减去1。这样一来,就可以将9种模式映射到[0,7]这个区间内,正好能用3个比特表示。
2.5  相邻块的位置关系
二、帧间编码模式
可变尺寸块、多参考帧、带权重预测和1/4像素精度是H.264运动补偿技术的四个新特征。
对于可变块大小的概念其实在H.263中已经出现过了,那就是高级预测模式,一个宏块的亮度块可以分为4个8×8子块分别进行运动估计。在H.264中提供了更多的块大小以供选择,当中包括了16×16、16×8、8×16、8×8、8×4、4×8、4×4(如图 2.6、图 2.7所示)等七种不同大小的尺寸。对于YUV420格式,由于色度块在水平方向及垂直方向密度都只有亮度块的一半,因此块的大小只有色度块的1/4。
2.6  宏块的分割方法
2.7  子块的分割方法
应当值得注意的是,虽然使用较小的块可以使得运动估计更加精确,用来表示运动残差的比特可以减少,但同时用来表示运动矢量的比特数需要增加,在实际使用时应根据运动图像的特点选择合适的模式,否则反而会使得编码效率降低。图 2.8是一幅仅有运动残差的图像。可以看到,残差的大小影响着块大小的选择。
2.8  运动残差与块大小的选择之间的关系
对多参考帧进行运动估计,优点是显而易见的。一来可以更加有效地提高运动估计的效率,二来可以增强差错的稳健性。H.264中有一套独特的参考帧管理系统,在编码器与解码器中可以有一个或两个参考帧列表,列表0用于P帧或B帧的前向预测,列表1用于B帧的后向预测。列表之中可以存放“短期”或“长期”的参考帧。在默认情况下,一个刚被解码的帧会标志为短期参考帧,短期帧按照它们的帧号进行识别,并按照帧号从高到低排列。如果一个帧指定了“长期帧编号”,它就是一个长期帧,按照它的长期帧编号进行识别,并且按照长期帧编码从低到高排列。一个长期帧一般是不会被移出参考帧列表的,除非编码器显式地指明丢弃它。当画面在两个场景中来回切换时,如果两个场景的画面都被保留下来了,就可以增强P帧的预测效果。当参考帧列表存满后,最早的一个短期帧将会被丢弃。表格 2?1演示了一个管理参考帧列表的例子。
Operation
0
1
2
3
4
Initial state
-
-
-
-
-
Encode frame 250
250
-
-
-
-
Encode 251
251
250
-
-
-
Encode 252
252
251
250
-
-
Encode 253
253
252
251
250
-
Assign 251 to LongTermPicNum 0
253
252
250
0
-
Encode 254
254
253
252
250
0
Assign 253 to LongTermPicNum 4
254
252
250
0
4
Encode 255
255
254
252
0
4
Assign 255 to LongTermPicNum 3
254
252
0
3
4
Encode 256
256
254
0
3
4
参考帧缓冲管理
多参考帧技术也有一定的弊病,一是在选择最佳参考帧的时候大大增加了运动估计的搜索量,二是要求编码器与解码器开辟更多的缓冲用来存放参考帧列表。
带权重预测是H.264中又一项新技术。这是一种修正预测块的像素值的方法。H.264中一个有三种带权重预测:
1、P Slice显式带权重预测;
2、B Slice显式带权重预测;
3、B Slice隐式带权重预测。
一旦使用带权重预测,预测块0与预测块1(B帧使用)分别需要乘尺度因子w0,w1。在显式方式下,这个权重由编码器指定,并且在条首部中传输。如果使用了隐式方式,w0和w1是根据各参考帧与当前帧的时间相关性计算得到的。如果参考帧与当前帧在时间上比较接近,它的权重就会大一些;反之,它的权重就会小一些。使用带权重预测技术可以有效地压缩令MPEG-4感到非常头痛的场景淡入淡出序列。
在H.264中,运动补偿的精度达到了1/4,比起H.263提高了一倍。在H.263中,半像素精度的像素点是经过双线性插值得到的。双线性插值虽然比较简单,但是它相当于频域上的低通滤波器,会把图像的高频分量滤掉,使得插值出来的图像精度不高。在H.264中引入了一种新的立方卷积内插方案,它使用一个六阶的FIR滤波器插值得到亮度块半像素精度的像素值,滤波器的系数为(1/32,-5/32,5/8,5/8,-5/32,1/32)。从图 2.9的频响曲线可以看出,卷积插值可以使更多的高频分量通过。如图 2.10所示,紧挨两个整数像素点的半像素点会先通过水平方向或垂直方向的卷积得到,如
b = round ((E-5F+20G+20H-5I+J)/32)
h = round ((A-5C+20G+20M-5R+T)/32)
随后,余下的半像素点才会被插值出来,如图中的像素j。一旦所有的半像素点都得到了,四分一像素点是通过半像素点或整像素点线性内插得到的。如果这个四分一像素点在两个整像素点或半像素点之间,则它的数值就是相邻两个像素值的均值;否则的话,它的数值就是对角线相邻的两个像素点的均值。(如图 2.11所示)
2.9  两种插值方法的频响特性比较
2.10  亮度块1/2像素的插值
2.11  亮度块1/4像素的插值
对于YUV420的格式,色度块的运动矢量精度将达到1/8。由于人眼对色度块的分辨力不如亮度块,因此无需采用太复杂的插值公式。H.264中使用了双线性插值来产生色度块1/8像素点,其插值公式为
图 2.12  色度块的双线性插值
三、整数变换及量化
传统的DCT变换,由于变换中存在无理数,所以无论是用整数还是浮点数来表示结果都会有精度损失,而且无理的变换系数也带来了计算复杂的问题。再加上DCT算法不统一,当中包括整型、定点型和浮点型,很容易导致编码器与解码器之间的变换不匹配,从而使得复原效果进一步变差。H.264中引入了新的4×4整数DCT变换,它是根据4×4DCT变换发展而来的。对于传统的DCT变换,其变换公式为
其中
我们分别在A的第一、第三行除以a,AT的第一、第三列除以a;在A第二、第四行除以b,AT的第二、第四列除以b,并令d=c/b,则可以推出上述变换的等价形式
式中的 是这个二维变换的核, 是一个尺度伸缩因子矩阵, 符号表示对应位置上的系数相乘。可以计算出

直接令d=1/2。但是为了保持变换的正交性,系数b、c也要作相应的调整。由于当d=1/2时
所以可以推出
因此
我们知道,如果一个整数跟2相乘后再除以2,这个转换过程是不会产生误差的;但是反过来先除以2后乘以2,对于奇数来说它就会有1的转换误差。为了避免这种乘除转换误差,需要将变换核C中的第2行、第4行以及CT的第2列、第4列乘以2,同时尺度伸缩因子矩阵 相应地缩小以给与补偿。最终得到的整数DCT正变换的公式
可以看出,变换核矩阵C中所有的系数要么为±1,要么为±2。在参考程序JM中给出了做一次行变换的快速算法
中间变量y[4]
y[0]=x[0]+x[3]
y[1]=x[1]+x[2]
y[2]=x[1]-x[2]
y[3]=x[0]-x[3]
变换结果z[4]
z[0]=y[0]+y[1]
z[1]=(y[3]<<1)+y[2]
z[2]=y[0]-y[1]
z[3]=y[3]-(y[2]<<1)
做一次行变换仅需要做8次加减法及2次左移,因此完全避免了转换过程中数据精度的丢失,可以保证正反变换的完全匹配;而且无需作乘除运算,也降低了运算复杂度;再者由于输入矩阵X的系数在±255之间,因此整数变换的中间及最后结果不会超过16位整数所能表示的范围,可以节省存储空间;最后还有一点,尺度伸缩这一步可以融合在量化的过程中,可以节省乘法运算的次数。
然而在H.26L还处于试验阶段的时候,当时提出的整数变换公式为
相比之下,当初方案的虽然也是整数运算,可以避免转换过程中的精度丢失,但是乘法运算就不能避免了;而且正反变换过后,X矩阵被放大了676倍,16位的整数就放不下运算结果了,必须用32位整数,存储空间也多需一倍。
正式的H.264方案中的反变换公式为
反变换同样只需要加减及右移运算就能完成了。而且由于反变换之前矩阵Y要先经过尺度放大,每一个系数都要乘以64,因此右移的精度损失很小。在参考程序JM中给出的快速算法为
中间变量y[4]
y[0]=x[0]+x[2]
y[1]=x[0]-x[2]
y[2]=(x[1]>>1)-x[3]
y[3]=x[1]+(x[3]>>1)
最终结果z[4]
z[0]=y[0]+y[3]
z[1]=y[1]+y[2]
z[2]=y[1]-y[2]
z[3]=y[0]-y[3]
做一次反变换也仅需要8次加减法以及2次右移运算。
经过变换后的残差系数需要进行量化来进一步缩小表示所需要的范围。量化的一般表达式为
其中 是经过变换的块中的系数, 是量化后的系数, 是量化步长。
在H.264中,量化步长有多达52种不同的选择,这52种步长用一个QP(Quantization Parameter)值作为索引。每当QP的值增加6时,量化步长 增加一倍。
在上面曾提到一个问题,一个完整的整数变换应包括与变换核C矩阵相乘以及与尺度伸缩因子矩阵 对应位置的值相乘两步,而后面一步在H.264中融合在量化的过程中了。所以完整的量化过程为
PF就是矩阵E中的 等,取哪个值取决于i,j的取值,即系数在矩阵中的位置。为了简化计算,在H.264的参考实现程序JM中将量化的过程变成了另一种形式,先乘以一个系数MF,然后再作右移运算,避免了做除法(因为CPU计算除法相当耗时),公式为
因此可以推出WF、qbits与PF、Qstep之间的关系
同时令
在JM中,量化的整数实现形式为
上式中的 因子决定了结果是几舍几入。例如要四舍五入的话, 要取 。在JM中,事先将 在 下的值算出来,放在一个表中,因此我们可以直接获得这些情况下WF的值。当 时,由于前面提到过了,QP每增加6, 就扩大一倍,所以WF无需改变,只要改变qbits,即QP每增加6,qbits加1就行了。
H.264反量化的公式为
其中PF是反变化尺度矩阵 中的 ,这取决于 的位置,乘以64是为了扩大量化因子的范围,使之能够用整数来近似表示。在JM中也事先将 在 下的值算了出来,放在一张表中。同样地当 时,QP每增加6, 就扩大一倍, 相应地多左移1次。
图 2.13  宏块中残差子块
当宏块采用了16×16帧内预测时,对于一个宏块中的16个4×4亮度块,或者4个4×4的色差块,其直流DC系数间的相关性还是很大的。在H.264中使用了4×4与2×2的哈达马变换来近一步消除DC系数间的相关性。其中4×4的哈达马变换公式为
而2×2的哈达马变换公式为
四、熵编码
在H.264中一共有三种熵编码方式,包括了指数型-哥伦布编码、CAVLC以及CABAC。前两者都属于变长编码,而后一种属于算术编码。
在介绍指数型-哥伦布编码之前,先介绍一下在H.26L草案中使用的UVLC编码。先产生一个VLC编码表,其码字的产生方式为
1
0  1
0  0  1
0  0  0  1
……
这是一个金字塔形状的编码表,当中的 可以取0或者1。令码字的长度为L, ,则INFO的长度为L/2。编码的码字序号可以表示为
按这种规则构造出来的码表为
码字序号
码字
0
1
1
001
2
011
3
00001
4
00011
5
01001
6
01011
7
0000001

……
在H.264的正式方案中使用的是指数型-哥伦布编码,抛弃了UVLC编码。它们两者之间是非常相似的,指数型-哥伦布编码的码字产生方案为
……
与UVLC相比,指数型-哥伦布编码只是将固定码字区域与INFO区域改了一下位置而已,而Code_number、INFO、L之间的对应关系并没有改变。很明显,指数型-哥伦布编码的码字构造规则更为简单,因为无需进行INFO区域与固定码字区域的穿插。它构造出来的码表为
码字序号
码字
0
1
1
010
2
011
3
00100
4
00101
5
00110
6
00111
7
0001000

……
在实际使用指数型哥伦布编码前还需要对被编码的元素做一次映射,映射成编码码字序号。映射的方式包括了:
a)         无符号数映射
该映射方式使用在宏块类型、色差块帧内预测模式等参数上。编码码字序号等于被编码元素,即
b)        有符号数映射
该映射方式使用在运动矢量增量、量化步长增量等参数上。编码前需要先进行一次有符号数到无符号数的映射,从而得到编码码字序号。映射规则为
c)        切断型映射
在使用该方式时,需要首先确定被编码元素所能赋值的范围,从0到x,其中x大于或等于1。如果x>1,则按普通无符号数方式进行映射;如果x=1,则编码得到的码字是一个比特的编码元素取反,即1对应0,0对应1。
d)        映射表映射
该映射方式使用在coded_block_pattern参数上,根据事先设定好的映射表进行映射。该表设计的原则是使最常见的方式使用最短的码字。
coded block pattern (Inter prediction)
code num
0 (no nonzero blocks)
0
16 (chroma DC block nonzero)
1
1 (top-left 8 × 8 luma block nonzero)
2
2 (top-right 8 × 8 luma block nonzero)
3
4 (lower-left 8 × 8 luma block nonzero)
4
8 (lower-right 8 × 8 luma block nonzero)
5
32 (chroma DC and AC blocks nonzero)
6
3 (top-left and top-right 8 × 8 luma blocks nonzero)
7
……

在H.264的Baseline Profile中,对于运动矢量增量、量化步长增量、宏块类型等参数,使用指数型-哥伦布编码。而对于变换、量化后的残差系数,指定使用CAVLC(Context-Based Adaptive Variable Length Coding)编码。
CAVLC编码是基于残差系数的下列特征设计的
l         经过预测、变换及量化后,块中的大部分系数为0。CAVLC使用游程编码来跳过大部分的0;
l         经过Zig-Zag扫描后的系数常常是一个由±1构成的序列(称为Trailing Ones)。CAVLC中仅使用符号位来表示±1序列,简洁高效;
l         相邻块的非零系数的个数常常是相关的。CAVLC中残差系数的个数是通过查表来进行编码的,相邻块非零系数的个数决定了选用哪个码表;
l         经过变换后的系数经常是低频的幅度大,高频的幅度小。CAVLC在编码残差系数时,能根据最近被编码的系数的幅度,自适应地改变所选用的码表。
而整个CAVLC编码过程为
1、编码块中非零系数的个数及±1的个数
块中非零系数的个数及±1的个数联合决定了CAVLC中第一个参数COEFF_TOKEN。非零系数的个数可以从0到16,而±1的个数可以是从0到3。如果±1的个数超过了3个,只有最后的三个可以享受“特殊待遇”,其余的±1按正常的系数进行编码。
编码COEFF_TOKEN有四个码表可供选择,包括了三个变长码表及一个定长码表。由当前块的左相邻块及上相邻块中非零系数的个数决定当前块所选用的码表。令nA是左相邻块中非零系数的个数,nB是上相邻块中非零系数的个数,则预测值nC=round((nA+nB)/2)。当nC为0,1时,选用码表1;为2,3时,选用码表2;为4~7时,选用码表3;大于等于8时选用码表4。
nC
选用的码表
0,1
码表1
2,3
码表2
4,5,6,7
码表3
大于等于8
码表4
我们不难想象出,码表1是偏向于非零系数个数少的情况的,对于小的非零系数个数,将分配较短的码字;码表2偏向于中等的非零系数个数,如2~4;码表3偏向于大的非零系数个数;而码表4由于使用了定长编码,因此没有偏向性,其码长为6位。
2、编码±1序列(Trailing Ones)的符号
对于±1序列,仅编码其符号,用0表示正,1表示负。值得注意的是,其扫描顺序是反向的,即先从高频的±1系数开始编码。
3、编码剩余的非零系数
这部分是CAVLC编码中最为难理解的一部分。对于剩余的非零系数,其扫描顺序也是从高频到低频。每个非零系数的VLC编码,包括了两个部分:前缀(prefix)和后缀(suffix)。而后缀的长度是由一个 的变量来控制的。一般的编码过程为
1)        初始化令 (如果非零系数的个数超过10且±1的个数小于3,则初始化 ),扫描顺序从高频到低频;
2)        对于当前要编码的系数,先做一次从有符号数到无符号数的映射,映射规则为 。值得注意的是,如果块中Trailing Ones的长度小于3,则编码的第一个系数肯定不是±1,因此可以先将第一个系数的绝对值减1,以节省比特开销;
3)        将 分成两部分: 除以 的商及余数。商部分通过查表得到其编码,作为码字的前缀;而余数部分用 位的二进制数来表示。前缀表为

编码
0
1
1
01
2
001
3
0001

……
4)        根据当前编码的系数的绝对值(前缀的编码长度),判断是否超过当前 所对应阈值。如果超出,则令 。这就是上下文自适应的过程。阈值表为( )
当前suffix Length
阈值
0
0
1
3
2
6
3
12
4
24
5
48
6
N/A(最大的suffix Length)
5)        如果所有非零系数都被编码了,则结束;否则转2。
上述的过程并不完整,还有一些例外的情况没有处理到。如果读者有兴趣可以自行参考ITU-T关于H.264的标准文档[3]、[4]或者JM的源程序。
4、编码最后一个非零系数前0的个数
这个部分也是一个VLC编码,一共有16个码表可供选择。当前块中非零元素的个数决定选用哪个码表。
5、编码各个非零元素前0串的游程长度
扫描的过程仍然是从高频到低频,对每个非零元素前连续0串的长度进行编码。由剩余没被编码的0的个数决定选用哪个码表。当所有的0元素都被编码了,这个过程也随之结束了,余下的非零元素就不需要进行前面0串长度的编码,因为已经没有余下的0了。
整个CAVLC编码的过程确实不太好懂,为了加深读者的理解,现举一个编码的例子:
2.14  CAVLC编码举例1
被编码的4×4块中系数如图 2.14所示。在经过Zig-Zag扫描后得到的序列为
0,3,0,1,-1,-1,0,1,0,…
总的非零系数的个数为5。虽然±1的总个数是4,但是超过了Trailing Ones长度是3的限制,因此Trailing Ones长度为3。
整个编码的过程为
Element
Value
Code
Coeff_token
TotalCoeff=5,
T1s=3 (assuming use Table 1)
0000100
T1 sign(4)
+
0
T1 sign(3)
-
1
T1 sign(2)
-
1
Level(1)
+1,level_code=0,suffixLength=0
quotient=0,remainder=0
1(prefix)
Level(0)
+3, level_code=4,suffixLength=1
quotient=2,remainder=0
001(prefix) 0(suffix)
total_zeros
3, TotalCoeff=5
111
run_before(4)
ZeroLefts=3;run_before=1
10
run_before(3)
ZeroLefts=2;run_before=0
1
run_before(2)
ZeroLefts=2;run_before=0
1
run_before(1)
ZeroLefts=2;run_before=1
01
run_before(0)
ZeroLefts=1;run_before=1
Last coefficient,not necessary to be encoded
最后得到的输出为000010001110010111101101,仅用了3个字节。
至于CABAC,由于其编码规则比较复杂,本文就不予讨论了。
五、解码环路去块滤波器
在H.263+中就已经提出了去块滤波器这个概念,但当时只是作为一个附件形式存在。在H.264中,去块滤波的算法得到了很好的改进,得到了更广泛的应用。块效应产生的原因是对图像进行分块压缩时,由于高频的分量被去除了,使得边界上原本很接近的像素值在重构后产生了较大的差异,形成明显的边界。去块效应滤波器的作用是使得块边界趋于缓和,从而能提高图像的主观质量,同时也能加强后续帧运动补偿的效果。通过图 2.15可以看出有无去块滤波的差异。
去块滤波需要在亮度及色度块的每个4×4的边界上进行。而每次的滤波能最多影响边界两边各三个像素值,如图 2.16中的p0,p1,p2以及q0,q1,q2。滤波所进行的强度决定于当前所用的量化步长、相邻块使用的编码模式以及图像边界上的梯度。
(a) 无去块滤波
(b) 有去块滤波
2.15  有无去块滤波的对比
2.16  垂直及水平边界
在进行滤波之前先要知道参数bS(boundary Strength)的值。有下列五种情况
p或q使用了帧内编码,而且边界是宏块的边界
bS=4(最强滤波)
p或q使用了帧内编码,但边界不是宏块的边界
bS=3
p和q都没有使用帧内编码;p或q有非零的系数
bS=2
p和q都没有使用帧内编码;p和q都没有非零的系数;
p、q使用了不同的参考帧或使用了不同的参考帧数量或运动矢量在x方向或y方向的差的决对值大于等于1个像素
bS=1
其它情况
bS=0(不进行滤波)
像素集合(p2,p1,p1,q0,q1,q2)只有在同时满足下列两种情况下才进行滤波
a)         bS>0;
b)        |p0-q0|<α且 |p1-p0|<β且 |q1-q0|<β
当中α与β是H.264标准中制定的两个阈值,它由块p与块q的QP的平均值决定。制定这两个阈值的目的是不想错误地把图像上的原有的边界给平滑了。当QP取值小的时候,由于量化带来的误差很小,因此梯度值大的边界多数是图像原有的特征,不是块效应,此时α与β的取值都应该取小;当QP取值大时,图像的扭曲程度加深了,此时应该提高α与β的值,让更多的边界进行去块滤波。
而滤波的过程为
a)         如果0使用一个4阶FIR滤波器产生Δ。p0加上Δ产生p0',q0减去Δ产生q0'。如果是一个亮度块,还要作两次判断:1、|p2−p0|是否小于β,如果满足,另一个4阶FIR滤波器将作用在p2,p1,p0,q0上,产生新的p1';2、|q2−q0|是否小于β,如果满足,一个4阶FIR滤波器将作用在p0,q0,q1,q2上,产生新的q1'。滤波的结果还要被一个门限来钳位,这个门限的大小取决于bS。
b)        如果bS=4
如果 |p2 − p0| < β且|p0 − q0| < round (α/4)且当前块是亮度块
p0'由一个作用在p2, p1, p0, q0, q1的5阶FIR滤波器产生
p1'由一个作用在p2, p1, p0, q0的4阶FIR滤波器产生
p2'由一个作用在p3, p2, p1, p0, q0的5阶FIR滤波器产生
否则
p0'由一个作用在p1, p0, q1的3阶FIR滤波器产生
如果|q2 − q0| < β且|p0 − q0| < round(α/4)且当前块是亮度块
q0'由一个作用在q2, q1, q0, p0, p1的5阶FIR滤波器产生
q1'由一个作用在q2, q1, q0, p0的4阶FIR滤波器产生
q2'由一个作用在q3, q2, q1, q0, p0的5阶FIR滤波器产生
否则
q0'由一个作用在q1, q0, p1的3阶FIR滤波器产生
六、H.264的轮廓划分
在H.264中,划分了三个不同的轮廓(Profile),分别是基本轮廓(Baseline Profile)、主轮廓(Main Profile)以及扩展轮廓(Extended Profile)。要进行这样的划分只要是为了使H.264能适应不同层面上的应用。每个Profile所能包含的技术主要有:
图 2.17  H.264的轮廓划分
Baseline Profile:支持H.264的主要核心技术,如I-Slice、P-Slice、帧内预测、1/4精度运动估计、可变大小预测块、多参考帧、4×4整数变换、去块滤波等。此外还支持一些增强的误码恢复技术,如灵活的宏块顺序(FMO)、任意的条顺序(ASO)以及冗余条(Redundant slices)。
Main Profile:支持Baseline中的除误码恢复以外的所有技术。此外,还新增B-Slice、带权重预测、CABAC及帧场交错。
Extended Profile:支持Baseline中所有的技术。此外添加B-Slice、带权重预测、SP及SI帧、数据分片技术。
2.     H.264中误码恢复的新技术
当视频流在网络上传输时,误码、丢包等问题不可避免。尤其是当传输的信道是移动信道时,误码的问题更为严重。H.264标准在制定的时候提供了大量的错误恢复工具, 提供了数据误码/损失的鲁棒性(Robustness)和在多种网络环境下工作的灵活性, 在一定程度上提高了监控图像质量和实时性, 保证网络QoS 和安全性, 并节省额外网络开销。
H.264的算法在概念上可以分为两层:视频编码层(VCL:Video Coding Layer)和网络提取层(NAL:Network Abstraction Layer)。其中,VCL层独立于网络,主要包括核心压缩引擎和块、宏块和片的语法句法定义。网络提取层的主要功能是定义数据的封装格式,把数据适配到各种各样分组或流式的网络中。
H.264从框架结构上将NAL与VCL分离,主要有两个目的:首先,可以定义VCL视频压缩处理与NAL网络传输机制的接口,这样允许视频编码层VCL的设计可以在不同的处理器平台进行移植,而与NAL层的数据封装格式无关;其二,VCL和NAL都被设计成工作于不同的传输环境,异构的网络环境并不需要对VCL比特流进行重构和重编码。下面分别就VCL和NAL对于视频传输的QoS进行分析。
一、VCL层误码恢复工具
a)         帧内预测及多参考帧
H.264中帧内预测宏块的参考宏块可以是帧内编码宏块,也可以是帧间编码宏块。采用预测的帧内编码比非预测的帧内编码有更好的编码效率,但降低了帧内编码的重同步性能。可以通过设置限制帧内预测标记(Constrained Intra Prediction Flag)来恢复这一性能。
在使用多参考帧技术时,由于在传输了帧内编码图像后,后续的图像仍可能使用该帧内编码图像前面的图像进行预测编码,因此即使该帧内编码图像没有误码,也无法消除误码扩散所导致的图像漂移。在H.264中指定了一种立即刷新(IDR,Instantaneous Decoder Refresh)片,它仍然使用了帧内编码技术。解码端在解码IDR片后,解码器立即将所有的参考图像标识为“未用作参考”。这样,后续图像被解码时,就不参考该IDR片前面的任何图像。每个视频序列的第一幅图像一定是IDR图像。与仅包含帧内编码片的图像相比,IDR图像具有更强的重同步特性。
在使用多参考帧技术时,如果解码端发现序列中的某一帧发生了误码或丢失,可以指定编码器使用先前无误码的一帧进行预测,防止误码扩散。当然,这需要增加编解码器帧图像缓存区。
b)        FMO
FMO的全称是灵活宏块排序(Flexible Macroblock Ordering)。它是H.264的一大特色,适用于H.264的基本档次和扩展档次的应用。
图像内部预测机制,例如帧内预测或运动矢量预测,仅允许使用同一片组里的空间相邻的宏块。由于在解码器中各个片被独立解码,从而有效地抑制了错误的蔓延,提高了解码的容错力。FMO通过宏块分配映射技术,把每个宏块分配到不按扫描顺序的片中。FMO模式划分图像的模式各种各样,重要的有棋盘模式、矩形模式等,如图 3.1所示。当然FMO模式也可以使一帧中的宏块顺序分割,使得分割后的片的大小小于无线网络的MTU尺寸,经过FMO模式分割后的图像数据分开进行传输。
(a)  棋盘模式                             (b)矩形模式
两种FMO图像划分模式
在使用棋盘模式时,所有的宏块被分成了片组0和片组1,相应地分别采用绿色和褐色表示。当褐色片丢失时,因为其周围的宏块都属于其他片的宏块,利用邻域相关性,绿色宏块的某种加权可用来代替褐色片相应宏块。这种错误隐藏机制可以明显提高抗误码性能。实验证明,在CIF图像的视频会议中,在丢包率达10%时,视频失真低到需要训练有素的眼睛才能识别。使用FMO的代价是稍微降低了编码效率(因为它打破了原先非邻居MB之间的预测),而且在高度优化的环境中,有较高的时延。
图 3.2  使用FMO在丢失一个片组的P帧时的解码图像
c)        ASO及冗余条
ASO的全称是任意条顺序(Arbitrary Slice Ordering)。在该模式下,宏块可以不按解码的先后顺序进行排列。该方式增强了视频会议等低延时应用的可操作性。
冗余条(Redundant slices)就是指在同一个比特流中,编码器除了将片自身中已编码的宏块放置其中外,还放置了同一宏块的1个或多个冗余的表示,通过利用宏块的一个或多个冗余表示来克服误码对重构图像造成的影响。这种技术与基于冗余的传输如包复制有着本质的区别。在包复制冗余传输中,被复制的包和复制包一模一样,而在冗余片技术的使用中,冗余片使用不同的编码参数来编码,从而形成对同一宏块的不同表示。例如,主冗余片可以使用较小的QP来量化编码,因此具有较好的重构图像质量。次要的冗余片可以使用一个较大的QP来量化编码,因而使用较少的比特数,重构质量较粗糙。在解码器中重构图像时,如果主冗余片可用,则仅使用主冗余片而丢弃其余的冗余片。只有当主冗余片在传输的过程中丢失或由于误码等原因而无法使用时,其余的冗余片才用于重构图像。这种对主次冗余片不同编码参数的运用,使得冗余片技术在花销最少比特数的情况下,最大限度地保证了重构图像的质量,尤其是在有误码倾向的移动信道或IP信道环境下,采用冗余片技术可显著提高重构图像的主客观质量。
d)        数据分割
数据分割是一种高效的抗误码技术。通常情况下,一个宏块中的所有码元被编码组织在单个的比特串中用于构成片。而数据分割则为每个片生成多个比特串,即多个数据分块,并将片中彼此之间语义相近并有紧密联系的码元组织在一个独立的数据分块中。针对信息的重要程度,对不同的数据分块采用不等的保护措施(UEP,Unequal Error Protection),保证了恢复视频的质量。
在H.264中,共使用了3种不同类型的数据分块:首部数据、帧内编码数据与帧间编码数据。
1)首部数据
首部数据中包含了Slice的首部以及该Slice中所有宏块的首部。首部中的宏块类型、量化步长和运动矢量等参数对于一个数据分块是最重要的,如果它丢失,即使别的数据分块被正确接收到也将无法解析,因此在分割重组后,头信息被赋予了最大程度的保护。此数据分块类型在H.264中称为A类分块。
2)帧内编码数据
帧内编码数据分块称为B类分块,它承载的是Intra Slice及SI Slice中编码后的残余数据。B类分块需要相应片的A类分块可用。
3)帧间编码数据
帧间编码数据分块称为C类分块,它承载的是帧间编码Slice中的残余数据。C类分块同样需要相应片的A类分块才可用。
当使用数据分割时,信源编码器将不同类型的码元放入3个不同的比特缓存器中,以生成3种类型的数据分块。同时,调整片的大小,以保证打包最大的数据分块时所生成的包小于MTU(maximum transfer unit)的允许值。也正是出于这个原因,在H.264中是由信源编码器来执行数据分割而不是NAL。
图 3.3  数据分割在编码器中所处的位置
在解码器中,所有的数据分块都应能有效地用于图像重构。特别地,如果仅仅是B类或者C类的数据片丢失,可以利用先前的解码图像很好地进行掩盖。
e)         参数集
参数集(Parameter Sets)是H.264标准的一个新概念,是一种通过改进视频码流结构增强错误恢复能力的方法。它所包含的信息用于解码数目可能相当大的一组视频。H.264的参数集又分为序列参数集和图像参数集。其中,序列参数集包括一个图像序列的所有信息,这些信息都相当重要,例如图像的分辨率、参考帧数量等。图像参数集包括一个图像的所有分片的所有相关信息,包括图像类型、序列号、使用熵编码的类型等,解码时某些序列号的丢失可用来检验信息包的丢失与否。多个不同的序列和图像参数集存储在解码器中,编码器依据每个编码分片的头部的存储位置来选择适当的参数集,图像参数集本身也包括使用的序列参数集参考信息。
众所周知,一些关键信息比特的丢失(如序列和图像的头信息)会造成解码的严重负面效应,而H.264把这些关键信息分离出来,凭借参数集的设计,确保在易出错的环境中能正确地传输。这种码流结构的设计无疑增强了码流传输的错误恢复能力。
参数集具体实现的方法也是多样化的:(1)通过带外传输,这种方式要求参数集通过可靠的协议,在首个片编码到达之前传输到解码器;(2)通过带内传输,这需要为参数集提供更高级别的保护,例如发送复制包来保证至少有一个到达目标;(3)在编码器和解码器采用硬件处理参数集。
二、NAL层误码恢复工具
NAL支持众多基于包的有线/无线通信网络。但目前,绝大部分的视频应用所采用的网络协议层次是RTP/UDP/IP,因此在下面的描述中主要基于这个传输框架。下面分析NAL层的基本处理单元NALU以及它的网络封装、分割和合并的方法。
每个NAL单元包含了一个字节的NAL头部信息以及一个原始字节顺序载荷(RBSP,Raw Byte Sequence Payload)。RBSP的内容可能是一个编码片、A/B/C型数据分割、附加的增强信息或一个序列或图像参数集。而头部信息包括了:T,负荷数据类型,占5bit;R,重要性指示位,占2bit;最后的F为禁止位,占1bit。具体如下:
1)NALU类型位
可以表示NALU的32种不同类型特征,类型1~12是H.264定义的,类型24~31是用于H.264以外的,RTP负荷规范使用这其中的一些值来定义包聚合和分裂,其他值为H.264保留。
2)重要性指示位
用于在重构过程中标记一个NAL单元的重要性,值越大,越重要。值为0表示这个NAL单元没有用于预测,因此可被解码器抛弃而不会有错误扩散;值高于0表示此NAL单元要用于无漂移重构,且值越高,对此NAL单元丢失的影响越大。
3)禁止位
编码中默认值为0,当网络识别此单元中存在比特错误时,可将其设为1,以便接收方丢掉该单元,主要用于适应不同种类的网络环境(比如有线无线相结合的环境)。例如对于从无线到有线的网关,一边是无线的非IP环境,一边是有线网络的无比特错误的环境。假设一个NAL单元到达无线那边时,校验和检测失败,网关可以选择从NAL流中去掉这个NAL单元,也可以把已知被破坏的NAL单元前传给接收端。在这种情况下,智能的解码器将尝试重构这个NAL单元(已知它可能包含比特错误)。而非智能的解码器将简单地抛弃这个NAL单元。NAL单元结构规定了用于面向分组或用于流的传输子系统的通用格式。在H.320和MPEG-2系统中,NAL单元的流应该在NAL单元边界内,每个NAL单元前加一个3字节的起始前缀码。在分组传输系统中,NAL单元由系统的传输规程确定帧界,因此不需要上述的起始前缀码。一组NAL单元被称为一个接入单元,定界后加上定时信息(SEI),形成基本编码图像。该基本编码图像(PCP)由一组已编码的NAL单元组成,其后是冗余编码图像(RCP),它是PCP同一视频图像的冗余表示,用于解码中PCP丢失情况下恢复信息。如果该编码视频图像是编码视频序列的最后一幅图像,应出现序列NAL单元的end,表示该序列结束。一个图像序列只有一个序列参数组,并被独立解码。如果该编码图像是整个NAL单元流的最后一幅图像,则应出现流的end。
H.264采用上述严格的接入单元,不仅使H.264可自适应于多种网络,而且进一步提高其抗误码能力。序列号的设置可发现丢的是哪一个VCL单元,冗余编码图像使得即使基本编码图像丢失,仍可得到较“粗糙”的图像。
3.     H.264在高清视频的扩展
H.264/AVC是一种很高效的视频编码标准,在很多领域得到了广泛的应用。但第一版本的标准主要用于提供“娱乐质量”的视频(基于8位的样本表示和YUV4:2:0的色度抽样)。因为H.264/AVC标准的发展时间有限,所以它不能满足一些专业领域的要求,例如它并没有涉及超高分辨率的情况。然而,微软公司在2003年将其视频压缩技术向美国的电影电视工程师协会(Society of Motion Picture and Television Engineers,SMPTE)提出公开标准化的申请,并以VC-1 (Video Codec 1)为此新标准的命名。由于VC-1在高分辨率影片上的表現出色,导致H.264/AVC在DVD论坛与蓝光协会的高清晰度DVD影片测试中败阵下来,其主要原因是H.264/AVC使用较小尺寸的转换公式与无法调整的量化矩阵,造成不能完整保留影像的高频细节,使得影片失去了人们常说的“菲林感”(Film Effect)。
为了满足诸如HDTV、下一代高清DVD等应用场合,JVT将一些新的扩展加入到原始的标准中,并最终命名为“高保真扩展”(Fidelity Range Extension)。使用这个扩展时可以以MPEG-2大约1/3左右的码率提供相同质量的画面。
图 4.1  H.264与MPEG-2的对比
这个扩展主要包括了以下内容
一、新的输入视频格式的支持
H.264/AVC的FRExt大大扩充了所支持的输入格式。它所支持的输入格式包括了:
l         只有亮度的单色视频,带或不带辅助矩阵;
l         带有亮度及两个色差的视频(YCbCr或YCgCo),带或不带辅助矩阵;
l         红、绿、蓝三色视频,带或不带辅助矩阵;
l         矩阵代表其它未指定的单色或三色模型(例如HSI),带或不带辅助矩阵;
其中辅助矩阵(单色的)对解码端来说是一个可选项,可以出现或者不出现在解码的视频中。它主要用于显示辅助图像,例如用于alpha混合。
YCgCo是H.264中新增加的一种三色模型。视频图像一般是使用RGB颜色空间进行捕捉和显示的。但是为了压缩数据量,通常要将图像从RGB空间转到YCbCr空间,并利用人眼对亮度比较敏感而对色差不太敏感的特性对色差进行降采样。转换的公式为
这个转换过程由于使用了浮点运算,因此存在舍入误差。而且使用浮点运算也增加了运算量。类似于对DCT变换做出的改进,YCgCo是一种整数变换,其变换公式为
这种方法比YCbCr变换降低了复杂度,但是它本身也存在舍入误差。然而,如果给Y、Cg分量增加两位,给Co分量增加一位来提高精度的话,舍入误差就可以避免了。
FRExt中还有进一步改进,它不需要为亮度分量增加多余的位来提高精度,也不存在舍入误差
其中t是一个中间变量。而反变换公式为
由于参于中间运算的变量对于编码端与解码端是一致的,所以结果不存在舍入误差。在这里仍需要对Cg、Co分量增加一个符号位扩展来表示变换后的数据。然而在FRExt中仍有进一步的工作,那就是在输入-输出和储存图像仍然使用RGB域,只在编码器和解码器的处理残差数据的时候使用上述的变换过程。这种技术称为残差色彩变换,在不提高系统复杂度的情况下消除了颜色空间的转换误差。
而色度抽样也不再仅限于4:2:0,可以支持4:2:2甚至4:4:4的色度抽样。而表示每个样本值可以使用8到12比特,而且允许表示亮度的比特多于表示色差的比特。
(a)  4:2:0采样              (b)  4:2:2采样              (c)  4:4:4采样
图 4.2  色度抽样示意图
二、8×8帧内预测与8×8整数变换
在原有的H.264标准中,亮度块只有4×4及16×16两种帧内预测方式。4×4预测的方式多,预测的效果较好,但是需要耗费较多的比特用来表示预测方式,不太适用于高分辨率的视频;16×16的预测方式可以减少表示预测方式的比特,但由于预测模式减少了,而且块也变大了,使得预测效果变差了,用来表示残差的比特相应地增加了。在高保真扩展中新增了一个8×8的预测方式介于4×4及16×16中间,使得表示模式与表示残差的两种数据量之间能有一个更好的平衡点。一共有9种8×8的亮度块预测方式,这些方式与4×4的亮度块预测方式是相似的。
高保真扩展中也新增加了一种8×8的整数变换,使宏块可以在4×4与8×8之间自由选择变换方式。这个8×8整数变换公式为
显然8×8整数变换比4×4整数变换来的复杂些,但是相比8×8的DCT变换还是简单了很多。原本在制定H.264标准时,有多种不同大小的块转换方式,称为ABT。但由于ABT的复杂度太高,因此在H.264第一版本中只保留了4×4变换。有趣的是在H.264的第二版本中又把8×8变换的方式追加回来了。8×8整数变换的优点在于能使能量更加地集中,有利于提高压缩比;而在相同的比特率下,能比4×4变换保留更多的高频细节,如电影胶片上的视频颗粒。
三、基于视觉的量化缩放矩阵
在高保真扩展中增加了一种已经在MPEG-2中使用的“基于视觉的量化放缩矩阵”。编码器可以分别为每个帧内或帧间的变换块,在解码器的反量化时指定一个特定的缩放因子。这样就可以根据人类视觉系统对不同类型视频误差的敏感度模型来调整量化以达到保真。当然这并不能提高客观保真度(均值平方误差或者PSNR),但却能提高主观保真度。在H.264 中指定了默认的量化放缩矩阵,编码器可以在图像层发送指定的值来代替它们。
四、无失真宏块模式
当编码视频的保真度非常高时(即量化步长非常小时),某些输入的图片内容就可能在编码过程中增加了数据量而不是减少。进一步,在解码器对一个数据位数的标识进行处理比对一个宏块进行解码要方便得多。为了解决这一问题,H.264中扩展了一种“I_PCM”的宏块类型,它不经过预测、变换或者量化而直接将样本点的值发送出去。同时,这也可以实现对图像中的特定部分进行无失真重构。
4.     H.264的实现及应用展望
目前许多公司都已经发布了基于H.264技术的产品,应用范围覆盖了视频会议、视频监控、网络视频、远程医疗/教学等方面。HD-DVD与蓝光两大下一代高清DVD阵营也均宣布了支持H.264压缩格式,ATI甚至已经把H.264的硬解码做进了新一代的镭X1000显卡中。
实现H.264编解码主要可以分为硬件实现和软件实现。硬件实现主要是指应用专门为H.264设计的FPGA、ASIC、DSP等IC芯片实现H.264的编解码,其主要优势是编解码的速度快,但是需要额外的投资购买新的硬件;软件实现主要是指在通用CPU、DSP及嵌入式处理器上通过优化算法实现H.264的编解码,其优点是可以重复利用已有投资,但是由于H.264编解码对运算量的要求很大,不容易做到实时。目前主要以硬件实现为主。
在目前主流的x86平台上实现H.264的编解码可以考虑在开源工程的基础上修改,以节省开发周期。现在世界上有两大主流H.264的开源工程,包括了JM以及X264。
JM是H.264的官方测试源码,由德国HHI研究所负责开发,实现了H.264所有的特性。学术研究的算法都是在JM基础上实现并和JM进行比较的。由于它侧重于学术研究,因此并没有重视程序的运行效率,结构也较为冗长。其编码复杂度极高,即使QCIF格式的视频,编码一帧都达到2~3秒,远达不到实时压缩的要求。
X264是由法国巴黎中心学校(Ecole Centrale Paris,ECP)的中心研究所(Centrale Réseaux)的一帮学生于2004年6月发起的一个开源项目,后来吸引了一大批热爱视频编码的成员共同完成这个项目。X264的目标是实现一个实用的264编码器,所以它引入了很多MMX,SSE等汇编指令来提高编码速度,同时摒弃了一些耗时但对编码性能提高微小的模块,如多参卡帧。目前,基于x264的DVDRip已经开始流行,由于X264的编码性能在很多情况下优于DIVX和XVID, x264在DVDRip中所占的份额开始明显增长,大有希望取代DIVX及XVID成为新一代网络视频压缩的王者。
JM源代码下载地址:http://bs.hhi.de/~suehring/tml/download
X264源代码下载地址:http://developers.videolan.org/x264.html
[1]     丁贵广,计文平,郭宝龙等编著,Visual C++ 6.0数字图像编码,机械工业出版社,2004
[2]     李春林,限失真视频编码技术的研究和算法的优化,西安电子科技大学硕士生毕业论文
[3]     ITU-T,Study of Final Committee Draft of Joint Video Specification,Feb 16,2003
[4]     ITU-T Recommendation H.264, Advanced video coding for generic audiovisual services, 03/2005
[5]     Iain E. G. Richardson,H.264 and MPEG-4 Video Compression,The Robert Gordon University, Aberdeen, UK
[6]     H.264 Reference Software Version JM86,http://bs.hhi.de/~suehring/tml/
[7]     左雯等,基于H.264 的高速运动图像技术研究,公路交通科技,Vol.22, No.2, 111-115, 2005
[8]     王德宝,梁立伟,齐美彬,H.264/AVC高保真扩展的概述,数字电视与数字视频,No.6, 30-32, 2005
[9]     王祖寿,王彩云,纵览最新视频编码标准H.264/AVC,http://www.hc360.com
[10]   郭其昌,H.264先进视频编解码标准,http://www.dvo.org.tw/publication/20050403.html
[11]   王健,毕厚杰,关于H.264视频编码传输的QoS特性分析,中国多媒体视讯
[12]   维基百科全书,H.264/MPEG-4 AVC,http://eeeeee.org/wiki/H.264
[13]   王俊生,视频编码新标准H.264中抗误码技术的研究,中国有线电视,No.19,2004