H.264 Quantization
来源:互联网 发布:洛瑞数据 编辑:程序博客网 时间:2024/05/20 09:10
H.264 Quantizer
一般的量化器,可用下面的公式来表示:
反量化可表示为:
量化步长
值。
Quantization Offset
可以看到,这种量化器是求下整,也就是会把区间
的值量化成0。这种量化器显然不是最优的,最优的量化器在某区间上的量化值应该为该区间的期望值。为此需要知道残差变换系数的统计分布,这个分布是经过统计实验得出来的,其中帧间比帧内分布得更为集中。
为了表明分布集中于区间的期望值,引入了参数——offset(量化偏移量)
。相应的量化公式变为:
反量化保持不变:
H.264参考模型建议:当帧内预测时
。
另外参数
可以控制量化死区(量化后为0区域)大小。
当
值。
从上方的例子可以看出,死区特征的应用是与应用直接相关的,最好能根据不同的应用相应加以调整。
我们注意到通过参数
来控制量化死区的大小,并将量化公式修改为:
但是这种方法并没有被标准采用。
Quantization Step
H.264标准共设计了52个不同的量化步长
,如下表所示,其中QP是量化参数,也就是量化步长的序号。QP由小变大,意味着量化步长的增大,也就是由精细变粗糙。
QP
Qstep
QP
Qstep
QP
Qstep
QP
Qstep
QP
Qstep
0
0.625
12
2.5
24
10
36
40
48
160
1
0.6875
13
2.75
25
11
37
44
49
176
2
0.8125
14
3.25
26
13
38
52
50
208
3
0.875
15
3.5
27
14
39
56
51
224
4
1
16
4
28
16
40
64
5
1.125
17
4.5
29
18
41
72
6
1.25
18
5
30
20
42
80
7
1.375
19
5.5
31
22
43
88
8
1.625
20
6.5
32
26
44
104
9
1.75
21
7
33
28
45
112
10
2
22
8
34
32
46
128
11
2.25
23
9
35
36
47
144
。
在讲述变换的时候说过,变换的
可以合并到量化表中。下面来看一下该运算矩阵
得到量化矩阵所进行的合并运算如下(归一化为
)
上式表明
以
为例,
把0~5这6个QP的
在
个参数:
采用量化矩阵的方式后,4x4整数DCT变换的量化公式为
同样道理,逆量化矩阵为(归一化为
):
上式表明
逆量化公式为:
逆量化矩阵为
Nonuniformity Quantization
非一致性量化就是4x4或8x8矩阵上各个位置的量化权重不同,通过这种方法可以在进行量化之前调整量化步长,得到更适合人类视觉系统,更真实的图像。
加入权重矩阵
后,量化矩阵与逆量化矩阵分别为:
其中
JM18.6参考代码如下
量化矩阵:
量化偏移矩阵
/*! ************************************************************************ * \brief * Init quantization offset parameters * * \par Input: * none * * \par Output: * none ************************************************************************ */void InitOffsetParam (QuantParameters *p_Quant, InputParameters *p_Inp){ int i, k; int max_qp_luma = (4 + 6*(p_Inp->output.bit_depth[0])); int max_qp_cr = (4 + 6*(p_Inp->output.bit_depth[1])); for (i = 0; i < (p_Inp->AdaptRoundingFixed ? 1 : imax(max_qp_luma, max_qp_cr)); i++) { if (p_Inp->OffsetMatrixPresentFlag) { memcpy(&(p_Quant->OffsetList4x4[i][0][0]),&(p_Quant->OffsetList4x4input[0][0]), 400 * sizeof(short)); // 25 * 16 memcpy(&(p_Quant->OffsetList8x8[i][0][0]),&(p_Quant->OffsetList8x8input[0][0]), 960 * sizeof(short)); // 15 * 64 } else { if (p_Inp->OffsetMatrixFlat == 1) { // 0 (INTRA4X4_LUMA_INTRA) memcpy(&(p_Quant->OffsetList4x4[i][0][0]),&(Offset_intra_flat_intra[0]), 16 * sizeof(short)); for (k = 1; k < 3; k++) // 1,2 (INTRA4X4_CHROMA_INTRA) memcpy(&(p_Quant->OffsetList4x4[i][k][0]),&(Offset_intra_flat_chroma[0]), 16 * sizeof(short)); for (k = 3; k < 9; k++) // 3,4,5,6,7,8 (INTRA4X4_LUMA/CHROMA_INTERP/INTERB) memcpy(&(p_Quant->OffsetList4x4[i][k][0]),&(Offset_intra_flat_inter[0]), 16 * sizeof(short)); for (k = 9; k < 25; k++) // 9,10,11,12,13,14 (INTER4X4) memcpy(&(p_Quant->OffsetList4x4[i][k][0]),&(Offset_inter_flat[0]), 16 * sizeof(short)); // 0 (INTRA8X8_LUMA_INTRA) memcpy(&(p_Quant->OffsetList8x8[i][0][0]),&(Offset8_intra_flat_intra[0]), 64 * sizeof(short)); for (k = 1; k < 3; k++) // 1,2 (INTRA8X8_LUMA_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_intra_flat_inter[0]), 64 * sizeof(short)); for (k = 3; k < 5; k++) // 3,4 (INTER8X8_LUMA_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_inter_flat[0]), 64 * sizeof(short)); // 5 (INTRA8X8_CHROMAU_INTRA) memcpy(&(p_Quant->OffsetList8x8[i][5][0]),&(Offset8_intra_flat_chroma[0]), 64 * sizeof(short)); for (k = 6; k < 8; k++) // 6,7 (INTRA8X8_CHROMAU_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_intra_flat_inter[0]), 64 * sizeof(short)); for (k = 8; k < 10; k++) // 8,9 (INTER8X8_CHROMAU_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_inter_flat[0]), 64 * sizeof(short)); // 10 (INTRA8X8_CHROMAV_INTRA) memcpy(&(p_Quant->OffsetList8x8[i][10][0]),&(Offset8_intra_flat_chroma[0]), 64 * sizeof(short)); for (k = 11; k < 13; k++) // 11,12 (INTRA8X8_CHROMAV_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_intra_flat_inter[0]), 64 * sizeof(short)); for (k = 13; k < 15; k++) // 8,9 (INTER8X8_CHROMAV_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_inter_flat[0]), 64 * sizeof(short)); } else if (p_Inp->OffsetMatrixFlat == 2) { // 0 (INTRA4X4_LUMA_INTRA) memcpy(&(p_Quant->OffsetList4x4[i][0][0]),&(Offset_intra_default_intra[0]), 16 * sizeof(short)); for (k = 1; k < 3; k++) // 1,2 (INTRA4X4_CHROMA_INTRA) memcpy(&(p_Quant->OffsetList4x4[i][k][0]),&(Offset_intra_flat_chroma[0]), 16 * sizeof(short)); memcpy(&(p_Quant->OffsetList4x4[i][3][0]),&(Offset_intra_default_inter[0]), 16 * sizeof(short)); for (k = 4; k < 6; k++) // 4,5 (INTRA4X4_CHROMA_INTERP) memcpy(&(p_Quant->OffsetList4x4[i][k][0]),&(Offset_intra_flat_inter[0]), 16 * sizeof(short)); memcpy(&(p_Quant->OffsetList4x4[i][6][0]),&(Offset_intra_default_inter[0]), 16 * sizeof(short)); for (k = 7; k < 9; k++) // 7,8 (INTRA4X4_CHROMA_INTERB) memcpy(&(p_Quant->OffsetList4x4[i][k][0]),&(Offset_intra_flat_inter[0]), 16 * sizeof(short)); for (k = 9; k < 25; k++) // 9,10,11,12,13,14 (INTER4X4) memcpy(&(p_Quant->OffsetList4x4[i][k][0]),&(Offset_inter_default[0]), 16 * sizeof(short)); // 0 (INTRA8X8_LUMA_INTRA) memcpy(&(p_Quant->OffsetList8x8[i][0][0]),&(Offset8_intra_default_intra[0]), 64 * sizeof(short)); for (k = 1; k < 3; k++) // 1,2 (INTRA8X8_LUMA_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_intra_default_inter[0]), 64 * sizeof(short)); for (k = 3; k < 5; k++) // 3,4 (INTER8X8_LUMA_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_inter_default[0]), 64 * sizeof(short)); // 5 (INTRA8X8_CHROMAU_INTRA) memcpy(&(p_Quant->OffsetList8x8[i][5][0]),&(Offset8_intra_flat_chroma[0]), 64 * sizeof(short)); for (k = 6; k < 8; k++) // 6,7 (INTRA8X8_CHROMAU_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_intra_flat_inter[0]), 64 * sizeof(short)); for (k = 8; k < 10; k++) // 8,9 (INTER8X8_CHROMAU_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_inter_default[0]), 64 * sizeof(short)); // 10 (INTRA8X8_CHROMAV_INTRA) memcpy(&(p_Quant->OffsetList8x8[i][10][0]),&(Offset8_intra_flat_chroma[0]), 64 * sizeof(short)); for (k = 11; k < 13; k++) // 11,12 (INTRA8X8_CHROMAV_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_intra_flat_inter[0]), 64 * sizeof(short)); for (k = 13; k < 15; k++) // 8,9 (INTER8X8_CHROMAV_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_inter_default[0]), 64 * sizeof(short)); } else { // 0 (INTRA4X4_LUMA_INTRA) memcpy(&(p_Quant->OffsetList4x4[i][0][0]),&(Offset_intra_default_intra[0]), 16 * sizeof(short)); for (k = 1; k < 3; k++) // 1,2 (INTRA4X4_CHROMA_INTRA) memcpy(&(p_Quant->OffsetList4x4[i][k][0]),&(Offset_intra_default_chroma[0]), 16 * sizeof(short)); for (k = 3; k < 9; k++) // 3,4,5,6,7,8 (INTRA4X4_LUMA/CHROMA_INTERP/INTERB) memcpy(&(p_Quant->OffsetList4x4[i][k][0]),&(Offset_intra_default_inter[0]), 16 * sizeof(short)); for (k = 9; k < 25; k++) // 9,10,11,12,13,14 (INTER4X4) memcpy(&(p_Quant->OffsetList4x4[i][k][0]),&(Offset_inter_default[0]), 16 * sizeof(short)); // 0 (INTRA8X8_LUMA_INTRA) memcpy(&(p_Quant->OffsetList8x8[i][0][0]),&(Offset8_intra_default_intra[0]), 64 * sizeof(short)); for (k = 1; k < 3; k++) // 1,2 (INTRA8X8_LUMA_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_intra_default_inter[0]), 64 * sizeof(short)); for (k = 3; k < 5; k++) // 3,4 (INTER8X8_LUMA_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_inter_default[0]), 64 * sizeof(short)); // 5 (INTRA8X8_CHROMAU_INTRA) memcpy(&(p_Quant->OffsetList8x8[i][5][0]),&(Offset8_intra_default_chroma[0]), 64 * sizeof(short)); for (k = 6; k < 8; k++) // 6,7 (INTRA8X8_CHROMAU_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_intra_default_inter[0]), 64 * sizeof(short)); for (k = 8; k < 10; k++) // 8,9 (INTER8X8_CHROMAU_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_inter_default[0]), 64 * sizeof(short)); // 10 (INTRA8X8_CHROMAV_INTRA) memcpy(&(p_Quant->OffsetList8x8[i][10][0]),&(Offset8_intra_default_chroma[0]), 64 * sizeof(short)); for (k = 11; k < 13; k++) // 11,12 (INTRA8X8_CHROMAV_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_intra_default_inter[0]), 64 * sizeof(short)); for (k = 13; k < 15; k++) // 8,9 (INTER8X8_CHROMAV_INTERP/INTERB) memcpy(&(p_Quant->OffsetList8x8[i][k][0]),&(Offset8_inter_default[0]), 64 * sizeof(short)); } } } }/*! ************************************************************************ * \brief * Calculation of the quantization offset parameters at the frame level * * \par Input: * none * * \par Output: * none ************************************************************************ */void CalculateOffset4x4Param (VideoParameters *p_Vid){ QuantParameters *p_Quant = p_Vid->p_Quant; int k; int qp_per, qp; int img_type = ((p_Vid->type == SI_SLICE) ? I_SLICE : (p_Vid->type == SP_SLICE ? P_SLICE : p_Vid->type)); int max_qp_scale = imax(p_Vid->bitdepth_luma_qp_scale, p_Vid->bitdepth_chroma_qp_scale); int max_qp = 51 + max_qp_scale; InputParameters *p_Inp = p_Vid->p_Inp; p_Vid->AdaptRndWeight = p_Inp->AdaptRndWFactor [p_Vid->nal_reference_idc != 0][img_type]; p_Vid->AdaptRndCrWeight = p_Inp->AdaptRndCrWFactor[p_Vid->nal_reference_idc != 0][img_type]; if (img_type == I_SLICE ) { for (qp = 0; qp < max_qp + 1; qp++) { k = p_Quant->qp_per_matrix [qp]; qp_per = Q_BITS + k - OffsetBits; k = p_Inp->AdaptRoundingFixed ? 0 : qp; // Intra4x4 luma update_q_offset4x4(p_Quant->q_params_4x4[0][1][qp], p_Quant->OffsetList4x4[k][ 0], qp_per); // Intra4x4 chroma u update_q_offset4x4(p_Quant->q_params_4x4[1][1][qp], p_Quant->OffsetList4x4[k][ 1], qp_per); // Intra4x4 chroma v update_q_offset4x4(p_Quant->q_params_4x4[2][1][qp], p_Quant->OffsetList4x4[k][ 2], qp_per); } } else if (img_type == B_SLICE) { for (qp = 0; qp < max_qp + 1; qp++) { k = p_Quant->qp_per_matrix [qp]; qp_per = Q_BITS + k - OffsetBits; k = p_Inp->AdaptRoundingFixed ? 0 : qp; // Inter4x4 luma update_q_offset4x4(p_Quant->q_params_4x4[0][0][qp], p_Quant->OffsetList4x4[k][12], qp_per); // Intra4x4 luma update_q_offset4x4(p_Quant->q_params_4x4[0][1][qp], p_Quant->OffsetList4x4[k][ 6], qp_per); // Inter4x4 chroma u update_q_offset4x4(p_Quant->q_params_4x4[1][0][qp], p_Quant->OffsetList4x4[k][13], qp_per); // Intra4x4 chroma u update_q_offset4x4(p_Quant->q_params_4x4[1][1][qp], p_Quant->OffsetList4x4[k][ 7], qp_per); // Inter4x4 chroma v update_q_offset4x4(p_Quant->q_params_4x4[2][0][qp], p_Quant->OffsetList4x4[k][14], qp_per); // Intra4x4 chroma v update_q_offset4x4(p_Quant->q_params_4x4[2][1][qp], p_Quant->OffsetList4x4[k][ 8], qp_per); } } else { for (qp = 0; qp < max_qp + 1; qp++) { k = p_Quant->qp_per_matrix [qp]; qp_per = Q_BITS + k - OffsetBits; k = p_Inp->AdaptRoundingFixed ? 0 : qp; // Inter4x4 luma update_q_offset4x4(p_Quant->q_params_4x4[0][0][qp], p_Quant->OffsetList4x4[k][ 9], qp_per); // Intra4x4 luma update_q_offset4x4(p_Quant->q_params_4x4[0][1][qp], p_Quant->OffsetList4x4[k][ 3], qp_per); // Inter4x4 chroma u update_q_offset4x4(p_Quant->q_params_4x4[1][0][qp], p_Quant->OffsetList4x4[k][10], qp_per); // Intra4x4 chroma u update_q_offset4x4(p_Quant->q_params_4x4[1][1][qp], p_Quant->OffsetList4x4[k][ 4], qp_per); // Inter4x4 chroma v update_q_offset4x4(p_Quant->q_params_4x4[2][0][qp], p_Quant->OffsetList4x4[k][11], qp_per); // Intra4x4 chroma v update_q_offset4x4(p_Quant->q_params_4x4[2][1][qp], p_Quant->OffsetList4x4[k][ 5], qp_per); } }}
- H.264 Quantization
- H.264/MPEG-4 Part 10 White Paper 译(四) Transform & Quantization
- H.264/MPEG-4 Part 10 White Paper 译(四) Transform & Quantization
- H.264/MPEG-4 Part 10 White Paper 译(四) Transform & Quantization(上)
- H.264/MPEG-4 Part 10 White Paper 译(四) Transform & Quantization(中)
- H.264/MPEG-4 Part 10 White Paper 译(四) Transform & Quantization(下)
- Quantization
- Quantization
- Vector quantization
- Trellis quantization
- Vector Quantization
- Vector Quantization
- model quantization
- Iterative Quantization
- Clustering (番外篇): Vector Quantization
- VQ(Vector quantization)
- 聚类 Vector Quantization
- sgu-205 Quantization Problem
- opencv中的Kmeans使用示例
- Example 2 : Multi Sampling And Filtering Methods
- 设计模式笔记-Interpreter解释器模式
- 算法排序之冒泡排序与插入排序
- HBuilder配置SVN
- H.264 Quantization
- PHP中is_file,file_exists的区别,is_file 不能替代file_exits的理由
- 第十五周项目2洗牌
- Java中Properties类的使用
- 【OpenCV_12】旋转视频以及图片 Rotate Image & Video
- Lintcode:数飞机
- java.sql.SQLException: oracle.jdbc.driver.OracleDriver
- linux常用vi编辑器命令
- 移动端头部meta、link书写比较好的案例