1. 参考
[1] Werner Robitza/Understanding Rate Control Modes (x264, x265, vpx)
[2] Werner Robitza/CRF Guide (Constant Rate Factor in x264, x265 and libvpx)
编码器中有一个码率控制模块,通过选择一系列编码参数,来控制编码视频的码率满足需要,并且使编码失真尽可能小。码率控制严格上不属于视频编码标准,属于率失真优化。
码率控制的几种模式[1]:
恒定QP(Quantization Parameter)。
- ffmpeg -s 1280x720 -i <input> -c:v libx264 -qp 23 <output>
- ffmpeg -s 1280x720 -i <input> -c:v libx265 -x265-params qp=23 <output>
不推荐使用这个模式,除非你明确知道这个模式的原理而有特定的用途。
4. CRF(Constant Rate Factor)/CQF(Constant Quality Factor) 恒定质量因子。
与恒定QP类似,但追求主观感知到的质量恒定,瞬时码率也会随场景复杂度波动。
对于快速运动或细节丰富的场景会适当增大量化失真(因为人眼不敏感),反之对于静止或平坦区域则减少量化失真。
CRF是x264和x265的默认码率控制方式,也可用于libvpx。
CRF值越大视频压缩率越高,但视频质量越低,各codec的CRF取值范围、默认值和建议值见下表。

ffmpeg -i input.mp4 -c:v libx264 -crf 23 output.mp4
如果你不确定要使用什么CRF,从默认值开始,并根据对输出的主观印象进行更改。如果质量没有足够好则较低的CRF。如果文件太大了则选择更高的CRF。更改±6会导致码率大小的一半/两倍左右的变化,±1会导致码率10%左右的变化。[2]
【CSDN文末扫码进君羊,免费分享】资料包括《Andoird音视频开发必备手册+音视频学习视频+学习文档资料包+大厂面试真题+2022最新学习路线图》等等

5. ABR(Average Bitrate) 指定平均码率。
使用FFmpeg指定ABR的示例如下所示。
- ffmpeg -s 1280x720 -i <input> -c:v libx264 -b:v 1M <output>
- ffmpeg -s 1280x720 -i <input> -c:v libx265 -b:v 1M <output>
- ffmpeg -s 1280x720 -i <input> -c:v libvpx-vp9 -b:v 1M <output>
避免使用这种模式, x264的一位主要开发者说你应该永远不要使用它,由于编码器无法提前知道要编码视频的情况,它将不得不猜测如何达到比特率。
2-Pass ABR
6. CBR(Constant Bitrate) 前面几个模式都属于可变码率VBR(Variable Bitrate),瞬时码率在波动。恒定码率与之相对,在更小的时间窗口保持码率的波动更小。
允许编码器执行两次(或更多次)使得它可以估计未来的情况。第一遍计算编码的成本,在第二遍中更有效地使用可用比特。这确保了在特定比特率约束下输出质量最佳。
对于x264,使用FFmpeg编码的示例:
- ffmpeg -i <input> -c:v libx264 -b:v 1M -pass 1 -f null /dev/null
- ffmpeg -i <input> -c:v libx264 -b:v 1M -pass 2
对于x265,使用FFmpeg编码的示例:
- ffmpeg -i <input> -c:v libx264 -b:v 1M -x265-params pass=1 -f null /dev/null
- ffmpeg -i <input> -c:v libx264 -b:v 1M -x265-params pass=2
对于VP9,使用FFmpeg编码的示例:
- ffmpeg -i <input> -c:v libvpx-vp9 -b:v 1M -pass 1 -f null /dev/null
- ffmpeg -i <input> -c:v libvpx-vp9 -b:v 1M -pass 2
这是为流式传输编码文件的最简单方法。有两点需要注意:
不知道最终的质量是什么,因此你必须做一些测试,以确保指定的码率实际上足够高,可以用于某些复杂的内容。
此模式的另一个缺点是可能存在比特率的本地峰值,这意味着可能发送超过客户端可以接收的峰值。
可以通过启用nal-hrd选项强制编码器始终使用某个比特率[1]。输出文件需要是.ts(MPEG-2 TS),因为MP4不支持NAL填充。注意,如果视频源是易于编码的,此模式将浪费带宽,但它确保比特率在整个流中保持不变。
ffmpeg -i <input> -c:v libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v 1M -minrate 1M -maxrate 1M -bufsize 2M
ffmpeg -i <input> -c:v libvpx-vp9 -b:v 1M -maxrate 1M -minrate 1M <output>
视频缓冲校验提供了一种方法,以保证码率被限制在一定的最大值。
-maxrate和-bufsize选项打开VBV以设置最大比特率和预期的客户端缓冲区大小:- ffmpeg -i <input> -c:v libx264 -crf 23 -maxrate 1M -bufsize 2M <output>
- ffmpeg -i <input> -c:v libx265 -crf 28 -x265-params vbv-maxrate=1000:vbv-bufsize=2000 <output>
ffmpeg -i <input> -c:v libvpx-vp9 -crf 30 -b:v 2M <output> 使用受约束的ABR-VBV编码的方法
- ffmpeg -i <input> -c:v libx264 -b:v 1M -maxrate 1M -bufsize 2M -pass 1 -f null /dev/null
- ffmpeg -i <input> -c:v libx264 -b:v 1M -maxrate 1M -bufsize 2M -pass 2
- ffmpeg -i -c:v libx265 -b:v 1M -x265-params pass=1:vbv-maxrate=1000:vbv-bufsize=2000 -f null /dev/null
- ffmpeg -i -c:v libx265 -b:v 1M -x265-params pass=2:vbv-maxrate=1000:vbv-bufsize=2000
- ffmpeg -i <input> -c:v libvpx-vp9 -b:v 1M -maxrate 1M -bufsize 2M -pass 1 -f null /dev/null
- ffmpeg -i <input> -c:v libvpx-vp9 -b:v 1M -maxrate 1M -bufsize 2M -pass 2
如何设置bufsize?