📄 一句话概括
四种帧里最容易混的是 I 帧与 IDR 帧——所有 IDR 都是 I 帧,但不是所有 I 帧都是 IDR;拖动定位找的其实是 IDR。
📝 本节和前面几节的关系
6.4 讲了帧内与帧间编码,6.5 收在三个具体结构上。先分清四种帧。
一、四种帧
I 帧:帧内编码,不参考任何帧——能独立解码。 P 帧:帧间编码,只参考前面的帧。 B 帧:帧间编码,参考前后两侧。 IDR 帧:一种特殊的 I 帧——明确切断与前面所有帧的依赖。
二、I 帧与 IDR 帧的差别
这是最容易混的一点: 所有 IDR 都是 I 帧——它本身也是帧内编码的。 但不是所有 I 帧都是 IDR——有些 I 帧【参考列表里还留着前面的帧】。 差别在实际效果上:IDR 之后的帧,绝不能再参考 IDR 之前的帧。 所以 IDR 才是真正的【随机访问点】。
三、为什么这个差别重要
因为播放器拖进度条时,要找的是 IDR 帧,而不是随便一个 I 帧。 如果从一个普通的 I 帧开始解,后面的帧可能还要参考更早的内容——解不出来。 所以【关键帧间隔】这个参数(5.1.4 提过),严格说的其实是 IDR 间隔。
四、四者的取舍
I/IDR 帧:贵,但提供落脚点——不能没有。 P 帧:省,延迟低——实时场景的主力。 B 帧:最省,但要缓存与重排序——点播场景的主力。 所以编码档位里往往有一项【是否允许 B 帧】,它直接对应延迟与码率的取舍。
五、动手 Demo:I、P、B、IDR 四种帧,各是什么角色
除了 I/P/B,还有一个特殊角色:IDR 帧。
rows = [("I 帧", "能", "不参考任何帧,但未必是随机访问点"),
("IDR 帧", "能", "I 帧的一种,明确切断依赖"),
("P 帧", "不能", "只参考前面"),
("B 帧", "不能", "参考前后,码率最低")]
for a, b, c in rows:
print("%-8s %-14s %s" % (a, b, c))
实跑输出:
--------------------------------------------------------------------
I、P、B、IDR 四种帧,各是什么角色
--------------------------------------------------------------------
除了 I/P/B,还有一个特殊角色:IDR 帧。
帧 能否独立解码 关键特征
-------------------------------------------------------------
I 帧 能 不参考任何帧,但未必是随机访问点
IDR 帧 能 I 帧的一种,明确切断依赖
P 帧 不能 只参考前面
B 帧 不能 参考前后,码率最低
最容易混的是前两行:**所有 IDR 都是 I 帧,但不是所有 I 帧都是 IDR。**
差别在于:**IDR 之后的帧绝不能再参考 IDR 之前的帧**——
所以拖动定位时,**找的其实是 IDR 帧,而不只是 I 帧**。
最容易混的是前两行:所有 IDR 都是 I 帧,但不是所有 I 帧都是 IDR。 所以拖动定位时,找的其实是 IDR 帧,而不只是 I 帧。
30 秒实验
- 用 ffprobe 加
-show_frames看一段视频,找出其中的 IDR 帧。 - 看它们是不是都带着 key_frame=1 的标记。
常见误区
- 把 I 帧与 IDR 帧当成一回事。IDR 才是真正的随机访问点。
- 以为 B 帧在任何场景都更优。低延迟场景要禁用它。
自测三问(点开对答案)
1. I 帧与 IDR 帧的关系是什么? —— 所有 IDR 都是 I 帧,但不是所有 I 帧都是 IDR。 2. 为什么拖动定位要找 IDR 帧? —— IDR 切断了与前面所有帧的依赖,从它开始才能独立解码。 3. 四类帧在码率与延迟上怎么取舍? —— I/IDR 贵但提供落脚点,P 帧省且延迟低,B 帧最省但要缓存重排序。- ☐ 下一节(6.5.2 GOP详细讲解)
相关笔记
- GOP详细讲解 — 这些帧怎么组成一组
- 帧内编码 — I 帧用的技术
- 视频的基础概念 — 关键帧间隔这个参数
- 🎬 FFmpeg入门详解 · 索引