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 EfEf可以合并到量化表中,而IDCT变换中的运算矩阵 E i EiEi 可以合并到反量化表中。
其中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 =
⎛⎝⎜⎜⎜⎜a2ab/2a2ab/2ab/2b2/4ab/2b2/4a2ab/2a2ab/2ab/2b2/4ab/2b2/4⎞⎠⎟⎟⎟⎟
(a2ab/2a2ab/2ab/2b2/4ab/2b2/4a2ab/2a2ab/2ab/2b2/4ab/2b2/4)
Ef=
⎝
⎜
⎜
⎛
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
⎠
⎟
⎟
⎞
其中,a = 1 / 2 a=1/2a=1/2,
b = 1 / 2 cos ( π 8 ) b=\sqrt{1/2}\cos{\left(\frac{\pi}{8}\right)}b=
1/2
cos(
8
π
),
c = 1 / 2 cos ( 3 π 8 ) c=\sqrt{1/2}\cos{\left(\frac{3\pi}{8}\right)}c=
1/2
cos(
8
3π
) ,
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 WijWij是DCT变换系数,Z i j ZijZij是输出的量化系数,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∗2
qbits
则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∗
2
qbits
MF(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.2MF(0,0)=0.25/0.625∗2
15
=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}}
};
1
2
3
4
5
6
7
8
9
weightScale4x4有SPS、PPS中的scaling_list 语法表示,最终LevelScale4x4的计算过程如下:
InvLevelScale4x4Luma_Intra[k][i][j]=dequant_coef[k][j][i]*qmatrix[0][temp];
1
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 CC
对DC系数矩阵C CC反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}LevelScale2{Qp/6}/26f
ij
∗LevelScale∗2
Qp/6
/2
6
如果Q p / 6 > = 6 Qp/6 >=6Qp/6>=6,计算过程为乘以2的n次方;否则计算过程需要除以2的n次方,此时需要做四舍五入,所以要加上2 5 − Q P / 6 2^{5-QP/6}2
5−QP/6
再除以2 6 − Q P / 6 2^{6-QP/6}2
6−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 CC
对DC系数矩阵C CC反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)
————————————————
版权声明:本文为CSDN博主「qq62」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42139383/article/details/118334630