(原)理解码率控制模式(x264,x265,vpx)

理解码率控制模式(x264,x265,vpx)

原文链接:https://slhck.info/video/2017/03/01/rate-control.html

翻译:lihaiping1603@aliyun.com

 

前言:Variable vs. Constant Bitrate (可变码率和固定码率)

 

简单地说,VBR让编码器为难编码的图像使用更大的bits,而为能简单压缩的节约bits. 那对于编码压缩什么是简单和难的呢?如果一个视频中存在大量运动,那么视频中相邻的视频图像帧之间的差异就会更大。同时,高空间细节和复杂的纹理也很难编码

 

你的编码场景是什么?

1,归档(存储):这种场景我们可能要求文件的大小应该在尽可能小的体积下具有尽可能好的质量,但是您并不关心确切的大小

2,流:您希望通过Internet发送文件,使用典型的视频点播(VoD)流媒体解决方案,如HTTP渐进下载或HTTP自适应流媒体。您需要确保文件不超过特定的比特率,或者您需要以不同的名义比特率提供相同文件的不同表示(用于自适应流)

3,实时流媒体(直播):你希望尽快的完成编码,同时你也事先对视频内容未知。

4,编码设备:你想把你的文件做成DVD,蓝光等等。您希望确保文件最终具有特定的大小

 

码率控制模式

需要注意的是:x264这样的编码器在默认情况下并不会不必要地用比特“填充”帧。这意味着如果你有一个非常容易编码的场景,你的比特率可能总是低于你指定的。不要担心这个——只要记住,如果浪费的话,实现一个精确的比特率是没有意义的。

1,Constant QP(CQP) :固定视频量化参数

ffmpeg使用:

ffmpeg -i <input> -c:v libx264 -qp 23 <output>

量化参数控制帧中每个宏块的压缩量.较大的值意味着更高的量化、更多的压缩和更低的质量.QPH.264中取值范围从051,使用x264x265可以轻松地为整个编码过程设置一个固定的QP。注意:libvpx没有固定的QP模式

除非您知道自己在做什么,并且明确地希望这样,否则不要使用此模式!设置一个固定的QP意味着根据每个场景的复杂性,产生的比特率会有很大的变化,这将导致输入视频的编码效率很低。您可能会浪费空间,而且无法控制实际的比特率。

Good for: Video encoding research好处是针对视频研究的场景
Bad for: Almost anything else      大部分的场景下都是不好的

请注意,Netflix建议使用固定qp编码对每个镜头进行编码优化,以实现每个场景的最佳编码。然而,这需要大量的处理和个别编码镜头的仔细组装,所以它不是一个“一刀切”的方法,你应该使用,除非你有整个框架的实现。

Netflix参考链接:

https://medium.com/netflix-techblog/dynamic-optimizer-a-perceptual-video-encoding-optimization-framework-e19f1e3a277f

 

2,Average Bitrate(ABR):平均码率模式

ffmpeg使用:

ffmpeg -i <input> -c:v libx264 -b:v 1M <output>

避免使用此模式!一个主要的x264开发人员自己说,你不应该使用它。为什么?由于编码器不知道确切的前方时间,它将不得不猜测如何达到该比特率。这意味着速率本身会发生变化,特别是在剪辑开始的时候,在某一时刻达到目标。特别是HAS-type的流媒体,这导致巨大的质量差异在短片段

这不是一个恒定比特率模式!虽然ABR在技术上是一种VBR模式,但它并不比指定恒定的比特率好多少,因为它不能可靠地提供良好的质量

Good for: Quick and dirty encodes  快速和下流的编码
Bad for: Almost anything    大部分场景下是不好的

 

3,Constant Bitrate(CBR):固定码率模式

ffmpeg使用(通过启用nal-hrd选项强制编码器始终使用特定的比特率)

ffmpeg -i <input> -c:v libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v 1M -minrate 1M -maxrate 1M -bufsize 2M <output>

这种模式下输出文件需要指定为ts格式,因为mp4格式不支持NAL stuffing(填充)。

