3. 推流技术全景
做流媒体这行,视频编码是绕不开的坎。我记得刚入行那会儿,总觉得编码是算法工程师的事,我们做传输的懂个大概就行。结果第一次调试RTSP推流卡顿,抓包抓了半天,最后发现是编码器配置的GOP太大,客户端等了快两秒才等到I帧。从那以后,我老老实实把编码基础补了一遍。
说白了,视频编码的核心就两件事:去掉冗余和控制码率。冗余包括空间上的(同一帧里相邻像素长得像)和时间上的(相邻帧之间画面变化不大)。去掉这些冗余,视频就能压缩到原来的几十分之一甚至百分之一。
3.1 视频编码原理概述
先看一张整体流程图,帮你建立直觉:
编码器拿到原始帧后,先做预测。预测分两种:帧内预测用当前帧已编码的像素推测当前块,帧间预测用前面或后面的帧做参考。预测完得到残差(实际值减预测值),残差里大部分数值接近0。然后做变换(比如DCT)把残差转到频域,再用量化去掉人眼不敏感的高频分量。最后熵编码把量化后的系数压缩成二进制码流。
3.2 帧类型:I/P/B帧
视频编码不是一帧一帧独立压缩的。那样效率太低。编码器把帧分成三种类型,各司其职。
| 帧类型 | 全称 | 压缩方式 | 大小 | 关键特性 |
|---|---|---|---|---|
| I帧 | Intra-coded frame | 仅帧内预测 | 最大 | 可独立解码,无需参考其他帧 |
| P帧 | Predictive-coded frame | 参考前面的I/P帧 | 中等 | 只能向前参考,压缩率比I帧高 |
| B帧 | Bi-directional frame | 参考前后I/P帧 | 最小 | 双向参考,压缩率最高,但需要缓存 |
I帧是"关键帧",相当于视频里的"锚点"。你拖动进度条时,播放器必须找到最近的I帧才能开始解码。所以I帧不能太少,否则seek响应慢;也不能太多,否则码率飙升。
P帧只参考前面的帧。比如第5帧是P帧,它可能只记录"第3帧的左上角那块往右移了3个像素"。B帧更聪明,它同时参考前面和后面的帧,能更精确地描述运动。但B帧需要缓存后面的帧才能解码,所以会增加延迟。
RTSP推流场景下的选择:
- 低延迟场景(如视频通话):只用I帧+P帧,不用B帧。B帧的重排序会引入至少1帧的延迟。
- 直播场景(如赛事转播):可以用少量B帧,但B帧数量控制在2以内,避免解码器缓冲区溢出。
- 点播场景:B帧可以多用,压缩率优先,延迟不是问题。
我曾经在一个RTSP安防项目中踩过坑。摄像头编码器默认开了3个B帧,结果客户端解码时频繁花屏。查了半天,发现是部分低端NVR的B帧缓存不够。后来强制改成0个B帧,问题解决。嗯,兼容性有时候比压缩率更重要。
3.3 GOP结构与码率控制
GOP(Group of Pictures)就是一组连续的帧,从I帧开始到下一个I帧之前结束。GOP结构决定了视频的随机访问能力和压缩效率。
常见的GOP结构有两种:
- 封闭式GOP:GOP内的帧只参考本GOP内的帧,不跨GOP参考。适合视频编辑场景,剪切时不会出现参考帧缺失。
- 开放式GOP:B帧可以跨GOP参考后面的I帧。压缩率更高,但编辑时可能出问题。
GOP长度(两个I帧之间的帧数)是个关键参数。我一般这样配置:
| 场景 | 推荐GOP长度 | 理由 |
|---|---|---|
| 实时监控 | 30-60帧(1-2秒) | 快速seek,丢包后快速恢复 |
| 直播推流 | 60-120帧(2-4秒) | 平衡压缩率和延迟 |
| 短视频/点播 | 120-250帧(4-10秒) | 追求高压缩率 |
码率控制是编码器的"油门"。它决定每一帧分配多少比特。常见模式有三种:
- CBR(恒定码率):码率始终保持在目标值附近。适合带宽固定的场景,比如RTSP over TCP。缺点是画面复杂时质量会下降。
- VBR(可变码率):码率随画面复杂度波动。简单场景用低码率,复杂场景用高码率。画质更稳定,但带宽需求会波动。
- CRF(恒定质量):固定量化参数,码率完全由画面决定。画质最好,但码率不可控。适合本地录制,不适合网络推流。
RTSP推流我推荐用CBR或VBR带最大码率限制。为什么?因为RTSP的传输层通常是TCP,带宽波动时TCP会重传,导致延迟堆积。如果码率忽高忽低,TCP的拥塞控制会频繁触发,画面反而更卡。
最后说一个容易被忽略的点:GOP和码率控制的联动。I帧的码率通常是P帧的5-10倍,B帧的15-20倍。如果码率控制没处理好,I帧瞬间的码率尖峰可能撑爆缓冲区。我见过有人把I帧的量化参数设得比P帧低很多,结果I帧码率爆炸,网络瞬间丢包。正确的做法是让码率控制器提前为I帧预留比特,或者适当提高I帧的QP,让它不要过于"突出"。
嗯,编码基础就聊到这儿。这些概念看起来简单,但实际调优时坑不少。后面我们会结合具体的编码器(x264、x265、NVIDIA NVENC)讲实战配置,到时候你会更清楚每个参数在RTSP推流中的真实表现。