H.264工作原理解析
H.264工作原理解析
H.264,也称为MPEG-4 Part 10或AVC(Advanced Video Coding),是一种广泛使用的视频压缩标准,由ITU-T视频编码专家组(VCEG)和ISO/IEC运动图像专家组(MPEG)联合开发。自2003年发布以来,H.264已成为视频编码领域的主流技术,广泛应用于视频流媒体、蓝光光盘、视频会议、数字电视和移动设备等领域。
格式发展
编码格式 | 发布年份 | 备注 |
---|---|---|
MPEG-1 | 1993 | 主要用于VCD,包含MP3音频编码 |
MPEG-2 | 1995 | 主要用于DVD、数字电视广播 |
MPEG-4 | 1999 | 包括Part 2(ASP)和Part 10(AVC,即H.264) |
H.263 | 1996 | 早期的视频压缩标准,主要用于视频会议 |
H.264 (AVC) | 2003 | 目前仍广泛应用于网络视频、高清电视等 |
H.265 (HEVC) | 2013 | 相比H.264提升约50%压缩率 |
VP8 | 2008 | Google收购On2后开源,用于WebM |
VP9 | 2013 | Google推出,改进VP8,提高压缩效率 |
AV1 | 2018 | 由AOMedia开发,开源、免专利费,竞争H.265 |
AAC | 1997 | 先进音频编码,广泛用于流媒体 |
Opus | 2012 | 适用于语音和音乐,低延迟,高质量 |
工作原理
1. 帧分割
视频被分割成多个帧(Frame),分为I帧(关键帧)、P帧(前向参考帧)、B帧(双向参考帧),以减少数据冗余。
2. 预测(帧内/帧间)
帧内预测(Intra Prediction): 利用当前帧的相邻像素进行预测,减少空间冗余。
示例 1:4×4 块的垂直预测(模式 1)
假设当前4×4 宏块需要预测,其上方像素(A, B, C, D)已经编码:
A B C D
? ? ? ?
? ? ? ?
? ? ? ?
? ? ? ?
已编码的上方像素:
A = 100, B = 102, C = 104, D = 106
垂直预测规则:
模式 1(Vertical Prediction):
- 直接复制上方像素A, B, C, D到整个 4×4 宏块的每一行。
预测后的宏块
100 102 104 106
100 102 104 106
100 102 104 106
100 102 104 106
适用场景: 图像存在明显的垂直条纹或纹理时,使用垂直预测可以更好地减少编码误差。
示例 2:4×4 块的水平预测(模式 2)
假设当前4×4 宏块需要预测,其左侧像素(I, M, Q, U)已经编码:
| ? | ? | ? | ? |
| ? | ? | ? | ? |
| ? | ? | ? | ? |
| ? | ? | ? | ? |
已编码的左侧像素:
I = 90
M = 92
Q = 94
U = 96
水平预测规则:
模式 2(Horizontal Prediction):
- 直接复制左侧像素I, M, Q, U到整个 4×4 宏块的每一列。
预测后的宏块
90 90 90 90
92 92 92 92
94 94 94 94
96 96 96 96
适用场景: 图像存在水平条纹或边缘时,水平预测可以有效减少误差。
实际 H.264 还支持其他 4×4 预测模式,如:
- 模式 3:对角预测(根据 A 传播到右下角)
- 模式4:DC预测
如果当前宏块是16×16,H.264 提供了:
- DC 预测(DC Prediction):使用左侧和上方像素的平均值填充整个 16×16 宏块。
- 水平预测(Horizontal Prediction):每一行的像素都填充左侧边界的值。
- 垂直预测(Vertical Prediction):每一列的像素都填充上方边界的值。
- 平滑预测(Plane Prediction):适用于渐变区域,利用边界像素计算梯度进行预测。
帧间预测(Inter Prediction): 利用前后帧的运动补偿来预测当前帧,减少时间冗余。
帧间预测(Inter Prediction)
适用于 P 帧和 B 帧,它利用运动估计(Motion Estimation)和运动补偿(Motion Compensation)来减少数据量。
运动估计:
计算当前帧和参考帧之间的差异
生成运动向量(Motion Vector),指示块是如何移动的
运动补偿:
只存储运动向量 + 预测误差,不存储整个块
示例:
假设前一帧里一个小球的像素值如下:
100 100 100 100
100 100 100 100
100 100 100 100
100 100 100 100
而在当前帧里,小球向右移动了 2 个像素:
0 0 100 100
0 0 100 100
0 0 100 100
0 0 100 100
编码器不会存储完整的像素数据,而是存储:
运动向量 (右移 2 像素) + 误差(前两个像素变成 0)
这样可以极大减少存储需求。
3. 变换与量化
采用整数离散余弦变换(Integer DCT,类似DCT)将空间域数据转换为频域数据,便于压缩。 进行量化(Quantization),降低数据精度以减少比特率。
变换(Integer Transform)示例
H.264 采用4×4 整数变换(Integer Transform),类似于离散余弦变换(DCT),但计算更简单。
示例输入:4×4 像素块
假设编码器要处理一个 4×4 的亮度(Luma)块,其像素值如下:
200 202 189 175
198 204 190 178
195 200 193 185
190 198 192 180
这是来自原始视频帧的像素亮度值。
第一步:转换到差分表示
H.264 先通过帧内预测或帧间预测生成一个预测块(即估计的像素值),然后计算残差(Residual):
残差 = 实际像素 - 预测像素
假设预测块如下:
198 200 190 176
197 202 190 178
195 199 192 184
192 197 191 181
计算残差块(Residual Block):
2 2 -1 -1
1 2 0 0
0 1 1 1
-2 1 1 -1
这个残差块表示像素值的变化量。
第二步:4×4 整数变换
H.264 使用整数变换矩阵T 将残差块变换到频率域:
其中,XXX 是残差块,TTT 是H.264 变换矩阵:
计算后,变换系数矩阵 YYY 可能如下:
4 -2 0 1
-3 1 0 -1
0 1 -1 0
1 -2 0 1
这里:
- 左上角的低频分量(如 4)保留主要图像信息
- 其他高频分量(如 -2, 0, 1)包含细节信息
量化(Quantization)
变换后的系数矩阵 YYY 还需要量化,以进一步减少数据量:
H.264 使用量化步长(QP)控制压缩率,例如:
4/2 -2/2 0/2 1/2
-3/2 1/2 0/2 -1/2
0/2 1/2 -1/2 0/2
1/2 -2/2 0/2 1/2
如果四舍五入后:
2 -1 0 0
-2 1 0 0
0 0 0 0
0 0 0 0
结果中很多高频系数变为 0,这就是H.264 压缩的关键。
4. 熵编码
采用CAVLC(上下文自适应变长编码)或CABAC(上下文自适应二进制算术编码),进一步压缩数据,提高编码效率。
熵编码是一种无损压缩技术,在H.264等视频压缩标准中用于进一步减少比特数。常见的熵编码方法包括:
- 霍夫曼编码(Huffman Coding)
- 算术编码(Arithmetic Coding)
- CABAC(Context-Adaptive Binary Arithmetic Coding)
- CAVLC(Context-Adaptive Variable-Length Coding)
在 H.264 中,CAVLC 和 CABAC是最常用的熵编码方法。
5. 码流封装
生成符合H.264标准的NALU(网络抽象层单元),用于网络传输或存储。
6. 解码器重建(用于误差恢复)
编码器内部会进行逆变换和去量化,确保解码器可以正确还原视频。