注意:这种模式下,会比较浪费带宽,如果你的视频源是比较容易编码的那种的话,但它可以确保比特率在整个流中保持不变。在某些应用程序中使用这种模式可能有意义,但是您通常希望允许流在可能的情况下使用较低的比特率

Good for: Keeping a constant bitrate (duh); video streaming (e.g. Twitch)

Bad for: Archival; efficient use of bandwith

好处:在保持恒大的比特率和视频流(例如twitch)场景有利

坏处:在存储和高效利用带宽的场景下是不利的。

4,2-Pass Average Bitrate(2-Pass ABR)2-Pass平均码率模式

ffmpeg使用:

ffmpeg -i <input> -c:v libx264 -b:v 1M -pass 2 <output>.mp4

允许编码器进行两次(或两次以上)传递,使其能够及时估计前方的情况。它可以在第一轮计算编码帧的成本,然后在第二轮更有效地利用可用的比特。这确保了在一定的比特率约束下,输出质量是最好的

这是对文件进行流编码的最简单方法。有两点需要注意:你不知道结果的质量如何,所以你必须做一些测试来确保你的比特率对于一些复杂的内容来说是足够高的。这种模式的另一个缺点是可能会出现本地比特率峰值,这意味着您发送的比特率可能会超过您的客户端能够接收到的比特率。至于选择比特率,YouTube会给你推荐上传的设置,但要记住,这些设置是为了让你上传的质量更好而优化的,所以实际上你也可以选择更低的比特率

Good for: Reaching a certain target bitrate; encoding for devices
Bad for: If you need quick encoding (e.g., live streaming)

好处是对于一些需要达到一定比特率的场景或者编码设备是有利的。

而对于实时流或者直播这个是不利的。

youtube比特率选择的参考链接:

https://support.google.com/youtube/answer/1722171?hl=en

如下:

 

 

5,Constant Quality(CQ)/Constant Rate Factor(CRF):恒定质量或者恒定速率因子模式

ffmpeg示例:

ffmpeg -i <input> -c:v libx264 -crf 23 <output>

H.264H.265中,CRF的范围是从051(就像QP)23x264的良好默认值,28x265的默认值。18 (x26524)应该在视觉上透明;任何更低的值都可能会浪费文件大小。±6的值将导致大约一半或两倍的原始比特率。对于VP9, CRF可以是063。推荐值为15-35
这种模式唯一的缺点是,您不知道最终的文件大小或比特率的波动。
请注意,双通道和CRF编码具有相同的比特率应该是相同的定性

Good for: Archival; achieving the best possible quality
Bad for: Streaming; obtaining a certain bitrate / file size

对于存储归档模式,这种是有利的,能实现最好的视频质量。而对于流来说,或者获得一定码率或者文件体积的来说,这种是不利的。

6,Constrained Encoding(VBV):约束编码模式VBV

VBV视频缓冲验证器提供了一种确保比特率被限制到某个最大值的方法。这对于流媒体非常有用,因为您现在可以确定在一定的时间范围内不会发送比承诺的更多的比特。VBV既可以与2-Pass VBR一起使用(在两个通道中都使用),也可以与CRF编码一起使用——它可以“添加”到已经提供的速率控制模式中。后一种模式也称为“上限CRF”。

打开VBV-maxrate-bufsize选项来设置最大比特率和预期的客户端缓冲区大小

ffmpeg示例:

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 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 <output>

注意:如果您对直播应用程序这样做,并且希望加快编码过程,那么使用x264x265的时候,可以添加-tune zerolatency- ultrafast选项。他们降低了你得到一定比特率的质量但大大加快了过程。对于libvpx-vp9,需要设置-quality realtime-speed 5。有关更多信息,请参阅H.264VP9指南

如何设置bufsize?这取决于你希望比特率有多大的可变性。一个好的默认设置是将缓冲区大小设置为最大速率的两倍,但是建议根据流设置的不同而有所不同。如果您的客户端缓冲区更小(大约几秒钟),则bufsize应该与maxrate大小相同。如果您想约束流的比特率,请尝试将bufsize设置为最大比特率的一半或更少。

