什么是码率控制
码率控制是编码器的一个重要模块,主要的作用就是用算法来控制编码器输出码流的大小。虽然它是编码器的一个非常重要的部分,但是它并不是编码标准的一部分,也就是说,标准并没有给码控设定规则。我们平时用的编码器的码控都是编码器程序自己实现的。
那码控的原理是什么呢?其实码控就是为每一帧编码图像选择一个合适的 QP 值的过程。
我们知道当一帧图像的画面确定了之后,画面的复杂度和 QP 值几乎决定了它编码之后的大小。由于编码器无法决定画面的复杂度,因此,码控的目标就是选择一个合适的 QP 值,以此来控制编码后码流的大小。当然有些码控算法是可以直接外部指定使用哪个 QP 值去编码的,就不需要编码器的码控算法去做决策了。但是最后的原理是一样的。那接下来我们就来看一下都有哪些码控算法吧。
码控的类型
常用的码控算法主要有:VBR(动态码率)、 CBR(恒定码率)、CVBR(受限动态码率)、CQP(恒定 QP)和CRF(恒定码率因子), 这几种。
VBR
VBR 指的是编码器输出码率随着原始视频画面复杂度的变化不断的变化。通常当画面复杂或者说运动比较多的时候使用的码率会比较高;而当画面比较简单的时候使用的码率会比较低。VBR 主要的目标是保证视频画面质量,因此比较适合视频点播和短视频场景使用
CBR
另外一种码控算法就是 CBR 了,它是恒定码率的。这种码控方式用户需要设置一个目标码率值给编码器。编码器在编码的时候不管图像画面复杂或简单、运动多或运动少的时候,都尽量使得输出的码率接近设置的目标码率。
这种方式非常适合 RTC 场景,因为 RTC 场景希望编码的码率跟实际预测的带宽值接近,不能超出目标码率太多,也希望能够尽量有效地利用可用带宽,不能太低于目标码率,从而尽量保证编码后图像画面清晰。因此,在 RTC 场景中,我们会将预估带宽分出一定比例给视频数据,并将这部分带宽值当作目标码率设置给编码器。需要编码器的码控算法,能够在各种网络状况下和各种画面变化的情况下,都能使得输出的码率尽量接近于当前预估带宽得到的目标码率。
CVBR(Constrained VariableBit Rate)
),这样翻译成中文就比较难听了,它是VBR的一种改进方法。但是Constrained又体现在什么地方呢?这种算法对应的Maximum bitRate恒定或者Average BitRate恒定。这种方法的兼顾了CBR,VBR方法的优点:在图像内容静止时,节省带宽,有Motion发生时,利用前期节省的带宽来尽可能的提高图像质量,达到同时兼顾带宽和图像质量的目的。这种方法通常会让用户输入最大码率和最小码率,静止时,码率稳定在最小码率,运动时,码率大于最小码率,但是又不超过最大码率。
CQP
CQP 很简单就是从头到尾每一个画面都是用同一个 QP 值去编码。
根据我们视频编码的课程可知:
- 在画面复杂的时候,残差比较大,相同 QP 值做量化之后的残差还是比较大的,编码之后的图像大小就会比较大。
- 而画面简单的时候,残差很小,同一个 QP 值量化之后残差可能很小,甚至都为 0 了,编码之后的大小就会很小。
其实,我个人觉得 CQP 是一种特殊的 VBR。但要注意的是 CQP 一般用来衡量编码算法的性能,在实际工程当中不会使用。
CRF
CRF 是 x264 默认的码控算法。它与 CQP 不同的是它的 QP 是会变化的。
在画面运动大的时候,它会根据具体算法提高 QP 值;
在画面运动小的时候,它会降低 QP 值。它的思想是:运动很大的时候,人眼不太关注细节,因此 QP 可以稍微大一点;
运动比较小的时候,人眼会将注意力放在细节上面,因此 QP 稍微小一点。所以相比 CQP,CRF 能够更省码率一些。
但是 CRF 码控总体上得到的编码后图像的大小,还是随着图像的画面复杂度在变化的。因此,我觉得 CRF 也算是一种特殊的 VBR。