视频编码-码率控制CQP/CRF/ABR/CBR/VBV

1. 参考

  • [1] Werner Robitza/Understanding Rate Control Modes (x264, x265, vpx)

  • [2] Werner Robitza/CRF Guide (Constant Rate Factor in x264, x265 and libvpx)

  • [3] codesequoia/What are CBR, VBV and CPB?

2. 概述

编码器中有一个码率控制模块,通过选择一系列编码参数,来控制编码视频的码率满足需要,并且使编码失真尽可能小。码率控制严格上不属于视频编码标准,属于率失真优化

码率控制的几种模式[1]:

  1. CQP(Constant QP):恒定QP(Quantization Parameter)。
  2. CRF(Constant Rate Factor)/CQF(Constant Quality Factor):恒定质量因子。
  3. ABR(Average Bitrate):指定平均码率。
  4. CBR(Constant Bitrate):恒定码率,相对的是可变码率(VBR, Variable Bitrate)。
  5. VBV(Video Buffering Verifier):视频缓冲校验。

3. CQP(Constant QP)

恒定QP(Quantization Parameter)。

  • 瞬时码率会随场景复杂度波动。
  • x264和x265中支持CQP模式,libvpx不支持。
  • H.264中QP范围是[0, 51]。QP值越大表示越大的量化步长,编码视频的质量越低。QP为0表示进行无损编码。
  • 使用FFmpeg指定QP的示例如下所示。
ffmpeg -s 1280x720 -i  -c:v libx264 -qp 23 
ffmpeg -s 1280x720 -i  -c:v libx265 -x265-params qp=23 

 

  • 不推荐使用这个模式,除非你明确知道这个模式的原理而有特定的用途。

4. CRF(Constant Rate Factor)/CQF(Constant Quality Factor) 恒定质量因子。

  • 与恒定QP类似,但追求主观感知到的质量恒定,瞬时码率也会随场景复杂度波动。

  • 对于快速运动或细节丰富的场景会适当增大量化失真(因为人眼不敏感),反之对于静止或平坦区域则减少量化失真。

  • CRF是x264和x265的默认码率控制方式,也可用于libvpx。

  • CRF值越大视频压缩率越高,但视频质量越低,各codec的CRF取值范围、默认值和建议值见下表。

视频编码-码率控制CQP/CRF/ABR/CBR/VBV_第1张图片

  • 使用FFmpeg中指定x264编码的crf值的示例如下。
ffmpeg -i input.mp4 -c:v libx264 -crf 23 output.mp4
  • 如果你不确定要使用什么CRF,从默认值开始,并根据对输出的主观印象进行更改。如果质量没有足够好则较低的CRF。如果文件太大了则选择更高的CRF。更改±6会导致码率大小的一半/两倍左右的变化,±1会导致码率10%左右的变化。[2]

【CSDN文末扫码进君羊,免费分享】资料包括《Andoird音视频开发必备手册+音视频学习视频+学习文档资料包+大厂面试真题+2022最新学习路线图》等等 

视频编码-码率控制CQP/CRF/ABR/CBR/VBV_第2张图片

 

5. ABR(Average Bitrate) 指定平均码率。

  • 使用FFmpeg指定ABR的示例如下所示。

ffmpeg -s 1280x720 -i  -c:v libx264 -b:v 1M 
ffmpeg -s 1280x720 -i  -c:v libx265 -b:v 1M 
ffmpeg -s 1280x720 -i  -c:v libvpx-vp9 -b:v 1M 
  • 避免使用这种模式, x264的一位主要开发者说你应该永远不要使用它,由于编码器无法提前知道要编码视频的情况,它将不得不猜测如何达到比特率。

2-Pass ABR

