3. 码率控制核心参数:Bitrate、FrameRate、GopSize、Profile/Level 对码率的影响
各位做 Camera 的朋友,咱们今天聊点实在的。码率控制这事儿,说复杂也复杂,说简单也简单。你想想看,编码器就是个压缩器,它得在画质和文件大小之间找个平衡。而这个平衡,全靠几个核心参数来调。
我个人习惯,拿到一个新平台,第一件事就是把这几个参数摸透。它们就像乐器的旋钮,拧对了,声音好听;拧错了,全是噪音。
3.1 Bitrate(码率):最直接的带宽控制
Bitrate 说白了就是每秒给编码器多少比特的预算。预算多,画质好;预算少,画质差。就这么简单。
但在高通平台上,Bitrate 的设置有几个坑要注意:
- 固定码率(CBR):码率恒定,适合直播、视频通话。缺点是场景切换时画质波动大。
- 可变码率(VBR):码率浮动,适合本地录制。静态场景省码率,动态场景多分配。
- 平均码率(ABR):介于两者之间,我项目中用得最多。
关键点:高通平台的 VBR 实现和标准 H.264 不太一样。它内部有个“码率池”机制,允许短时间内的码率突发。我曾经在调试 4K60 录像时,发现码率峰值冲到 200Mbps,结果 ISP 带宽被打爆。后来加了 peak_bitrate 限制才解决。
设置示例:
// 高通平台 QCamera 码率配置示例
cam_stream_parm_buffer_t streamParm;
streamParm.bitrate = 20 * 1000 * 1000; // 20 Mbps
streamParm.peak_bitrate = 25 * 1000 * 1000; // 峰值 25 Mbps
streamParm.rate_control = RATE_CONTROL_CBR; // 固定码率模式
3.2 FrameRate(帧率):码率的隐形杀手
帧率对码率的影响,很多人会忽略。你想想看,30fps 和 60fps,每秒要多编码一倍的帧。码率不变的情况下,每帧能分到的比特数直接减半。
我遇到过最典型的案例:客户要求 4K 60fps 录像,码率只给 20Mbps。结果画面全是马赛克,尤其是运动场景。为什么?因为每帧只有 0.33Mbps 的预算,根本不够用。
| 帧率 | 码率(Mbps) | 每帧预算(Kb) | 画质表现 |
|---|---|---|---|
| 30fps | 20 | 666 | 良好 |
| 60fps | 20 | 333 | 较差 |
| 60fps | 40 | 666 | 良好 |
经验之谈:帧率翻倍,码率建议至少增加 50%-70%。别想着省码率,画质崩了用户第一个骂你。
3.3 GopSize(关键帧间隔):影响码率分布的节奏
GopSize 决定了两个 I 帧之间的帧数。I 帧是完整帧,占的码率最大;P/B 帧是预测帧,占的码率小。
GopSize 越小,I 帧越频繁,码率波动越大。GopSize 越大,码率越平稳,但 seek 响应慢。
- GopSize = 1:全 I 帧,码率爆炸,画质最好。适合截图场景。
- GopSize = 30:每秒一个 I 帧(30fps 下),常见于直播。
- GopSize = 60-120:2-4 秒一个 I 帧,适合本地录像。
我记得有一次调试行车记录仪,客户要求 GopSize 设成 300(10 秒一个 I 帧)。结果回放时 seek 到某帧要等好几秒,用户体验极差。后来我建议改成 60,码率只增加了 8%,但 seek 速度快了 5 倍。
3.4 Profile/Level:编码能力的上限
Profile 和 Level 决定了编码器能用哪些工具。工具越多,压缩效率越高,码率越低。
| Profile | 支持特性 | 码率节省 |
|---|---|---|
| Baseline | I/P 帧,无 B 帧 | 基准 |
| Main | I/P/B 帧,CABAC | 比 Baseline 省 10-15% |
| High | 8x8 DCT,量化矩阵 | 比 Main 再省 5-10% |
注意:高通平台有些老芯片(如 SDM660)的 High Profile 实现有 bug,开启 8x8 DCT 后会出现色块。我踩过这个坑,后来强制降级到 Main Profile 才解决。
Level 则限制了分辨率、帧率、码率的上限。比如 Level 4.0 最高支持 1080p 30fps,Level 5.0 才能跑 4K 60fps。
3.5 参数间的联动关系
这几个参数不是孤立的。它们互相影响,牵一发而动全身。
举个例子:你设了 20Mbps 的码率,60fps 的帧率,GopSize=60,High Profile。实际编码时,I 帧可能吃掉 2-3Mbps,剩下的 17-18Mbps 分给 59 个 P/B 帧。每帧平均只有 300Kb 左右。如果场景复杂,画质必然崩。
我的建议:先定 Profile/Level,再定帧率,然后根据分辨率算码率,最后调 GopSize 优化 seek 体验。这个顺序别搞反了。
3.6 实战中的参数调优策略
不同场景,参数组合完全不同。我整理了一份常用配置表:
| 场景 | 分辨率 | 帧率 | 码率 | GopSize | Profile |
|---|---|---|---|---|---|
| 视频通话 | 720p | 30 | 1.5-2 Mbps | 30 | Baseline |
| 直播推流 | 1080p | 30 | 4-6 Mbps | 30 | Main |
| 本地录像 | 4K | 30 | 40-60 Mbps | 60 | High |
| 慢动作 | 1080p | 240 | 80-120 Mbps | 240 | High |
避坑指南:我曾经在调试 1080p 240fps 慢动作时,按常规算法算码率,结果编码器直接报错。后来发现是高通平台的 Level 限制——Level 5.1 最大码率只有 240Mbps,而 240fps 的瞬时码率很容易超限。最后加了 level=51 的强制约束才搞定。
嗯,这几个参数说完了。你可能会问,这么多参数,怎么快速找到最优组合?我的做法是:先用默认参数跑一遍,看码率曲线和 PSNR。然后逐个调参,每次只改一个变量,记录效果。别想着一步到位,编码调优是个迭代过程。