什么是“码率控制”?它是编码器决定为每帧视频分配多少比特的工具。
视频编码(有损)的目标是尽可能多的节省比特(码率)的同时尽量保持视频质量。码率控制是平衡码率和质量的重要工具。
码率控制有多种方式,你将会了解到"1-pass","2-pass","CBR","VBR","VBV Encoding"和"CRF"等。
下面是不同码率控制模式的简单示例,它告诉你作为终端用户应该在什么时候用什么模式。注意这里不包含RDO的具体细节。
很多人可能更熟悉音频编码器,尤其是那些经历了MP3年代的人。不过从CD的发展史来说,最开始使用固定码率(Constant Bitrate,CBR)编码,后来发展出了可变码率(Variable Bitrate,VBR)。VBR可以确保在给定限制下使用最少的比特情况下保持最高质量。
简单说,VBR可以使编码器在难编码的地方花费更多比特,在编码简单的地方花费更少比特。对编码来说“难编码”和“容易编码”代表什么呢?通常有大量运动的视频需要更多比特,空间细节丰富和纹理复杂的视频也较难编码。
选择哪种码率控制模式往往取决于你的应用场景。通常有以下几种常见场景:
存档:压缩一个文件存到硬盘或网盘上。这时你希望文件编码后质量尽可能好同时码率尽可能低,但是你不关心压缩后文件的具体大小。
流媒体:你想要通过网络传输一个文件。这是你要确保文件码率不超过网络带宽,或者你需要在不同带宽下提供不同码率的文件。(例如,在网上看视频网络不好时将视频从高清切换到低清)。
直播流:和2类似,但是你需要尽快编码(实时),并且直播时你无法提前预知视频内容。
面向设备的编码:例如你想向DVD或蓝光碟上存放文件,你想使文件编码后达到特定大小(正好占满碟片空间)。
了解使用场景可以帮助你选择码率控制模式。
下面介绍不同的码率控制模式,这些模式基于ffmpeg中的x264,x265和libvpx编码器。你可以在ffmpeg文档找到详细参数介绍。
注意:编码器默认不会“填塞”比特。意味着,当编码简单的帧时,实际使用比特可能低于设定的比特,这时编码器不会浪费比特强行达到设定比特。
量化参数(Quantization Parameter,QP)控制着压缩大小。QP越大压缩率越高同时质量越低,QP越小压缩率越低同时质量越高。在H.264和H.265中,QP的范围是0-51间的整数。你可以很容易的在x264和x265中设置固定QP来编码。注意:libvpx没有固定QP模式。
ffmpeg -i -c:v libx264 -qp 23
可以参考这个教程了解更多QP的作用原理。
除非你明确的知道你想要做什么,否则不要使用这个模式。采用CQP模式会导致根据场景复杂度不同比特率波动很大,你无法控制实际比特率。
好处:视频编码研究。
坏处:几乎其他所有应用。
下面是给定编码器一个目标码率,编码器计算如何达到这个码率:
ffmpeg -i -c:v libx264 -b:v 1M
ffmpeg -i -c:v libx265 -b:v 1M
ffmpeg -i -c:v libvpx-vp9 -b:v 1M
避免使用这个模式!x264的主要开发者之一说你应该永远不要使用它。为什么?因为编码器不知道后面还未编码的内容,所以它不得不猜测如何达到给定码率。这意味着码率要一直变化,尤其是在开始时。对于 HAS-type流,这会导致在短时间内质量巨大波动。
ABR不是一种恒定码率模式而是可变码率模式。
好处:快速编码。
坏处:几乎其他所有应用。
通过设置nal-hrd可以使编码器强制保持在特定码率。
ffmpeg -i -c:v libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v 1M -minrate 1M -maxrate 1M -bufsize 2M
输出文件必须是MPEG-2 TS文件,因为mp4不支持NAL填充。注意这种模式对于简单的视频会浪费带宽,但是它保证整个流的码率一致。你可以在这里找到更多用例。在某些应用中使用这种模式是有意义的,但是你可能希望在可能的时候码率更低。
对于VP9使用CBR的命令如下:
ffmpeg -i -c:v libvpx-vp9 -b:v 1M -maxrate 1M -minrate 1M
好处:保持恒定码率;视频流(例如:Twitch)。
坏处:文档存储;高效使用带宽的场景。
如果允许编码器两遍(或更多)编码那么它就可以预先估计未来还未编码的内容。它可以在第一遍编码是计算编码代价,然后在第二遍编码是更高效的利用比特。这种模式使得在特定码率下输出的质量最好。
对于x264:
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 -i -c:v libx265 -b:v 1M -x265-params pass=1 -f null /dev/null
ffmpeg -i -c:v libx265 -b:v 1M -x265-params pass=2 .mp4
对于VP9:
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
这是对流进行编码的最简单的方法。但有两点注意:你不知道最终结果的质量如何,所以你必须进行多次实验以确保给定的码率足够编码复杂内容。另一点是这种模式码率可能出现局部峰值,意味着发送能力可能超过客户端的接受能力。对于码率的选择,你可以参考YouTube的推荐设置,但是注意这些都是为了让你上传高质量的照片而优化的,实际中你可以选择更低的码率。
好处:达到特定码率;面向设备的编码。
坏处:如果你需要快速编码(例如,直播流)。
CRF可以保持整个视频流质量恒定。
ffmpeg -i -c:v libx264 -crf 23
ffmpeg -i -c:v libx265 -crf 28
ffmpeg -i -c:v libvpx-vp9 -crf 30 -b:v 0
在H.264和H.265中,CRF取值为0到51间的整数(和QP类似)。x264默认值是23,x265默认值是28。CRF增减6会导致码率减半或加倍。对于VP9,CRF取值范围0到63,推荐值为15-35。
这种模式缺点是无法确定最终文件的码率和码率波动。
好处:文档存储;达到尽可能好的质量。
坏处:流媒体;需要特定码率(或文件大小)。
对于VBV可以确保码率不超过某个最大值。这对于流媒体非常有用,你现在可以确定你不会发送比你承诺的更多的比特。VBV可以和2-pass VBR(在两遍编码中都使用)或CRF一起使用。
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
如果你在直播流中应用VBV,且你想加速编码过程,你可以使用-tune zerolatency和-preset ultrafast选项。这会牺牲一部分质量来加速编码。
在受约束的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设为maximum rate的两倍。如果客户端缓存比较小,设置bufsize等于maxrate。如果你想限制码流的码率,设置bufsize为maximum rate的一半或更小。
好处:带宽受限的流媒体;直播流(使用CRF,1-pass);VoD流。
坏处:文档存储。
下面是不同码率控制算法的比较。使用Big Buck Bunny和Tears of Steel序列,每个序列截取三段(每段30秒)。使用libx264编码器,除了码率控制模式不同外,其他都是默认设置。设置了不同的目标码率(750,1500,3000,7500kbit/s)和最大码率(针对VBV)和QP/CRF值(17,23,29,35)。
注意这个实验并不充分,你可以尝试更多的序列和使用不同编码器。
下图是使用不同码率控制模式的结果。左边是3000kbit/s的结果,右边是7500kbit/s的结果。另两种结果的图像差不多,这里不再展示。每条线代表不同模式下码流的码率变化情况。
从BBB1看出,ABR(蓝绿色线)和ABR+VBV(紫色线)开始时错估了视频复杂度,实际是BBB视频的开始部分比较平滑,运动比较小只需要很少的比特就可以保证质量。2-pass模式在开始时正确估计了复杂度,起始使用了低码率节省了带宽。视频的后1/3部分,空间细节丰富使得2-pass模式消耗了大量比特,超过了起始节省的比特。
BBB2视频里,不同模式实际上比预期要好。但是2-pass的波动还是比其他模式更多。
下面是CQP和CRF的实验情况,这里只展示了CRF/CQP为17和23的结果。CRF的效果更好。
下面是CRF+VBV在不同码率下的结果。为CRF选择合适的目标码率和最大码率通常需要多次尝试,完全取决于视频源。
翻译自Understanding Rate Control Modes (x264, x265, vpx)
感兴趣的请关注微信公众号Video Coding