H264 H265 编码器 解码器原理

  • 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, ...

解码顺序等于编码顺序

在视频流中,用DTSPTS来标识这两个顺序:

  • DTS​:解码时间戳

  • PTS​:显示时间戳

2. POC的作用

POC是H.265/HEVC中用来唯一标识一帧图像在显示序列中的位置的整数值。它是一个逻辑序号,与PTS等价,但在编解码内部使用。

  • 核心功能​:

    1. 确定显示顺序​:解码器通过比较POC值的大小,就能知道帧的正确显示顺序。

    2. 管理参考帧缓冲区​:解码器需要知道哪些帧是参考帧,以及它们之间的前后关系。POC是管理这个缓冲区的关键索引。

    3. 推导运动向量​:在帧间预测中,运动向量的缩放和预测都依赖于POC的差值。

3. 为什么会在错误信息中看到POC?

错误信息 "Could not find ref with POC 2"的含义是:

解码器正在解码当前帧,该帧的预测指令告诉它:"你需要参考POC值为2的那一帧来计算当前帧"。

但解码器在自己的参考帧缓冲区里找不到POC=2的帧。

这通常意味着​:

  • 视频流损坏​:包含POC=2的那一帧(可能是一个I帧或P帧)在传输或存储过程中丢失或损坏了。

  • 解码器bug​:参考帧管理出现错误,提前将POC=2的帧从缓冲区中移除了。

四、它们如何协同工作​:

  1. 编码器决定一个GOP 结构(如IBBPBBP)。

  2. 在编码这个GOP时,I帧独立编码;P帧参考前面的帧;B帧参考前后帧。这导致编码顺序显示顺序不同。

  3. 编码器为每一帧分配一个唯一的POC 值,来标识其真正的显示顺序

  4. 这个GOP数据(包含帧数据和POC信息)被打包进码流。

  5. 解码器收到码流后,先按编码顺序 解码每一帧,然后根据POC 值将它们重新排序,得到正确的显示顺序并输出。

五、例子

RTSP视频流在OpenCV-Python中的完整处理流程,结合编码、传输、解码和显示的细节说明

1. 编码器侧 (HEVC编码)

输入顺序 ​:摄像头按时间顺序生成帧 F0, F1, F2, F3...

编码关键规则​:

  1. B帧需等待后续参考帧就绪才能编码

  2. 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 ✅ 概念通用
预测方向 ✅ 帧内/帧间预测 ✅ 帧内/帧间预测 ✅ 完全通用
相关推荐
lxmyzzs8 小时前
成功解决NVIDIA Jetson docker环境下Opencv+Gstreamer 无法对rtsp相机拉流问题
人工智能·数码相机·opencv
周杰伦_Jay18 小时前
【MCP开发部署流程表格分析】MCP架构解析、开发流程、部署方案、安全性分析
人工智能·深度学习·opencv·机器学习·架构·transformer
周杰伦_Jay21 小时前
【OpenManus深度解析】MetaGPT团队打造的开源AI智能体框架,打破Manus闭源壁垒。包括架构分层、关键技术特点等内容
人工智能·深度学习·opencv·架构·开源
渡我白衣1 天前
未来的 AI 操作系统(八)——灵知之门:当智能系统开始理解存在
人工智能·深度学习·opencv·机器学习·计算机视觉·语言模型·人机交互
蜉蝣之翼❉2 天前
检测十字标 opencv python
python·opencv·计算机视觉
AI technophile2 天前
OpenCV计算机视觉实战(27)——深度学习与卷积神经网络
深度学习·opencv·计算机视觉
heisd_12 天前
OpenCV计算机视觉库
人工智能·opencv·计算机视觉
Sunhen_Qiletian3 天前
基于OpenCV与Python的身份证号码识别案例详解
人工智能·opencv·计算机视觉
JANGHIGH3 天前
YOLO系列——Ubuntu20.04下通过conda虚拟环境源码安装opencv-4.10与opencv_contrib-4.10.0
opencv·yolo·conda