当您将VBV应用于CRF编码时,诀窍是找到一个CRF值,该值平均会产生您所期望的最大比特率,但不会更多。如果你的编码总是“最大化”你的最大比特率,你的CRF可能设置得太低了。在这种情况下,编码器试图花费它没有的比特。另一方面,如果你有一个高的CRF,使比特率不总是达到最大,你仍然可以降低它来获得一些质量。例如,你编码在crf18没有VBV。您的剪辑以3.0 Mbit/s的平均比特率结束。但你希望你的VBV设置上限剪辑1.5 Mbit/s所以你需要把你的CRF降低到24来得到一半的比特率。

Good for: Streaming under bandwith constraints; live streaming (with CRF, 1-pass); VoD streaming (with target bitrate, 2-pass)
Bad for: People who want to play around; archival

这个模式对于在一定受限的带宽流媒体下和直播流(crf,1-pass模式);VoD流媒体(使用目标比特率,2-pass)场景,是有好处的,而对于归档存储场景,并不是那么有利。

 

7,实例比较演示

让我们从不同的比特率控制模式开始。左边是3000 kbit/s,右边是7500 kbit/s。我排除了其他目标比特率,因为它们在图中没有表现出强烈的差异,因为比特率已经处于如此低的水平,编码器在如何分配它上没有太多的选择。这些行是不同的剪辑从大巴克兔(BBB)和眼泪的钢铁(ToS)。这条线代表了对单个帧大小的LOESS(拟合)平滑——它指示了比特率在剪辑持续时间内的变化。

 

 

 

 

你可以看到——尤其是前四个内容——ABR(绿松石线)ABR+VBV(紫色)错误地估计了剪辑的复杂性。事实上,大的巴克兔序列以渐隐、平滑的梯度和低运动开始,这意味着不需要很多位元来压缩它以获得足够好的质量。2-pass方法正确地以较低的比特率开始,并节省带宽。视频剪辑的最后三分之一包含了大量的空间细节,这使得2-pass模式消耗了更多它在开始时保存的比特

对于基于质量的模式(CQPCRF),我只显示CRF/QP 1723的结果,这是质量范围的“好”端(就像30007500 kbit/s是全高清视频的“好”值)。曲线的顺序是相反的——越低意味着质量越好:

 

 

 

 

在这里,可以看到与2-pass相同的趋势:比特率跟随内容的复杂性。然而,使用CRF时,它受到了更多的限制,可以在不需要的地方保存数据。最有趣的情况是左下角:CRF比常数QP节省比特率,就像它通常做的那样,但它是以常数偏移量做到的。我不得不猜测为什么会这样,也许这篇文章将会更新一些进一步的分析。

一般来说,我们可以看到CRF方法如何很好地匹配内容,只要我们事先知道结果的平均比特率是多少……这就是CRF+VBV发挥作用的地方:

 

 

 

 

为给定的CRF选择正确的目标/最大比特率通常是猜测,完全取决于源视频。然而,当正确完成时,您不会对质量进行太多的限制,将其推到极限(3000 kbit/sCRF 17的情况)。你也不想让比特率变化太多。CRF 23libx264的默认设置,您可以看到,在给定适当的目标比特率设置(比如7500 kbit/s)的情况下,这种编码模式允许比特率的变化足以反映内容复杂性的差异,同时仍然符合VBV模型

 

8,小结

理解不同的速率控制模式并不容易。不幸的是,最简单的解决方案(只指定比特率)是完全不推荐的,但是Web一直使用这种方法传播代码示例。

总结一下,根据你的用例,你应该这样做:

档案- CRF,给你想要的质量。
-2-pass(双通道)CRFABRvbv恒定的比特率。
实时流媒体-一遍CRFABRvbv恒定的比特率,或CBR,如果你可以浪费比特。
设备编码——通常是2-pass ABR

 

转载请注明出处:https://www.cnblogs.com/lihaiping/p/11726306.html

posted @ 2019-10-23 14:55  lihaiping  阅读(3906)  评论(0编辑  收藏  举报