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 则是两者的折中方案。
码率控制模式原理对比 时间 → CBR 目标码率 VBR CQ 码率大幅波动 码率稳定 质量恒定

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 测量步骤

  1. 准备测试源:将 30 秒 1080p 测试视频 push 到设备 /sdcard/test_source.mp4。
  2. 执行编码脚本:分别使用 CBR、VBR、CQ 配置运行编码测试,输出为 output_cbr.h264、output_vbr.h264、output_cq.h264。
  3. 提取码率日志:在编码循环中,每 100 帧打印一次 outputBufferInfo.presentationTimeUs 和 buffer 大小,计算瞬时码率。
  4. 质量评估:使用 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,确保配置帧正确传递。