- H.264/AVC
- H.265/HEVC
- 帧内预测:略
- 帧间预测
详细解析视频编解码中帧间预测最核心的概念。它们共同构成了现代视频压缩技术的骨架。
一、I帧、P帧、B帧(帧类型)
这三种帧类型是视频压缩的基石,它们决定了帧与帧之间是如何压缩和依赖的。
1. I帧(Intra-coded frame,帧内编码帧)
-
别名:关键帧
-
编码方式 :独立编码。I帧只利用本帧图像内部的空间冗余进行压缩,类似于一张JPEG图片。它不需要参考任何其他帧。
-
特点:
-
自包含:可以独立解码。
-
数据量大:因为只进行帧内压缩,压缩率相对较低。
-
随机访问点:视频的播放、快进、快退等操作,都需要定位到I帧才能开始。
-
-
比喻 :一本漫画书中的完整画面。你不需要看前面的页面也能理解这一页的内容。
2. P帧(Predicted frame,前向预测帧)
-
编码方式 :参考编码 。P帧需要参考前面最近的一个I帧或P帧 来进行压缩。它只存储与参考帧之间的差异信息(运动向量和残差)。
-
特点:
-
向前参考:只参考前面的帧。
-
数据量较小:因为只存储差异,压缩率比I帧高。
-
有依赖性:解码P帧必须先正确解码它所参考的帧。
-
-
比喻 :漫画书中表示"这个人物从画面左边移动到了右边"的指令。你需要知道上一页(参考帧)的样子,才能根据指令画出当前页。
3. B帧(Bi-directionally predicted frame,双向预测帧)
-
编码方式 :高级参考编码 。B帧是压缩率最高的帧类型。它同时参考前面和后面的帧(I帧或P帧)来进行压缩。
-
特点:
-
双向参考:可以同时参考过去和未来的帧。
-
数据量最小:压缩率最高。
-
依赖性最强:解码B帧必须先解码它参考的所有帧(包括它后面的帧)。这导致了编码和解码顺序与显示顺序的不同。
-
计算更复杂:编码和解码时需要更大的缓存和更高的计算量。
-
-
比喻 :漫画书中表示"将第一页和第三页中的人物合成,得到第二页"的指令。你需要同时知道前一页和后一页,才能画出当前页。
三种帧的数据量与依赖性对比:
I帧 > P帧 > B帧(数据量)
I帧 < P帧 < B帧(依赖性)
二、GOP(Group of Pictures,图像组)
1. 什么是GOP?
一个GOP就是两个I帧之间的图像序列。它是一个独立的编码单元,也是视频随机访问的基本单位。
2. GOP的结构
一个GOP由一個I帧开始,后面跟着一系列的P帧和B帧。
-
GOP长度:GOP中包含的帧的数量。例如,GOP长度为12,表示每12帧有一个I帧。
-
GOP结构模式:
-
开放式GOP:B帧可以跨越GOP的边界,参考下一个GOP的I帧。压缩效率更高,是现代编码器(如x264/x265)的默认模式。
-
封闭式GOP:GOP之间完全独立,不存在跨GOP的参考。更适合视频编辑和流媒体切换。
-
示例 :一个简单的GOP结构:IBBPBBPBBPBBP
3. GOP长度的影响
-
长GOP:
-
优点:I帧数量少,平均压缩率高,文件小。
-
缺点:随机访问不频繁(快进快退不灵活),容错性差(一个帧出错会影响整个GOP)。
-
-
短GOP:
-
优点:随机访问频繁,容错性好。
-
缺点:I帧数量多,压缩率低,文件大。
-
应用场景:
-
视频点播:通常使用较长的GOP(如250帧以上),以最大化压缩效率。
-
直播:使用较短的GOP(如1-2秒,例如25-50帧),以降低延迟并提高容错性。
-
视频编辑:通常使用非常短的GOP(如全I帧),便于精确剪切。
三、POC(Picture Order Count,图像顺序计数)
POC是一个相对复杂但至关重要的概念,用于解决编码顺序 和显示顺序不一致的问题。
1. 问题的产生:DTS和PTS
由于B帧的存在,解码器需要先解码后面的参考帧,才能解码B帧。这就导致了:
-
解码顺序 :帧被解码的先后顺序。
I0, P3, B1, B2, P6, B4, B5, ... -
显示顺序 :帧在屏幕上显示的先后顺序。
I0, B1, B2, P3, B4, B5, P6, ...
解码顺序等于编码顺序
在视频流中,用DTS 和PTS来标识这两个顺序:
-
DTS:解码时间戳
-
PTS:显示时间戳
2. POC的作用
POC是H.265/HEVC中用来唯一标识一帧图像在显示序列中的位置的整数值。它是一个逻辑序号,与PTS等价,但在编解码内部使用。
-
核心功能:
-
确定显示顺序:解码器通过比较POC值的大小,就能知道帧的正确显示顺序。
-
管理参考帧缓冲区:解码器需要知道哪些帧是参考帧,以及它们之间的前后关系。POC是管理这个缓冲区的关键索引。
-
推导运动向量:在帧间预测中,运动向量的缩放和预测都依赖于POC的差值。
-
3. 为什么会在错误信息中看到POC?
错误信息 "Could not find ref with POC 2"的含义是:
解码器正在解码当前帧,该帧的预测指令告诉它:"你需要参考POC值为2的那一帧来计算当前帧"。
但解码器在自己的参考帧缓冲区里找不到POC=2的帧。
这通常意味着:
-
视频流损坏:包含POC=2的那一帧(可能是一个I帧或P帧)在传输或存储过程中丢失或损坏了。
-
解码器bug:参考帧管理出现错误,提前将POC=2的帧从缓冲区中移除了。

