← 首页

WeCodec 知识库 · 视频编码

码率控制:CBR、VBR、CRF

CBR、VBR、CRF 各适合什么场景,怎么给码率封顶

码率控制决定每一帧分到多少比特。CBR 让码率保持恒定,适合带宽固定的推流。VBR 让码率跟着画面复杂度走。CRF 固定画质、不管体积,适合存档。

流媒体常用两遍编码或 CRF,再用 maxrate 和 bufsize 给码率封顶。

1. 码率控制管什么

一段视频的复杂度一直在变。静止的访谈镜头用不了多少比特,快速运动的体育画面要多得多。码率控制就是编码器分配比特的策略,它决定文件大小,也决定画质在时间上怎么分布(FFmpeg Wiki:Encode/H.264)。

选哪种模式,先看用途。Werner Robitza 把常见需求分成三类,下表按他的建议整理(Understanding Rate Control Modes)。

用途要求推荐模式
存档体积尽量小、画质尽量好,不在乎精确大小CRF
点播码率不能超过上限,或者要出几档固定码率两遍编码,加 VBV 限制
直播编码要快,事先不知道内容单遍 CRF 加 VBV 限制,或 CBR

表里的 VBV 是给码率封顶的机制,第 5 节再讲。

2. CBR:码率恒定

CBR(constant bitrate,恒定码率)让每秒输出的比特数基本不变。带宽因此可以精确预留,适合直播推流这类场景(Understanding Rate Control Modes)。

01234015304560时间(秒)Mbps比特不够填充浪费CBR 码率画面实际需要
图 1 CBR 和画面实际需要的码率示意。需要量曲线是虚构数据。

代价在图里很清楚。画面简单时,预算用不完,编码器只能塞填充数据凑够码率,浪费带宽。画面复杂时,预算又不够,画质就会下降。

x264 做严格 CBR 要打开 nal-hrd=cbr,输出也得用 MPEG-TS 封装,因为 MP4 不支持这种填充(同上)。

3. VBR 和两遍编码

VBR(variable bitrate,可变码率)允许码率跟着画面走:简单处少给,复杂处多给。平均码率相同时,VBR 的画质比 CBR 更均匀。

01234015304560时间(秒)Mbps两条线的平均码率相同CBRVBR
图 2 平均码率相同的 CBR 和 VBR 示意。

难点在于编码器边编边分配,不知道后面的画面有多复杂。单遍的平均码率模式(ABR)只能边走边猜,码率波动大,片头尤其明显,Robitza 不建议使用(Understanding Rate Control Modes)。

两遍编码(two-pass)先完整分析一遍,记下每段的复杂度,第二遍再按目标码率分配比特。需要控制文件大小时,它是推荐做法之一(FFmpeg Wiki:Encode/H.264)。

4. CRF:固定画质

CRF(constant rate factor,恒定质量因子)不设码率目标,只设画质目标。编码器自己决定每帧用多少比特,结果是画质稳定,文件大小事先不知道。

x264 的 CRF 取值 0 到 51,数值越小画质越好。默认 23,常用范围 17 到 28。8 bit 编码时,0 是无损,17 或 18 已经接近肉眼无损。CRF 每加 6,码率大约减半;每减 6,大约翻倍(FFmpeg Wiki:Encode/H.264)。

×4CRF 11×2CRF 17×1CRF 23×0.5CRF 29×0.25CRF 35以 x264 默认值 CRF 23 的码率为 1
图 3 按 CRF 每差 6 码率约差一倍的规律画的示意,实际比例随内容变化。

CRF 和固定 QP 不是一回事。固定 QP 让每帧用同样的量化强度,码率会随场景剧烈起伏,编码效率也低。Robitza 只建议在做编码研究时用固定 QP(Understanding Rate Control Modes)。

x265 的 CRF 默认 28,画质大致相当于 x264 的 CRF 23,文件约小一半(FFmpeg Wiki:Encode/H.265)。所以换编码器时,CRF 数值不能直接照搬。

5. 给码率封顶:maxrate 和 bufsize

流媒体想要 CRF 那样按需分配,又不能让码率突然冲高、超过用户带宽。办法是加 VBV 约束。VBV(video buffering verifier,视频缓冲校验器)在编码器里模拟播放端的缓冲区,保证一段时间内发出的比特不超过约定的上限(Understanding Rate Control Modes)。

01234015304560时间(秒)Mbpsmaxrate = 2.5 Mbps只用 CRFCRF 加 maxrate 封顶
图 4 CRF 加 maxrate 封顶前后的码率示意。

FFmpeg 用 -maxrate 设上限,-bufsize 设缓冲区大小,maxrate 必须和 bufsize 一起用(FFmpeg Codecs Documentation)。bufsize 决定码率能波动多大:设得越小,编码器检查得越勤,码率越平稳,但太小会伤画质(FFmpeg Wiki:Limiting the output bitrate)。

Robitza 建议 bufsize 先取 maxrate 的两倍。例如 -crf 23 -maxrate 1M -bufsize 2M。如果码率总是顶到上限,说明 CRF 设得太低,编码器在抢它没有的比特(Understanding Rate Control Modes)。

参考资料

  1. 《Understanding Rate Control Modes (x264, x265, vpx)》,Werner Robitza https://slhck.info/video/2017/03/01/rate-control.html
  2. 《Encode/H.264》,FFmpeg Wiki https://trac.ffmpeg.org/wiki/Encode/H.264
  3. 《Encode/H.265》,FFmpeg Wiki https://trac.ffmpeg.org/wiki/Encode/H.265
  4. 《Limiting the output bitrate》,FFmpeg Wiki https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate
  5. 《FFmpeg Codecs Documentation》,FFmpeg https://ffmpeg.org/ffmpeg-codecs.html