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。

编码预设 vs CPU/GPU 消耗对比 软件编码 (x264) ultrafast 35% veryfast 48% medium 65% slow 85% 硬件编码 (NVENC) p1 (最快) 18% p4 (默认) 22% p7 (最慢) 28% 说明:软件编码 CPU 占用随预设变慢急剧上升;硬件编码 GPU 占用变化平缓 硬件编码下 CPU 占用通常 < 10%,适合推流场景 软件编码 CPU 消耗 随预设指数增长 硬件编码 GPU 消耗 变化幅度很小

从图上可以清楚看到:软件编码下,从 ultrafast 到 slow,CPU 占用从 35% 飙升到 85%,几乎翻了三倍。而硬件编码呢?从最快预设到最慢预设,GPU 占用只从 18% 涨到 28%。

为什么会这样?因为硬件编码的算法是固化在芯片里的,预设调整的只是量化参数和运动搜索范围,不会像软件编码那样大幅改变计算量。

4.4 如何选择:场景化决策指南

嗯,这里要注意,没有万能的编码方案。我一般会按以下逻辑来选:

  1. 单路推流,CPU 充裕 → 用软件编码,预设选 veryfast 或 faster,画质更好
  2. 多路推流,或 CPU 紧张 → 用硬件编码,预设选默认(p4),GPU 占用低,延迟稳定
  3. 低码率场景(< 2Mbps) → 优先软件编码,硬件编码在低码率下画质衰减明显
  4. 高帧率场景(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 占用和编码帧率是否稳定。如果编码帧率低于输入帧率,说明预设太快了,需要降一档。