3. 码率控制模式对比:CBR、VBR、CQ
码率控制模式决定了编码器如何在时间和空间上分配比特预算,直接影响视频的码率稳定性、图像质量与编码效率。Android MediaCodec 支持三种主流模式:CBR(恒定比特率)、VBR(可变比特率)和CQ(恒定质量)。本章通过参数测试方法,辨析三者的原理与适用边界,并提供可复现的测试脚本与调参策略。
3.1 参数含义与核心原理
| 模式 | 全称 | 核心原理 | 码率波动特征 |
|---|---|---|---|
| CBR | Constant Bit Rate | 强制输出码率稳定在设定值附近,通过填充比特(padding)或降低质量来满足约束。 | 几乎平坦,波动 ≤ ±5% |
| VBR | Variable Bit Rate | 允许码率在预设范围内浮动,复杂场景分配更多比特,简单场景节省比特。 | 大幅波动,峰值可达平均值的 2~3 倍 |
| CQ | Constant Quality | 固定量化参数(QP),不直接限制码率,质量稳定但输出码率完全由场景复杂度决定。 | 完全不可控,波动范围最大 |
关键区别:CBR 是比特率优先,质量可以牺牲;CQ 是质量优先,比特率可以无限;VBR 则是两者的折中方案。
3.2 测试条件与仪器/工具配置
为保证对比测试的公平性,所有模式使用同一段 30 秒 1080p 测试源(包含静态、快速运动、黑白场景切换),编码器统一使用 OMX.google.h264.encoder 或硬件编码器 OMX.qcom.video.encoder.avc。
| 测试项目 | CBR 组 | VBR 组 | CQ 组 |
|---|---|---|---|
| 目标码率 | 2 Mbps | 2 Mbps(平均) | 不设置 |
| 最大码率 | 2 Mbps | 4 Mbps | 不限制 |
| 帧率 | 30 fps | 30 fps | 30 fps |
| 关键帧间隔 | 2 秒 | 2 秒 | 2 秒 |
| 分析工具 | MediaCodec Stat 日志 + Elecard StreamEye / ffprobe bitrate 分析 | ||
3.3 MediaCodec 配置代码片段
// 创建 MediaFormat 并设置通用参数
MediaFormat format = MediaFormat.createVideoFormat(MIMETYPE_VIDEO_AVC, width, height);
format.setInteger(MediaFormat.KEY_BIT_RATE, 2000000); // 2 Mbps
format.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 2); // 2 秒
// 设置码率控制模式(关键步骤)
// CBR 模式
format.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR);
// VBR 模式(需同时设置最大码率)
// format.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR);
// format.setInteger(MediaFormat.KEY_MAX_BIT_RATE, 4000000); // 4 Mbps
// CQ 模式
// format.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ);
MediaCodec codec = MediaCodec.createEncoderByType(MIMETYPE_VIDEO_AVC);
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
兼容性提示:部分低端设备可能不支持
BITRATE_MODE_CQ。配置前请先通过 MediaCodecInfo.getCapabilitiesForType() 查询支持的码率控制模式集合。
3.4 测量步骤
- 准备测试源:将 30 秒 1080p 测试视频 push 到设备
/sdcard/test_source.mp4。 - 执行编码脚本:分别使用 CBR、VBR、CQ 配置运行编码测试,输出为
output_cbr.h264、output_vbr.h264、output_cq.h264。 - 提取码率日志:在编码循环中,每 100 帧打印一次
outputBufferInfo.presentationTimeUs和 buffer 大小,计算瞬时码率。 - 质量评估:使用 ffprobe 输出帧级码率曲线,同时用 SSIM/PSNR 计算工具对比源视频与解码后的质量。
3.5 数据判断与期望值
| 模式 | 瞬时码率波动范围 | 平均码率偏差 | PSNR 波动 |
|---|---|---|---|
| CBR | 1.9 ~ 2.1 Mbps | ±5% | 3~6 dB |
| VBR | 0.5 ~ 4.0 Mbps | ±5%(若配置合理) | 2~4 dB |
| CQ | 0.2 ~ 10.0 Mbps | 完全不可控 | ≤ 2 dB |
3.6 误差分析
- CBR 误差来源:填充比特导致缓冲延迟;当场景超出编码器处理能力时,PSNR 急剧恶化。
- VBR 误差来源:码率峰值超限可能导致缓冲或解码器不兼容;低码率段容易产生块效应。
- CQ 误差来源:输出码率不可预估,不适用于网络传输;部分硬件编码器对固定 QP 支持不完善,实际输出 QP 与设定值有偏差。
3.7 调参策略
选型建议:
- 直播/实时通信 → CBR:保证码率稳定,避免网络拥塞。适当降低目标码率留出缓冲余量。
- 本地录制/点播 → VBR:在文件大小与质量之间取得最佳平衡,建议最大码率设为平均码率的 1.5~2 倍。
- 离线转码/存档 → CQ:追求最高保真度,根据内容复杂度选择 QP 值(通常 18~28)。
精细调优参数:
KEY_MAX_BIT_RATE:仅 VBR 需要,设为平均码率的 200% 可应对大多数高动态场景。KEY_QUALITY:部分编码器在 CQ 模式中使用 0~100 的 scale,具体范围需参考设备驱动。KEY_BITRATE_MODE与KEY_BIT_RATE必须在configure()前设置完成。
3.8 验收阈值
| 验收指标 | CBR | VBR | CQ |
|---|---|---|---|
| 码率偏差 | ≤ ±10% | ≤ ±10%(平均) | 不适用 |
| 码率峰值/平均值 | ≤ 1.2 | ≤ 2.5 | 不适用 |
| PSNR 最小值 | ≥ 35 dB | ≥ 37 dB | ≥ 40 dB |
| 帧率稳定性 | 100% 帧命中目标帧率 | ≥ 98% | ≥ 95% |
测试建议:验收时使用至少 3 种不同复杂度的测试源(静态、运动、混合),每种源运行 5 次取均值,消除单次波动影响。日志中记录每次编码的
outputBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG 是否为 0,确保配置帧正确传递。