四、它们如何协同工作:
-
编码器决定一个GOP 结构(如
IBBPBBP)。 -
在编码这个GOP时,I帧独立编码;P帧参考前面的帧;B帧参考前后帧。这导致编码顺序 与显示顺序不同。
-
编码器为每一帧分配一个唯一的POC 值,来标识其真正的显示顺序。
-
这个GOP数据(包含帧数据和POC信息)被打包进码流。
-
解码器收到码流后,先按编码顺序 解码每一帧,然后根据POC 值将它们重新排序,得到正确的显示顺序并输出。
五、例子
RTSP视频流在OpenCV-Python中的完整处理流程,结合编码、传输、解码和显示的细节说明
1. 编码器侧 (HEVC编码)
输入顺序 :摄像头按时间顺序生成帧 F0, F1, F2, F3...
编码关键规则:
-
B帧需等待后续参考帧就绪才能编码
-
I帧优先编码,P帧次之,B帧最后
示例GOP结构: I-B-B-P-B-B-P...
显示顺序(POC): 0(I),1(B),2(B),3(P),4(B),5(B),6(P)...
编码顺序(DTS): 0(I),3(P),1(B),2(B),6(P),4(B),5(B)...
**编码顺序≠帧产生顺序:** B帧会导致编码顺序滞后(如帧1在帧3之后编码)
数据封装
2. 网络传输 (RTSP/RTP)
# 按编码顺序发送:
I0 -> P3 -> B1 -> B2 -> P6 -> B4 -> B5...
关键特性:
-
每个RTP包携带时间戳(DTS)
-
I帧数据较大,可能分多个RTP包
-
网络丢包可能导致参考帧丢失(引发POC错误)
GOP是否整组传输?
❌ 否!RTSP是流式传输,切片(Slice)到达即发送
3. OpenCV处理流程 (opencv-python)
内部解码机制 (FFmpeg)
OpenCV是否整GOP解码?
❌ 否!FFmpeg是增量解码:
-
收到I帧立即解码
-
P帧在参考帧就绪时解码
-
B帧在所有参考帧到位后解码
详情看文章 使用opencv-python 处理HEVC格式RTSP视频流
4. 显示处理 (cv2.imshow)
-
显示顺序:严格按POC顺序
-
同步机制:
-
使用帧的PTS(显示时间戳)
-
动态调整显示速率匹配源帧率
-
显示是否等待整GOP?
❌ 否!显示严格按POC顺序:
-
I帧解码后立即显示
-
B帧在参考帧显示后立即显示
5.完整的视频传输流程
视频流显示完整流程图
网络缓冲区:存储原始压缩数据
解码帧缓冲区(DPB):存储已解码帧
三个环节并行运作,通过缓冲区解耦
三重异步机制
6.DPB(Decoded Picture Buffer)管理
帧类型决定释放时机
| 帧类型 | 释放条件 | 示例 |
|---|---|---|
| B帧 | 显示后立即释放 | POC1(B)显示后直接释放 |
| P帧 | 被后续帧引用结束后释放 | POC3(P)需等到POC6(P)解码完成 |
| I帧 | 整个GOP结束后释放 | I0在GOP最后一个POC显示后释放 |

典型场景示例
假设GOP结构:I0 B1 B2 P3 B4 B5 P6,DPB容量=4
| 时间点 | 解码帧 | DPB状态 | 动作 |
|---|---|---|---|
| t1 | I0解码 | [I0] | 立即显示I0 |
| t2 | P3解码 | [I0, P3] | P3不显示(等待B1/B2) |
| t3 | B1解码 | [I0, P3, B1] | 显示B1→释放B1 |
| t4 | B2解码 | [I0, P3, B2] | 显示B2→释放B2 |
| t5 | P6解码 | [I0, P3, P6] | DPB满! |
| t6 | B4到达 | DPB仍满 | 丢弃B4 |
| t7 | B5解码 | 尝试解码 | 失败(缺少参考帧B4) |
|----|------|------|-------------|
| t7 | B5解码 | 尝试解码 | 失败(缺少参考帧B4) |
触发Could not find ref with POC4

六、通用核心概念对比
之前讨论的I/B/P帧、GOP、POC、DPB管理 等概念是H.264和H.265的通用模式,但两者在具体实现和技术细节上有重要差异。
| 概念 | H.264/AVC | H.265/HEVC | 是否通用 |
|---|---|---|---|
| I/P/B帧类型 | ✅ 支持 | ✅ 支持 | ✅ 完全通用 |
| GOP结构 | ✅ 支持 | ✅ 支持 | ✅ 完全通用 |
| 参考帧管理 | ✅ DPB机制 | ✅ DPB机制 | ✅ 完全通用 |
| POC概念 | ✅ 存在(frame_num) | ✅ 增强POC | ✅ 概念通用 |
| 预测方向 | ✅ 帧内/帧间预测 | ✅ 帧内/帧间预测 | ✅ 完全通用 |
