视频编码中的 I帧、P帧、B帧

理解 I帧、P帧、B帧是学习视频编解码、WebRTC、直播技术的基础。本文从「为什么需要三种帧」出发,讲清楚三者的定义、解码顺序、以及 WebRTC 为什么不用 B帧。


一、为什么需要这三种帧

视频本质是一串图片,每秒 30 帧就是 30 张图。如果每张都完整存储,1080p 视频 1 秒钟原始数据大约 400MB,完全没法传输。

压缩的核心思路:相邻帧之间变化很小,只记录「变了什么」,不记录「完整画面」

三种帧就是围绕这个思路设计的:

  • I帧:必须有一张完整的参考图
  • P帧:只记录相对前一帧的变化
  • B帧:同时参考前后帧,压缩率最高

二、三种帧的定义

I帧(Intra-coded frame,帧内编码帧)

1
2
3
完整的一张图,不依赖任何其他帧,可以独立解码
类比:一张完整的照片
体积:最大(是 P 帧的 3-5 倍)

P帧(Predictive frame,预测帧)

1
2
3
4
只记录「相对于前一帧,哪些地方变了」
类比:对上一张照片的修改说明「左上角的人移动了 5 个像素」
依赖:必须有前面的 I 帧或 P 帧才能解码
体积:比 I 帧小很多

B帧(Bidirectional frame,双向预测帧)

1
2
3
4
同时参考前一帧(I或P)和后一帧(I或P)来预测当前帧
类比:「这帧介于前后两帧之间,取个平均」
依赖:需要前面和后面的 I/P 帧才能解码(不依赖其他 B 帧)
体积:最小

三、解码顺序详解

播放顺序 vs 编码/传输顺序

假设一段视频的播放顺序是:

1
2
I  B  B  P  B  B  P  I
1 2 3 4 5 6 7 8 ← 帧编号(按播放时间)

但实际编码和传输顺序是:

1
2
I  P  B  B  P  B  B  I
1 4 2 3 7 5 6 8 ← 重排了!

为什么要重排?

B帧(第2、3帧)解码时需要参考「后面」的 P帧(第4帧),所以 P帧必须先传输到达,B帧才能解码。编码器提前把 P帧排到 B帧前面。

逐帧解码过程

1
2
3
4
5
6
7
8
9
10
11
收到顺序:  I(1) → P(4) → B(2) → B(3) → P(7) → B(5) → B(6) → I(8)

① 收到 I(1) → 直接解码,立刻输出第1帧
② 收到 P(4) → 先缓存,等 B(2) B(3) 解码完再输出
③ 收到 B(2) → 参考 I(1) 和 P(4) → 解码,输出第2帧
④ 收到 B(3) → 参考 I(1) 和 P(4) → 解码,输出第3帧
⑤ 输出 P(4) → 第4帧
⑥ 收到 P(7) → 先缓存
⑦ 收到 B(5) → 参考 P(4) 和 P(7) → 解码,输出第5帧
⑧ 收到 B(6) → 参考 P(4) 和 P(7) → 解码,输出第6帧
⑨ 输出 P(7) → 第7帧

B帧只依赖 I/P帧,不依赖其他 B帧

这是一个常见的误解:B(2) 和 B(3) 互相不依赖,两者都只参考前后的 I/P 帧。

1
2
3
4
5
6
7
I  B  B  P
1 2 3 4

B(2) 依赖 → I(1) 和 P(4)
B(3) 依赖 → I(1) 和 P(4)

B(2) 和 B(3) 互相独立,可以并行解码

只要 I(1) 和 P(4) 都到了,B(2) 和 B(3) 可以同时解码,不需要等对方。

特殊情况:分层 B帧(了解即可)

高压缩率编码器(如 x265)会用分层 B帧,B帧之间也可以互相参考:

1
2
3
I              P
B B
B B

中间的 B 参考外层的 B,外层的 B 再参考 I/P。压缩率更高,但解码复杂度和延迟也更大。WebRTC 完全不使用这种模式。


四、B帧引入的延迟

每个 B帧都需要等它后面的 P/I 帧到达后才能解码,播放器必须缓冲几帧,等「未来帧」到齐再解码输出:

1
2
缓冲区:[I(1), P(4), B(2), B(3)] → 等 P(4) 到了才能输出 B(2) B(3)
→ 额外延迟 60-200ms

五、WebRTC 为什么不用 B帧

1
2
3
4
5
6
7
B帧需要等「未来帧」到了才能解码
→ 必须缓冲几帧
→ 引入 60-200ms 额外延迟

实时通话不能接受这个延迟
→ WebRTC 默认禁用 B帧
→ 只用 I帧 + P帧

只用 I + P 的解码流程

1
2
3
4
5
收到顺序:  I(1) → P(2) → P(3) → P(4) → ...

① 收到 I(1) → 立刻解码,立刻输出
② 收到 P(2) → 参考 I(1),立刻解码,立刻输出
③ 收到 P(3) → 参考 P(2),立刻解码,立刻输出

收到即解码,零缓冲,延迟低。代价是压缩率不如有 B帧的方案,同等画质码率更高。


六、I帧(关键帧)的实际意义

视频跳转(Seek)

视频 seek 时必须找到最近的 I帧开始解码,因为 P/B 帧无法独立解码。这就是为什么有些视频跳转不精确——只能跳到最近的关键帧位置。

花屏恢复

网络丢包导致某个 P帧丢失,之后所有依赖它的帧都无法正确解码 → 花屏。等到下一个 I帧到来才能恢复正常画面。

WebRTC 的 PLI 机制

WebRTC 检测到花屏时,接收端发 PLI(Picture Loss Indication) 给发送端,请求立即插入一个 I帧:

1
2
3
4
接收端发现花屏
→ 发 RTCP PLI 给发送端
→ 发送端立刻插入一个 I帧
→ 接收端收到后画面恢复正常

七、对比总结

I帧 P帧 B帧
完整画面
依赖 前面的 I/P 帧 前后的 I/P 帧
体积 最小
解码延迟 高(需缓冲未来帧)
WebRTC 使用
适用场景 所有 所有 点播/录制

最后更新:2026-06