← 首页

WeCodec 知识库 · 视频编码

帧类型与 GOP:I 帧、P 帧、B 帧

I、P、B 三种帧怎么互相参考,GOP 长度怎么取舍

I 帧能单独解码,P 帧参考前面的帧,B 帧可以同时参考前后的帧。压缩率从 I 到 B 依次提高。

GOP 是从一个 I 帧开始的一组帧。GOP 拉长能省码率,代价是拖动起播变慢,出错后也要更久才能恢复。

1. 三种帧各存什么

视频相邻两帧通常差别很小。编码器利用这一点,只有少数帧完整保存,其余帧只记录和参考帧的差别。按参考方式,帧分为三类(维基百科:Video compression picture types)。

I 帧(intra,帧内编码)只用本帧的数据,相当于一张单独压缩的图片。它最占码率,但解码器拿到它就能直接出图。

P 帧(predictive,预测帧)引用之前解码过的帧,只存运动信息和残差。残差是预测画面和真实画面之间的差值。B 帧(bi-predictive,双向预测帧)可以同时引用前面和后面的帧,压缩率最高。

类型参考谁码率开销能否作为起播点
I 帧不参考其他帧最高能
P 帧之前解码的帧中等不能
B 帧前后两个方向的帧最低不能

2. 参考关系长什么样

下图按播放顺序画了 7 帧。P3 参考 I0,P6 参考 P3,串成一条前向链。B1 和 B2 夹在 I0 和 P3 之间,两头都参考。

I0B1B2P3B4B5P6前向参考前向参考B1、B2 同时参考 I0 和 P3
图 1 7 帧的参考关系示意。箭头从被参考的帧指向使用它的帧。B4、B5 同样参考 P3 和 P6,图中省略。

MPEG-2 这类老标准限制很严。P 帧只能参考前面一个 I 帧或 P 帧,B 帧只能参考前后各一帧。H.264 和 HEVC 放宽了限制,可以参考更多帧,B 帧自己也能被参考(维基百科:Group of pictures)。

参考链也会传递错误。某一帧出错,直接或间接参考它的帧都会跟着出错,直到解码器处理到下一个正确的 I 帧(同上)。

3. 播放顺序和解码顺序不同

B 帧要参考后面的帧,所以解码器必须先拿到后面那一帧。编码器因此会调整帧的发送顺序:先发 P3,再发 B1 和 B2。播放器解码后,再按时间顺序排回去。

播放顺序解码顺序I0B1B2P3B4B5P6I0P3B1B2P6B4B5P3 和 P6 被提前,因为后面的 B 帧要用它们
图 2 同一组帧的播放顺序和解码顺序示意。虚线连接同一帧。

解码端也要多做一步。P3 先解出来却不能马上显示,要放在缓存里,等 B1、B2 解完再按顺序送出去。所以用了 B 帧的码流,播放器要多留几帧的缓存。

这也是 B 帧会增加延迟的原因。编码 B1 之前,编码器得先等 P3 的画面到达。视频通话这类对延迟敏感的场景,可以减少或关掉 B 帧,FFmpeg 里对应的选项是 -bf,它设定两个非 B 帧之间最多放几个 B 帧(FFmpeg Codecs Documentation)。

4. GOP 结构:M 和 N

GOP(group of pictures,图像组)是从一个 I 帧开始的一组连续帧。解码器遇到新的 GOP,就不再依赖之前的帧,所以拖动进度条时可以从这里起播(维基百科:Group of pictures)。

GOP 结构常用两个数描述。M 是两个锚帧之间的距离,锚帧指 I 帧或 P 帧。N 是两个 I 帧之间的距离。M=3、N=12 时,结构就是 IBBPBBPBBPBB(同上)。

IBBPBBPBBPBBIM = 3(锚帧间距)N = 12(I 帧间距,也就是 GOP 长度)下一个 GOP
图 3 M=3、N=12 的 GOP 结构。

GOP 还分封闭和开放两种。封闭 GOP 以 IDR 帧开头。IDR(instantaneous decoder refresh,即时解码刷新)是一种带标记的 I 帧,它后面的帧都不会参考它前面的帧。开放 GOP 允许 B 帧越过 I 帧去参考上一个 GOP,这时这个 I 帧就不再是 IDR 帧,不能当作干净的起播点(同上)。

5. GOP 该设多长

I 帧越多,视频越方便剪辑和拖动,但所需码率也会明显上升(维基百科:Group of pictures)。设 GOP 长度,就是在这两者之间取舍。

对比项短 GOP长 GOP
同画质下的码率较高较低
拖动起播快,附近总有 I 帧慢,可能要从较远的 I 帧开始解
出错后恢复快慢
典型场景数字电视常见约半秒一次帧内刷新本地存档、点播
N = 6N = 24■ I 帧■ P 帧■ B 帧柱高代表该帧占用的比特
图 4 同样 24 帧,短 GOP 和长 GOP 的每帧比特数示意。I 帧是明显的尖峰,GOP 越短尖峰越多。

表中数字电视的例子来自维基百科:Video compression picture types。GOP 长度也不必固定。切换场景时插入 I 帧是常见做法(维基百科:Group of pictures),因为新画面和前一帧差别太大,P 帧和 B 帧预测不出有用的内容(维基百科:Video compression picture types)。

在 FFmpeg 里,-g 设 GOP 长度,-keyint_min 设 IDR 帧的最小间隔(FFmpeg Codecs Documentation)。

参考资料

  1. 《Video compression picture types》,Wikipedia https://en.wikipedia.org/wiki/Video_compression_picture_types
  2. 《Group of pictures》,Wikipedia https://en.wikipedia.org/wiki/Group_of_pictures
  3. 《FFmpeg Codecs Documentation》,FFmpeg https://ffmpeg.org/ffmpeg-codecs.html