视频传输基础概念;帧内压缩 vs 帧间压缩
视频传输基础概念
三层核心概念
视频从摄像头到最终被处理,涉及三个相互独立、可以自由组合的层面:
| 层面 | 解决的问题 | 常见例子 |
|---|---|---|
| 编码格式(Codec) | 画面本身怎么被压缩 | H.264、H.265、MJPEG、VP9 |
| 封装/容器格式(Container) | 压缩后的数据怎么打包组织 | MP4、FLV、TS |
| 传输协议(Protocol) | 打包好的数据怎么在网络上传输 | RTSP、RTMP、HTTP、HLS |
这三层互不依赖,理解视频流问题时要先分清楚"卡"在哪一层。
编码格式(Codec)
MJPEG(Motion JPEG)
- 本质是连续的独立 JPEG 图片,每一帧自己包含完整图像信息
- 解码简单:每帧独立解码,不需要参考前后帧
- 仍然需要解码(JPEG解码),只是没有帧间压缩那么复杂
- 压缩率低,同画质下数据量大,但延迟低、CPU开销小
- 基本不需要容器封装(每帧本身就是完整单元)
H.264 / H.265
- 有帧内压缩(类似JPEG)+ 帧间压缩(P帧/B帧参考前面的I帧)
- 压缩率高,数据量比MJPEG小很多
- 解码更复杂:要维护 GOP(Group of Pictures)帧间依赖关系
- 编码/解码需要更多算力,Jetson等设备上建议用硬件编解码器(如
nvv4l2enc)而非纯软件编解码
编码 ≠ 必须要容器
H.264 压缩完的裸码流(Annex B / raw H.264)本身可以直接通过 RTP 这类协议打包传输,
不一定非要塞进 FLV / MP4 这种完整容器。只有 RTMP(固定要求FLV)或存文件(常用MP4)时才必须走完整容器。
封装/容器格式(Container)
容器负责把编码后的视频数据 + 音频 + 时间戳等元信息打包在一起,方便播放器识别和播放。
| 容器 | 常配合的编码 | 常见场景 |
|---|---|---|
| FLV | H.264 | RTMP直播 |
| MP4 | H.264/H.265 | 存文件、点播 |
| TS | H.264 | HLS切片 |
| 裸流(无容器) | H.264(RTP打包)、MJPEG | RTSP、HTTP MJPEG |
传输协议(Protocol)
| 协议 | 底层容器 | 常用编码 | 延迟 | 特点 |
|---|---|---|---|---|
| RTSP | 裸流(RTP打包) | H.264/H.265 | 低 | 监控摄像头标配,支持TCP/UDP |
| RTMP | FLV | H.264 | 中 | 曾是直播标配,渐被淘汰 |
| HTTP-FLV | FLV | H.264 | 较低 | 基于HTTP传输FLV |
| HLS | TS切片 | H.264 | 高(几秒~十几秒) | 穿透性好,适合大规模分发,不适合实时场景 |
| HTTP MJPEG | 无容器 | MJPEG | 极低 | 浏览器<img>标签原生支持,带宽消耗大 |
选择逻辑
- 只是自己的服务内部拉流、局域网内、追求最低延迟 → HTTP MJPEG 最简单直接
- 需要多路复用/多个客户端同时看同一路流 → RTSP/RTMP + 流媒体转发服务器(如 mediamtx)
- 大规模分发给很多终端看 → HLS,但不适合需要低延迟的实时检测场景
完整链路示意(USB摄像头 → 远程YOLO推理)
USB摄像头
↓ (本地设备读取,无网络概念)
采集端 ffmpeg/mjpg-streamer 推流
↓ (编码:H.264 或 MJPEG)
↓ (可选容器:FLV/裸流)
↓ (协议:RTSP/RTMP/HTTP)
网络传输
↓
推理服务端 拉流
↓ (FFmpeg 解协议 + 解容器 + 解码)
得到逐帧 numpy array
↓
YOLO 推理(纯计算,不涉及编解码)
每一层(编码/容器/协议)的选择,影响的是延迟、带宽占用、CPU开销,不影响 YOLO 最终能不能拿到画面进行推理——只要 FFmpeg 能成功解出画面,YOLO 就能处理。
帧内压缩 vs 帧间压缩
帧内压缩(MJPEG、H.264的I帧)
- 只用这一帧自己的信息压缩(类似JPEG),利用画面内部像素相似性
- 每帧独立,不依赖其他帧
- 优点:解码简单、延迟低;缺点:压缩率低
帧间压缩(H.264的P帧/B帧)
- 利用帧与帧之间的相似性(大部分画面没变)
- 靠运动矢量:不存整帧像素,只存"这块内容相对参考帧挪了多少"+ 少量差异
- 无人机平稳移动:位移规律,运动矢量好找,压缩率依然高
- 剧烈抖动/不规则运动:矢量难匹配,压缩率下降
参考帧不是重新传输的
- 编码端、解码端各自本地都保留一份完整的上一帧(解码端存缓冲区;编码端内部也自解一份,保证两边一致)
- 传输时只传"差异",双方各自拼出来的都是完整画面,只是传的数据量小
- 类比:两人手里都有同一页内容,更新只需说"第3行改成xx",不用整页重念
I/P/B帧
| 类型 | 依赖 |
|---|---|
| I帧 | 独立,不依赖别的帧 |
| P帧 | 依赖前面的帧 |
| B帧 | 依赖前后的帧,压缩率最高但延迟大 |
I帧丢了会导致后面P帧全错 → 定期插入新I帧防止错误累积。
浙公网安备 33010602011771号