Bootstrap

音视频编解码 --X264码率控制初探

1 比特率介绍

1.1 比特率是什么?

比特率是直播、实时通话或者在线视频流的一个非常重要参数。

比特率衡量一段时间内传输的数据量,是网络传输的重要依据。在直播、实时通话、在线视频流中,视频比特率以千比特每秒或 kbps 为单位。比特率直观体现就是会影响视频的质量。当我们以更高的比特率流传输视频时,用户会获得更高质量的视频体验,对于已经是红海的视频传输来说,便可留住更多用户。

当涉及在线视频流时,互联网公司通常以多种比特率提供其内容,我们称这种传输方式为多比特率流。这种传输模式允许观众根据自身网络、设备情况访问更适合其互联网速度的比特率,从而使他们能够以最少的延迟、抖动和缓冲大小访问最高质量的内容。

自适应比特率视频播放器已经改变了游戏规则,因为它们自动以适当的比特率播放视频,以响应对每个观众的互联网速度的实时状态。

比特率在流媒体过程的编码或转码阶段也很重要,因为这也涉及数据传输。正如我们提到的,恒定比特率流和可变比特率流是两种最流行的编码类型。

1.2 实例说明

举例说明:我们选取了一个本地保存的视频,首先用工具来分析一下。

通过Bitrate Viewer工具查看如下,峰值在18454kpbs,最低4928kpbs,平均10014kpbs,属于比较高清、大码率的文件了。

通过MediaInfo查看,符合上面的观察,比特率大概在10Mbps左右:

2 X264码率控制说明

2.1 码率控制原理

H264标准中采用的是拉格朗日中值定理进行控制的。在数学中的最优化问题中,拉格朗日乘数法(以数学家约瑟夫·拉格朗日命名)是一种寻找多元函数在其变量受到一个或多个条件的约束时的极值的方法。这种方法可以将一个有n个变量与k个约束条件的最优化问题转换为一个解有n + k个变量的方程组的解的问题。

该方法实现复杂度非常高,在实际中应用的比较少,HM中采用该方案。

X264属于工程实践,更加追求效率和简便性,采用了一种更简单、效率高的控制策略--半精度帧的SATD算法,作为码率控制中策略选择的依据,该方案更多是根据经验总结出来的算法,但是作为指导码率控制策略是可以满足基本需求的,简便性更是拉格朗日乘数法不可比拟的。

2.2 码率控制基本函数

从FFMPEG中调用码控相关函数,基本上是x264_init和x264_frame两个地方,调用方式符合FFMPEG的接口api,代码如下:

其相关调用流程,主要是从x264_encoder_open 开始时候被创建,完成ratecontrol的构建初始化动作,然后在x264_encoder_encode时候真正开始码率控制相关内容,完成视频流的码率控制整体估计和使能操作。调用逻辑还是清晰明了的。主要的核心算法或者模块包括:lookahead、zone、ratecontrol和slice等,其部分调用流程如下图所示:

这样就可以进行码率控制了。

3 X264码率控制

之前文章中有介绍一些关于码控的内容,这里简单说明一下,主要是跟踪X264的代码说明参数如何使用的。

X264中一共有三种码率控制参数:CQP、ABR、CRF。每种模式针对不同的场景,以及不同的视频效果不一,以下我们稍微做一些介绍,之后有时间再分别针对每种详细展开讲解。

3.1 恒定量化参数--CQP

CQP对应的类型为:X264_RC_CQP该值表示恒定量化参数,编码器会尽量把每帧图像采用相同的量化参数该方法并不推荐。由于每帧图像都采用相同的量化参数,会导致静止图像浪费码率,运动激烈,变化突出的图像码率不够,而且码率也会有剧烈变化,呈现明显锯齿状;还有需要注意的是libvpx是不支持改模式的。

还是眼见为实,通过实例观察有对比才能发现差异:通过FFMPEG命令,我们转码为6Mbps左右,具体命令如下:

ffmpeg -i 20210707.mp4 -vcodec libx264 -profile:v baseline -b:v 6000k -minrate 6000k -maxrate 6000k -bufsize 250k -an -movflags rtphint -bf 0 test6M.mp4;

在执行时,可以看到rc模式为CBR模式,

对应的Bitrate View截图如下,当用cqp = 23进行转码时,生成的码率大概如下:并且于原图进行对比,无论最大值、最小值、平均值都有了非常大的变化。同时发现波形分布基本上相同;

CQP的模式使得每帧图像采用固定大小的QP进行量化,因此每帧图像码率波动和原图像基本保持一致。

3.2 平均比特率--ABR

ABR对应的类型为:X264_RC_ABR,也算VBR的一种;该值表示编码器会根据视频采集内容的复杂度(实际上是帧间变化量、运动情况)动态调整输出码率,图像复杂则码率高,图像简单则码率低,码率会波动比较大。该模式在输出码率时有一定的波动:对于静止画面,压缩后的码率会非常低;而对于小幅度运动场景,可能会有方块效应,这时画面质量逐渐变差,码率也会上升;但是对于剧烈晃动,比如连续挥手测试,则出现严重马赛克。

相同的视频,用ABR模式转码,实例截图如下:

ffmpeg -i 20210707.mp4 -c:v libx264 -b:v 6000k test_dr_6m.mp4

对应的Bitrate View截图如下,大概码率设置为6Mbps,

ABR模式也是按照每帧图像的内容进行调整QP的,所以码率波动也和原视频保持一致

如果按照CBR进行转码,则波形就差异比较多了:

ffmpeg -i 20210707.mp4 -vcodec libx264 -profile:v baseline -b:v 6000k -minrate 6000k -maxrate 6000k -bufsize 250k -an -movflags rtphint -bf 0 test6M.mp4

由于采用CBR模式,整个码率输出基本稳定在4709Kbps上下,上下峰值之前差距非常小,可以看出对应的码率严格按照固定的码率输出的。

3.3 恒定质量因子--CRF

CRF对应的类型:X264_RC_CRF该模式是一种编码模式,可以向上或向下调整文件数据速率以达到选定的质量级别,而不是特定的数据速率。如果要保持最佳质量,而又不怎么担心文件大小,这时候就可以使用CRF速率控制模式。CRF 编码适用于存档或生成用于上传和转码的夹层文件。 但是,从可交付性的角度来看,它不是最理想的,因为在对文件进行编码之前,不知道将产生的数据速率。

可以参考

进行crf转码的命令行如下:

ffmpeg -i 20210707.mp4 -c:v libx264 -b:v 6000k -crf 23 test_crf23_6M.mp4

CRF模式的码率自成一派,有点像原视频,也有差异,压缩后图像也还维持在比较好的状态。

4 计划

要理清码率控制相关内容,需要准备比较多的知识,比如RDO,比如VBV,比如量化参数;以及对于编码的深度理解。我们会分几次分别对相关内容进行讲解,依次拨开码率控制的面纱。当原理讲解清楚后,会从实战方向,说明具体参数对于网络传输的影响,以及如何进行优化以期达到理想的效果。

欢迎感兴趣的童鞋一起参与学习和探讨。