1.概述
量化是使数据比特率下降的有效工具。量化过程的输入值动态范围很大,需要较多的比特才能表示一个数值,量化后的输出则只需要较小比特表示。
量化是不可逆过程,处理过程中有信息丢失,存在量化误差。
H.264采用标量量化技术,它将每个图像样点编码映射成较小的数值。一般标量量化器的原理为:
F
Q
=
r
o
u
n
d
(
y
/
Q
P
)
FQ=round(y/QP)
FQ=round(y/QP)
其中,y 为输入样本点编码,QP 为量化步长,FQ 为 y 的量化值,round()为取整函数(其输出为与输入实数最近的整数)
在量化和反量化过程中,量化步长 QP 决定量化器的编码压缩率及图像精度。如果 QP 比较大,则量化值 FQ 动态范围较小,其相应的编码长度较小,数据压缩率高但会损失较多的图像细节信息;如果QP 比较小,则 FQ 动态范围较大,相应的编码长度也较大,但图像细节信息损失较少。编码器根据图像值实际动态范围自动改变 QP 值,在编码码率和图像精度之间折衷,达到整体最佳效果。
2.H264的量化表设计
H.264 中,量化步长 Qstep 共有 52 个值。如下表所示。其中 QP 是量化参数,是量化步长的序号。
- 当 QP 取最小值 0 时代表最精细的量化,当 QP 取最大值 51 时,代表最粗糙的量化。
- QP 每增加 6,Qstep 增加一倍,也就是QStep(QP+6) = 2*QStep(QP);这种周期性步长的好处是可以显著减少量化表和反量化表的长度。
- 为了避免在较高量化步长时的出现颜色量化人工效应, H.264 规定,亮度 QP 的最大值是 51,而色度 QP 的最大值是 39。
- DCT变换中的按位置相乘运算矩阵
E
f
Ef
Ef可以合并到量化表中,而IDCT变换中的运算矩阵
E
i
Ei
Ei 可以合并到反量化表中。
其中Ef矩阵
E f = ( a 2 a b / 2 a 2 a b / 2 a b / 2 b 2 / 4 a b / 2 b 2 / 4 a 2 a b / 2 a 2 a b / 2 a b / 2 b 2 / 4 a b / 2 b 2 / 4 ) Ef = \begin{pmatrix} a^2 & ab/2 & a^2 & ab/2 \\ ab/2 & b^2/4&ab/2 & b^2/4 \\ a^2 & ab/2 & a^2 & ab/2 \\ ab/2 & b^2/4&ab/2 & b^2/4 \end{pmatrix} Ef=⎝⎜⎜⎛a2ab/2a2ab/2ab/2b2/4ab/2b2/4a2ab/2a2ab/2ab/2b2/4ab/2b2/4⎠⎟⎟⎞
其中, a = 1 / 2 a=1/2 a=1/2,
b = 1 / 2 cos ( π 8 ) b=\sqrt{1/2}\cos{\left(\frac{\pi}{8}\right)} b=1/2cos(8π),
c = 1 / 2 cos ( 3 π 8 ) c=\sqrt{1/2}\cos{\left(\frac{3\pi}{8}\right)} c=1/2cos(83π) ,
2.1量化过程
在 H.264 中,量化过程是对 DCT 结果进行操作:
Z
i
j
=
r
o
u
n
d
(
W
i
j
∗
E
f
(
i
,
j
)
/
Q
S
t
e
p
)
Zij = round(Wij * Ef(i,j)/ QStep)
Zij=round(Wij∗Ef(i,j)/QStep)
其中,
W
i
j
Wij
Wij是DCT变换系数,
Z
i
j
Zij
Zij是输出的量化系数,Qstep 是量化步长。
利用量化步长随量化参数每增加 6 而增加一倍的性质,可以进一步简化计算,设
q
b
i
t
s
=
15
+
f
l
o
o
r
(
Q
P
/
6
)
qbits = 15 + floor(QP/6)
qbits=15+floor(QP/6)
令
M
F
(
i
,
j
)
=
E
f
(
i
,
j
)
/
Q
S
t
e
p
∗
2
q
b
i
t
s
MF(i,j) = Ef(i,j)/QStep*2^{qbits}
MF(i,j)=Ef(i,j)/QStep∗2qbits
则
Z
i
j
=
r
o
u
n
d
(
W
i
j
∗
M
F
(
i
,
j
)
2
q
b
i
t
s
)
Zij = round(Wij* \frac{MF(i,j)}{2^{qbits}})
Zij=round(Wij∗2qbitsMF(i,j))
根据上式,可以计算QP=0时,
M
F
(
0
,
0
)
=
0.25
/
0.625
∗
2
15
=
13107.2
MF(0,0)=0.25/0.625*2^{15}=13107.2
MF(0,0)=0.25/0.625∗215=13107.2,用整数13107表示。
这样,MF 可以取整数,如下表所示的量化表。表中只列出对应 QP 值为 0 到 5 的 MF 值,对于QP 值大于 5 的情况,只是 qbits 值随 QP 值每增加 6 而增加 1,而对应的 MF 值不变。比如QP=6和QP=0的MF值相等。
因此,对于QP范围为0-51只需要维护6个量化表,这也就是上文中描述的“周期性步长的好处是可以显著减少量化表和反量化表的长度”。
量化过程则为整数运算,并且可以避免使用除法,并且确保用 16 位算法来处理数据,在没有 PSNR 性能恶化的情况下实现最小的运算复杂度。
具体量化过程的运算为:
⏐
Z
i
j
⏐
=
(
⏐
W
i
j
⏐
⋅
M
F
+
f
)
>
>
q
b
i
t
s
⏐Zij⏐ = (⏐Wij⏐⋅MF + f)>>qbits
⏐Zij⏐=(⏐Wij⏐⋅MF+f)>>qbits
s
i
g
n
(
Z
i
j
)
=
s
i
g
n
(
W
i
j
)
(
6.30
)
sign(Zij) = sign (Wij) (6.30)
sign(Zij)=sign(Wij)(6.30)
其中,“>>”为右移运算,右移一次完成整数除以 2;sign()为符号函数;f 为偏移量,它的作用是改善恢复图像的视觉效果,例如,对帧内预测图像块 f 取 2qbits/3,对帧间预测图像块 f 取 2qbits/6。
2.2反量化表
同理,我们可以得到H264的反量化公式
3.非一致性量化
上一节我们得到了各分量量化步长一致情况下的量化公式。为了更好的支持高清视频,H264引入了非一致性量化,也就是不同位置的变换系数使用不同的量化参数。通过量化参数调整,使编码图像更加适合人类视觉系统(去除人类视觉冗余信息)。
使用量化权重矩阵W来描述不同位置的步长区别。权重越大,量化步长越短,则量化结果越精细。编码时某个位置的量化步长为:宏块QP对应的量化步长QStep除以该位置的量化权重。
为了方便表示,这里的权重系数都放大了16倍,默认量化权重矩阵参数都为16。权重系数矩阵可以从SPS中解析得到。
按照标准文档8.5.9节,以4x4块为例,weightScale4x4表示量化权重系数矩阵,normAjust4x4表示上一节中的反量化表
JM代码中normalAdjust4x4 由下面的三维数组表示,低两个维度表示4x4矩阵坐标,第三维表示QP%6.
//! Dequantization coefficients
const int dequant_coef[6][4][4] = {
{{10, 13, 10, 13},{ 13, 16, 13, 16},{10, 13, 10, 13},{ 13, 16, 13, 16}},
{{11, 14, 11, 14},{ 14, 18, 14, 18},{11, 14, 11, 14},{ 14, 18, 14, 18}},
{{13, 16, 13, 16},{ 16, 20, 16, 20},{13, 16, 13, 16},{ 16, 20, 16, 20}},
{{14, 18, 14, 18},{ 18, 23, 18, 23},{14, 18, 14, 18},{ 18, 23, 18, 23}},
{{16, 20, 16, 20},{ 20, 25, 20, 25},{16, 20, 16, 20},{ 20, 25, 20, 25}},
{{18, 23, 18, 23},{ 23, 29, 23, 29},{18, 23, 18, 23},{ 23, 29, 23, 29}}
};
weightScale4x4有SPS、PPS中的scaling_list 语法表示,最终LevelScale4x4的计算过程如下:
InvLevelScale4x4Luma_Intra[k][i][j]=dequant_coef[k][j][i]*qmatrix[0][temp];
4.反量化计算过程
解码时的反量化过程包括以下几个步骤:
- 计算宏块QP
- 计算量化矩阵LevelScale
- 反量化
4.1QP计算
相邻宏块QP具有相关性,一般不会相差太大,因为相邻宏块QP相差太大容易产生块效应。因此,当前宏块QP计算会以前一个宏块QP_prev做参考,也就是QP_cur = QP_prev + mb_qp_delta.
宏块QP计算依赖以下几个变量:
- PPS中的pic_init_qp_minus26,表示一组图像中QP的初始值;
- slice header中slice_qp_delta,表示该slice相对于pic_init_qp_minus26的差值;
- 每个宏块头中有一个mb_qp_delta,表示该宏块相对于前一宏块的差值。
如果当前宏块为slice第一个宏块,前一个宏块不存在,它对应的QP_prev = pic_init_qp_minus26+26+pic_init_qp_minus26.
每个宏块亮度分量和色度分量计算方式有些差异,以最常用的8bit像素为例,公式如下
亮度分量QPy
QPy = (QPy_prev+mb_qp_delta+52)%52
色度分量QPc
色度分量计算还依赖pps中的两个变量 chroma_qp_index_offset/second_chroma_qp_index_offset,分别表示Cb、Cr分量相对于当前宏块亮度分量QP的差值。
计算步骤如下:
- 计算qpi = clip(0,51,QPy+qp_offset)
- 根据qpi查表得到最终的QPc。由表可知,色度分量QP最大值为39
4.2计算量化矩阵
对于YUV420格式,量化矩阵一共有8组,包括intra_8x8_Y、inter_8x8_Y、intra_4x4_Y、intra_4x4_cb、intra_4x4_cr、inter_4x4_Y、inter_4x4_cb、inter_4x4_cr。其中,每一组有对应QP%6为0-5的6个量化矩阵
量化矩阵计算依赖于SPS中的scaling_list量化权重参数语法.
最终可以得到48个量化矩阵。
4.3 反量化过程
反量化可分为4中情况说明:
4.3.1 Intra16x16宏块亮度分量的反量化过程
Intra16x16亮度块是按照4x4块划分编码
1.DC系数解析过程
- 反扫描,从码流中解析得到的16个DC系数是按照4x4块扫描顺序存放,如下图,因此需要先做反扫描。反扫描后矩阵
C
C
C
- 对DC系数矩阵
C
C
C反hadamard变换
- 根据前面得到的量化参数QP和量化矩阵LevelScale,得到DC系数
上面计算公式可以这么理解:
f i j ∗ L e v e l S c a l e ∗ 2 Q p / 6 / 2 6 f_{ij}*LevelScale*2^{Qp/6}/2^6 fij∗LevelScale∗2Qp/6/26
如果 Q p / 6 > = 6 Qp/6 >=6 Qp/6>=6,计算过程为乘以2的n次方;否则计算过程需要除以2的n次方,此时需要做四舍五入,所以要加上 2 5 − Q P / 6 2^{5-QP/6} 25−QP/6再除以 2 6 − Q P / 6 2^{6-QP/6} 26−QP/6.
2.AC系数解析过程
从码流中解析每个4x4块中的15个AC系数。AC系数反扫描,反量化
通过上面两步,可得到每个4x4块反量化后的DC、AC系数,可以对4x4系数块进行后面的IDCT变换。
4.3.2 色度分量的反量化过程
1.DC系数解析
- 从码流中解析每个色度分量4个DC系数,4个DC系数按行扫描顺序存放,可得到2x2的DC系数矩阵 C C C
- 对DC系数矩阵
C
C
C反hadamard变换
3.根据前面得到的量化参数QP和量化矩阵LevelScale,得到CbCr分量的DC系数
2.AC系数解析过程
从码流中解析每个4x4块中的15个AC系数。AC系数反扫描,反量化
通过上面两步,可得到每个4x4块反量化后的DC、AC系数,可以对4x4系数块进行后面的IDCT变换。
4.3.3 4x4亮度块(transform_size_8x8_flag=0)
1.残差系数解析,从码流中解析得到4x4块的DC系数和15个AC系数,
2.按4x4块顺序反扫描,并按照下面公式反量化
通过上面两步,可得到每个4x4块反量化后的DC、AC系数,可以对4x4系数块进行后面的IDCT变换。
4.3.4 8x8亮度块(transform_size_8x8_flag=1)
1.残差系数解析,从码流中解析得到8x8块的DC系数和63个AC系数
2.按8x8块顺序反扫描,并按照下面公式反量化
通过上面两步,可得到每个8x8块反量化后的DC、AC系数,可以对8x8系数块进行后面的IDCT变换。
参考文献:
《新一代视频编解码压缩标准H.264》
《深入理解视频编解码技术–基于h264标准及参考模型》
ITU-T H.264标准 (2010-03)