什么是宏块?
在 H.264 中,宏块是编码图像时最小的处理单位。它的核心作用包括:
- 帧内预测(Intra Prediction)
- 帧间预测(Inter Prediction)
- 变换、量化、熵编码等
标准定义:
- 一个宏块 = 16×16 像素(亮度 Y 分量)
- 包含:
- 4 个 8×8 的子块(Y 分量)
- 8 个 8×8 的色度块(U、V 分量各 4 个)
为什么用宏块?
视频压缩的本质是去冗余:
- 空间冗余(同一帧内相似区域)→ 帧内预测
- 时间冗余(帧之间变化不大)→ 帧间预测
宏块的使用使得这些处理可以局部进行,提高压缩效率、预测准确性。
宏块划分示意图
一个 1080p(1920×1080)的视频帧会被划分成:
水平宏块数 = 1920 / 16 = 120
垂直宏块数 = 1080 / 16 = 67.5 ≈ 68(不足的部分补0)
总宏块数 ≈ 120 × 68 = 8160
H.264 宏块的编码方式
每个宏块可以选择不同的预测与编码方式来达到最优压缩效果:
帧内编码(Intra)
- 预测模式:4×4、16×16(亮度)、8×8(色度)
- 利用同一帧中已编码的邻近像素预测当前宏块
┌───────────────┐
│ │ ← ← ← ← ← ← ←
│ │ 上方像素
│ 当前宏块 │ ← ← ← ← ← ← ←
│ │
│ │
└───────────────┘
← 左侧像素参与预测
预测方向(示意):
↖ ↑ ↗ ← → ↙ ↓ ↘
帧间编码(Inter)
- 运动估计(Motion Estimation):从前/后帧找“最像”的块
- 支持子块划分(如 16×8、8×16、8×8、4×4)
- 运动矢量(MV):表示宏块如何在时间维度上“移动”
帧 t+1 帧 t
┌────────┐ 查找最相似宏块
│ MB16x16│ ←←←←←←←←←←──────────────┐
└────────┘ 运动矢量 MV │
┌──┴───────┐
│宏块参考 │
└──────────┘
宏块与压缩的关系
机制 | 说明 |
---|---|
预测块分割越小 | 越能贴合图像细节 → 更高质量,但编码复杂度增加 |
全帧重复区域 | 多个宏块会复用相同预测块 → 压缩率提升 |
噪声图像/快速运动 | 预测效果差,宏块间差异大 → 码率增高 |
如何查看宏块信息?
FFmpeg + x264 编码日志
x264 --verbose --output out.mp4 input.y4m
使用 ffmpeg
分析码流:
ffmpeg -debug mb_type -i video.mp4 -f null -
你会看到每帧中宏块的预测类型(I, P, B,Intra, Inter, Skip 等)
H.265 的 CTU
在 H.265 中,宏块(MB)被更灵活的结构**CTU(Coding Tree Unit)**替代:
- 最大支持 64×64 编码单元
- 更灵活的划分(递归四叉树)
这让 H.265 的压缩效率比 H.264 提升约 50%。
名称 | 大小 | 用途 | 特点 |
---|---|---|---|
宏块 (MB) | 16x16 | H.264 最小编码单元 | 用于帧内/帧间预测,支持子块划分 |
CTU (Coding Tree Unit) | 最大 64x64 | H.265 编码单元 | 更灵活,提升压缩效率 |