WeCodec 知识库 · 视频编码
CBR、VBR、CRF 各适合什么场景,怎么给码率封顶
码率控制决定每一帧分到多少比特。CBR 让码率保持恒定,适合带宽固定的推流。VBR 让码率跟着画面复杂度走。CRF 固定画质、不管体积,适合存档。
流媒体常用两遍编码或 CRF,再用 maxrate 和 bufsize 给码率封顶。
一段视频的复杂度一直在变。静止的访谈镜头用不了多少比特,快速运动的体育画面要多得多。码率控制就是编码器分配比特的策略,它决定文件大小,也决定画质在时间上怎么分布(FFmpeg Wiki:Encode/H.264)。
选哪种模式,先看用途。Werner Robitza 把常见需求分成三类,下表按他的建议整理(Understanding Rate Control Modes)。
| 用途 | 要求 | 推荐模式 |
|---|---|---|
| 存档 | 体积尽量小、画质尽量好,不在乎精确大小 | CRF |
| 点播 | 码率不能超过上限,或者要出几档固定码率 | 两遍编码,加 VBV 限制 |
| 直播 | 编码要快,事先不知道内容 | 单遍 CRF 加 VBV 限制,或 CBR |
表里的 VBV 是给码率封顶的机制,第 5 节再讲。
CBR(constant bitrate,恒定码率)让每秒输出的比特数基本不变。带宽因此可以精确预留,适合直播推流这类场景(Understanding Rate Control Modes)。
代价在图里很清楚。画面简单时,预算用不完,编码器只能塞填充数据凑够码率,浪费带宽。画面复杂时,预算又不够,画质就会下降。
x264 做严格 CBR 要打开 nal-hrd=cbr,输出也得用 MPEG-TS 封装,因为 MP4 不支持这种填充(同上)。
VBR(variable bitrate,可变码率)允许码率跟着画面走:简单处少给,复杂处多给。平均码率相同时,VBR 的画质比 CBR 更均匀。
难点在于编码器边编边分配,不知道后面的画面有多复杂。单遍的平均码率模式(ABR)只能边走边猜,码率波动大,片头尤其明显,Robitza 不建议使用(Understanding Rate Control Modes)。
两遍编码(two-pass)先完整分析一遍,记下每段的复杂度,第二遍再按目标码率分配比特。需要控制文件大小时,它是推荐做法之一(FFmpeg Wiki:Encode/H.264)。
CRF(constant rate factor,恒定质量因子)不设码率目标,只设画质目标。编码器自己决定每帧用多少比特,结果是画质稳定,文件大小事先不知道。
x264 的 CRF 取值 0 到 51,数值越小画质越好。默认 23,常用范围 17 到 28。8 bit 编码时,0 是无损,17 或 18 已经接近肉眼无损。CRF 每加 6,码率大约减半;每减 6,大约翻倍(FFmpeg Wiki:Encode/H.264)。
CRF 和固定 QP 不是一回事。固定 QP 让每帧用同样的量化强度,码率会随场景剧烈起伏,编码效率也低。Robitza 只建议在做编码研究时用固定 QP(Understanding Rate Control Modes)。
x265 的 CRF 默认 28,画质大致相当于 x264 的 CRF 23,文件约小一半(FFmpeg Wiki:Encode/H.265)。所以换编码器时,CRF 数值不能直接照搬。
流媒体想要 CRF 那样按需分配,又不能让码率突然冲高、超过用户带宽。办法是加 VBV 约束。VBV(video buffering verifier,视频缓冲校验器)在编码器里模拟播放端的缓冲区,保证一段时间内发出的比特不超过约定的上限(Understanding Rate Control Modes)。
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)。