6. CBR(Constant Bitrate) 前面几个模式都属于可变码率VBR(Variable Bitrate),瞬时码率在波动。恒定码率与之相对,在更小的时间窗口保持码率的波动更小。

  • 允许编码器执行两次(或更多次)使得它可以估计未来的情况。第一遍计算编码的成本,在第二遍中更有效地使用可用比特。这确保了在特定比特率约束下输出质量最佳。

  • 对于x264,使用FFmpeg编码的示例:

  • ffmpeg -i  -c:v libx264 -b:v 1M -pass 1 -f null /dev/null
    ffmpeg -i  -c:v libx264 -b:v 1M -pass 2 .mp4

    对于x265,使用FFmpeg编码的示例:

    ffmpeg -i  -c:v libx264 -b:v 1M -x265-params pass=1 -f null /dev/null
    ffmpeg -i  -c:v libx264 -b:v 1M -x265-params pass=2 .mp4

    对于VP9,使用FFmpeg编码的示例:

    ffmpeg -i  -c:v libvpx-vp9 -b:v 1M -pass 1 -f null /dev/null
    ffmpeg -i  -c:v libvpx-vp9 -b:v 1M -pass 2 .webm

  • 这是为流式传输编码文件的最简单方法。有两点需要注意:

  • 不知道最终的质量是什么,因此你必须做一些测试,以确保指定的码率实际上足够高,可以用于某些复杂的内容。

  • 此模式的另一个缺点是可能存在比特率的本地峰值,这意味着可能发送超过客户端可以接收的峰值。

  • 可以通过启用nal-hrd选项强制编码器始终使用某个比特率[1]。输出文件需要是.ts(MPEG-2 TS),因为MP4不支持NAL填充。注意,如果视频源是易于编码的,此模式将浪费带宽,但它确保比特率在整个流中保持不变。

ffmpeg -i  -c:v libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v 1M -minrate 1M -maxrate 1M -bufsize 2M 
  • 对于VP9,使用FFmpeg通过下面的命令控制:
ffmpeg -i  -c:v libvpx-vp9 -b:v 1M -maxrate 1M -minrate 1M 

7. VBV(Video Buffering Verifier)

视频缓冲校验提供了一种方法,以保证码率被限制在一定的最大值。

  • 适用场景:带宽约束下的流媒体; 直播(指定CRF,1-pass); VoD流媒体(目标比特率,2-pass)。
  • 可用于2-pass VBR(在两遍中使用它)。注意:使用1-pass方法也可以 - 根据x264开发人员 - 通常与2-pass一样好,但压缩效率低一些。
  • 可用于CRF编码,也称为“capped CRF”。
  • 使用-maxrate-bufsize选项打开VBV以设置最大比特率和预期的客户端缓冲区大小:
ffmpeg -i  -c:v libx264 -crf 23 -maxrate 1M -bufsize 2M 
ffmpeg -i  -c:v libx265 -crf 28 -x265-params vbv-maxrate=1000:vbv-bufsize=2000 

  • VP9有一个类似的模式,不叫VBV,但背后是相同的思想:
  • ffmpeg -i  -c:v libvpx-vp9 -crf 30 -b:v 2M 

    使用受约束的ABR-VBV编码的方法

  • ffmpeg -i  -c:v libx264 -b:v 1M -maxrate 1M -bufsize 2M -pass 1 -f null /dev/null
    ffmpeg -i  -c:v libx264 -b:v 1M -maxrate 1M -bufsize 2M -pass 2 

  • 对于x265:
  • 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 

  • 对于VP9:
  • ffmpeg -i  -c:v libvpx-vp9 -b:v 1M -maxrate 1M -bufsize 2M -pass 1 -f null /dev/null
    ffmpeg -i  -c:v libvpx-vp9 -b:v 1M -maxrate 1M -bufsize 2M -pass 2 

    如何设置bufsize?

  • 这取决于码率需要有多大的可变性。
  • 一个好的默认设置:缓冲区大小是最大速率的两倍,但建议可能会因流设置而异。
    • 如果客户端缓冲区较小(只需几秒钟),bufsize应该与maxrate大小相同。
    • 如果要限制流的码率,尝试将bufsize设置为最大速率的一半或更低。

你可能感兴趣的:(音视频开发,流媒体服务器,Android音视频开发,音视频,实时音视频,视频编解码,语音识别,webrtc)