4. 视频Codec概览
H.264,也叫 AVC,是视频编码领域绕不开的一座里程碑。哪怕到了 2025 年,它依然是兼容性最好、应用最广的编码标准。我做了这么多年音视频,几乎每个项目都会跟它打交道。今天咱们就把它拆开揉碎了讲清楚。
说白了,H.264 的核心就四个东西:宏块怎么切、帧分哪几种、码率怎么控、档次和级别怎么选。搞懂了这些,你就能在项目中做出靠谱的选型决策。
核心要点:H.264 的压缩效率来自三个维度——空间冗余(帧内预测)、时间冗余(帧间预测)、统计冗余(熵编码)。宏块划分和帧类型就是前两个维度的具体实现。
4.1 宏块划分:视频压缩的最小作战单元
宏块(Macroblock,MB)是 H.264 处理的基本单位。标准规定一个宏块是 16×16 的像素块。但你别以为就这么简单——H.264 支持把宏块继续往下拆。
我个人习惯把宏块划分理解成「切蛋糕」:
- 16×16:整块,适合平坦区域(比如天空、白墙)
- 16×8 或 8×16:切成两半,适合有水平或垂直边界的区域
- 8×8:四等分,适合纹理较复杂的区域
- 8×4、4×8、4×4:继续细分,适合细节丰富的区域
我在项目中遇到过一个问题:某个视频会议系统在低码率下画面全是马赛克。排查后发现编码器默认用了 16×16 的宏块,没有启用子块划分。改成允许 8×8 和 4×4 后,码率节省了将近 30%,画质反而更好了。
实战技巧:运动剧烈的场景(比如体育比赛),多用小尺寸子块(8×8 以下);静态场景(比如监控摄像头),用大尺寸宏块更省码率。编码器一般会通过率失真优化(RDO)自动选择,但你可以通过配置参数影响它的决策。
4.2 帧类型:I/P/B 帧的协同工作
H.264 定义了三种帧类型,它们的分工很明确:
| 帧类型 | 全称 | 压缩方式 | 压缩比 | 随机访问 |
|---|---|---|---|---|
| I 帧 | Intra Frame | 只使用帧内预测 | 最低(约 1:10) | 支持 |
| P 帧 | Predictive Frame | 参考前面的 I/P 帧 | 中等(约 1:20) | 不支持 |
| B 帧 | Bi-predictive Frame | 参考前后帧 | 最高(约 1:50) | 不支持 |
你想想看,为什么 B 帧压缩比最高?因为它可以同时参考前面和后面的帧做双向预测。说白了就是「前后都看看,取个平均值」,这样运动估计更准,残差更小。
但 B 帧也有代价——它需要缓存后面的帧才能解码,所以会引入延迟。我曾经在直播项目中为了降低延迟,直接把 B 帧禁用了,只用 I+P 帧。延迟从 500ms 降到了 200ms,画质虽然差了一点,但用户反馈流畅度提升明显。
注意:I 帧虽然压缩比最低,但它是随机访问的入口点。直播场景中 I 帧间隔通常设为 2-5 秒(即 GOP 长度 60-150 帧),点播场景可以设到 10 秒以上。I 帧太密会浪费码率,太疏则切换频道或拖动进度条时等待时间过长。
4.3 码率控制模式:CBR / VBR / ABR
码率控制是编码器的大脑,它决定每一帧分配多少比特。三种主流模式各有适用场景:
CBR(恒定码率)
码率始终保持在目标值附近,波动很小。适合带宽固定的场景,比如视频会议、IPTV。缺点是画面复杂时质量会下降,简单时又浪费码率。
VBR(可变码率)
码率根据画面复杂度动态调整。简单场景用低码率,复杂场景用高码率。适合存储和点播,比如电影、纪录片。质量稳定,但码率峰值可能很高。
ABR(平均码率)
介于 CBR 和 VBR 之间。它允许短时间内的码率波动,但保证长时间的平均码率接近目标值。这是目前直播平台最常用的模式——既控制了带宽成本,又保证了画质。
我记得有一次做短视频 App 的编码优化,产品经理要求「画质好、码率低、不卡顿」。我选了 ABR 模式,设置目标码率 2Mbps,最大码率 4Mbps,缓冲区大小 2 秒。实测下来,静态场景码率降到 1.2Mbps,运动场景冲到 3.5Mbps,整体平均 2.1Mbps,用户反馈非常好。
选型建议:
- 实时通信(WebRTC、视频会议):CBR,避免码率抖动导致丢包
- 点播/存储(电影、课程):VBR,追求画质一致性
- 直播/短视频:ABR,平衡画质和带宽
4.4 Profile 与 Level:兼容性的关键
Profile(档次)定义了编码器支持哪些工具集,Level(级别)定义了分辨率、帧率、码率的上限。选错了,解码器可能播不了。
Profile 的选择
| Profile | 支持特性 | 典型应用 |
|---|---|---|
| Baseline | I/P 帧、CAVLC、无 B 帧 | 低端手机、视频会议 |
| Main | I/P/B 帧、CAVLC/CABAC、加权预测 | 标清电视、DVD |
| High | 8×8 变换、自定义量化矩阵、更多色度格式 | 高清/超高清、蓝光、流媒体 |
我个人的建议是:除非你确定解码器只支持 Baseline(比如某些老旧的嵌入式设备),否则直接用 High Profile。它比 Main Profile 平均节省 10-15% 的码率,而且兼容性已经很好了。
Level 的选择
Level 用数字表示,比如 3.0、4.0、5.0。每个 Level 对应一组约束:
- Level 3.0:最大 720×576@30fps,码率 10Mbps
- Level 4.0:最大 1920×1080@30fps,码率 20Mbps
- Level 4.1:最大 1920×1080@60fps,码率 50Mbps
- Level 5.0:最大 2560×1920@30fps,码率 135Mbps
嗯,这里要注意:Level 不是越高越好。选高了,老设备解码会卡;选低了,高分辨率视频会被限制。我一般按「目标分辨率×帧率」查表选择,然后向上兼容一级。
避坑指南:我曾经在某个项目中把 Level 设成了 5.1,结果用户的一批旧手机播放时直接黑屏。后来发现那些手机的硬件解码器只支持到 Level 4.1。从那以后,我养成了习惯——先调研目标设备的解码能力,再定 Level。
4.5 知识体系总览
下面这张图把 H.264 的核心知识点串起来了。你可以把它当作选型时的检查清单:
这张图把 H.264 的四个核心维度串在了一起。你选型的时候,按这个顺序走一遍,基本不会出大问题。
最后提醒一句:H.264 虽然成熟,但坑也不少。比如某些编码器对 B 帧数量有限制,某些解码器不支持 CABAC(Context-based Adaptive Binary Arithmetic Coding)。我的经验是——先做兼容性测试,再上线。花半天时间跑一遍各种设备的解码测试,能省下后面几周的排查时间。