4. 编码器性能分析:软件编码 vs 硬件编码、编码预设对CPU/GPU的消耗
推流卡顿,很多时候不是网络不行,而是编码器扛不住了。
我见过不少团队,上来就开 ultrafast 预设,结果画面糊成一团;也有人迷信硬件编码,结果在低码率场景下频繁跳帧。说白了,编码器的选择,本质上是在算力、画质、延迟之间做权衡。这一章,我们就来拆解软件编码和硬件编码的差异,以及编码预设到底怎么影响 CPU/GPU 的消耗。
4.1 软件编码 vs 硬件编码:核心差异
先看一张对比表,把两者的底牌亮出来。
| 对比维度 | 软件编码(如 x264、x265) | 硬件编码(如 NVENC、QSV、AMF) |
|---|---|---|
| 计算载体 | CPU 通用核心 | GPU 专用编码单元 |
| 画质(同码率) | 更高(算法更灵活) | 稍低(固定流水线) |
| 延迟 | 可控,但受 CPU 负载影响 | 极低,通常 < 1ms 编码延迟 |
| CPU 占用 | 高(可占满多核) | 低(仅驱动开销) |
| 多路并发 | 受限于核心数 | 强(单卡可编 8~16 路) |
| 典型场景 | 点播转码、高画质直播 | 低延迟直播、游戏推流 |
我个人习惯,在推流场景下优先考虑硬件编码。为什么?因为推流对延迟敏感,CPU 还要同时处理采集、滤镜、封装、发送,如果编码再吃掉大量 CPU 时间,很容易出现编码队列堆积,最终表现为推流卡顿。
核心结论: 硬件编码用空间换时间,软件编码用时间换空间。推流场景下,延迟是第一优先级,硬件编码通常是更稳妥的选择。
4.2 编码预设:从 ultrafast 到 placebo
编码预设,说白了就是告诉编码器:「你愿意花多少力气去压缩画面?」
预设越慢,压缩率越高,画质越好,但 CPU 消耗也越大。以 x264 为例,预设从快到慢依次是:
- ultrafast / superfast / veryfast —— 适合实时推流,CPU 占用低,但码率浪费严重
- faster / fast / medium —— 平衡点,medium 是 x264 默认值
- slow / slower / veryslow —— 适合离线转码,画质好但延迟高
- placebo —— 几乎不用,收益极低,消耗极高
我在项目中遇到过一个问题:某直播平台用 veryfast 预设推 1080p@60fps,服务器端 CPU 直接飙到 90% 以上,导致编码队列溢出,画面每隔几秒就卡一下。后来改成 medium 预设,CPU 降到 60%,卡顿消失。你想想看,有时候不是预设越慢越好,而是要在你的硬件能力范围内找到那个「刚刚好」的点。
我的经验: 推流场景下,建议从 veryfast 起步,如果 CPU 有余量,再尝试 faster 或 medium。不要一上来就 ultrafast,那个预设下画质损失太大,观众一眼就能看出马赛克。
4.3 CPU/GPU 消耗实测对比
下面这张图,是我在实际测试中记录的数据。测试环境:i7-12700 + RTX 3060,推流 1080p@30fps,码率 4Mbps。
从图上可以清楚看到:软件编码下,从 ultrafast 到 slow,CPU 占用从 35% 飙升到 85%,几乎翻了三倍。而硬件编码呢?从最快预设到最慢预设,GPU 占用只从 18% 涨到 28%。
为什么会这样?因为硬件编码的算法是固化在芯片里的,预设调整的只是量化参数和运动搜索范围,不会像软件编码那样大幅改变计算量。
4.4 如何选择:场景化决策指南
嗯,这里要注意,没有万能的编码方案。我一般会按以下逻辑来选:
- 单路推流,CPU 充裕 → 用软件编码,预设选
veryfast或faster,画质更好 - 多路推流,或 CPU 紧张 → 用硬件编码,预设选默认(p4),GPU 占用低,延迟稳定
- 低码率场景(< 2Mbps) → 优先软件编码,硬件编码在低码率下画质衰减明显
- 高帧率场景(60fps+) → 硬件编码更稳,软件编码容易丢帧
避坑指南: 我曾经在推流 4K 内容时,想当然地用了软件编码的 slow 预设,结果 CPU 直接 100%,编码队列积压了 2 秒,观众端看到的画面延迟越来越大。后来换成 NVENC 的 p4 预设,CPU 降到 8%,延迟恢复到 500ms 以内。记住:推流不是离线转码,延迟和稳定性比极致画质更重要。
4.5 FFmpeg 命令行实战
最后,给几个可以直接用的命令。我平时调试编码器性能,就用这些模板:
软件编码推流(veryfast 预设):
ffmpeg -i input.mp4 -c:v libx264 -preset veryfast -b:v 4M -maxrate 4M -bufsize 8M \
-c:a aac -b:a 128k -f flv rtmp://your-server/live/stream
硬件编码推流(NVENC,默认预设):
ffmpeg -i input.mp4 -c:v h264_nvenc -preset p4 -b:v 4M -maxrate 4M -bufsize 8M \
-c:a aac -b:a 128k -f flv rtmp://your-server/live/stream
查看编码器支持的预设列表:
ffmpeg -h encoder=h264_nvenc | grep "preset"
小技巧: 如果你不确定当前硬件能扛住哪个预设,可以加 -stats_period 1 参数,每秒输出一次编码统计,观察 CPU 占用和编码帧率是否稳定。如果编码帧率低于输入帧率,说明预设太快了,需要降一档。