写点什么

音视频学习 --X264 码率控制起航

作者:Fenngton
  • 2021 年 12 月 04 日
  • 本文字数:2112 字

    阅读完需:约 7 分钟

音视频学习--X264码率控制起航

上篇文章中讲述了码率控制的基本调用流程,只是梳理了一下大概,具体函数并没有展开讲解,有兴趣的可以参看一下:

https://xie.infoq.cn/article/2cf6cad0ba2963b84efb3f981http://192.168.13.20:83/pages/viewpage.action?pageId=20938792

本章中将针对 x264_ratecontrol_start 进行说明,并且针对其中重要的函数进行详细讲解,以期能够明白码率控制如何起航的。

废话不读,干活来了。


我们翻看上一次的函数调用图,可以看到从 X264open 时候就完成 ratecontrol 的构建初始化动作。在 encode 阶段进行完成视频流的码率控制整体估计和使能操作。调用逻辑还是清晰明了的。

2 x264_encoder_open

x264_encoder_open 函数主要作用就是打开 x264 编码器,并完成 x264 中编码所需要的各种变量初始化动作,包括参数验证;sps、pps 的初始化;帧内预测模块初始化;像素计算相关变量初始化;运动补偿 MC 初始化;量化器模块初始化;去块效应滤波器初始化;Lookahead 模块初始化;以及码率控制模块初始化。


这里我们关心码率控制即可,其他部分有时间再补充更新。

3 Lookahead:

主要作用就是完成 MB-Tree 码率控制以及 vbv-Lookahead 视频帧类型判定,其最大值是 250;其实 Lookahead 模块在大家日常使用 FFMPEG 时肯定都用过。如果有人不知道,只是说明没有留意。在进行 X264 参数预设时,preset 参数大家肯定都预设过,其中就包含的 Lookahead 的使用,参看下图:


Lookahead 的开启可以使得码率控制更加精确,画质更加精良,但是也有副作用,就是增加了编码延迟,特别是 Lookahead 值越大,编码延迟越高,这也是上图中 preset 预设时,fast 侧的 Lookahead 设置为小于 2;而 slow 侧的 Lookahead 值都大于 5 的原因。Lookahead 功能也是码率控制的一个重要部分,其原理和实现都是非常有必要说明,之后会抽出一篇文章单独说明,在此先略过。我们只需要明白该功能主要作用是预判帧的类型,以及 MB-Tree 相关码率即可。

对于 mb-tree 部分,增加帧数会产生更好的结果,但也更慢。 mb-tree 使用的最大缓冲区值计算公式: MIN( rc-lookahead, --keyint );

对于 vbv-lookahead 部分,增加帧数会在使用 vbv 时产生更好的稳定性和准确性。vbv-lookahead 使用的最大值计算公式:MIN(rc-lookahead, MAX(--keyint, MAX(--vbv-maxrate, --bitrate) / --vbv-bufsize * --fps))

4 x264_ratecontrol_new


x264_ratecontrol_new 的主要作用是:

(1)构建 x264_ratecontrol_t,并且初始化码率控制相关的参数,比如 b_abr、b_2pass、rate_tolerance 等,并调用 x264_ratecontrol_init_reconfigurable 进行参数配置;

(2)设置输出视频的缓冲区相关参数 parse_zones,并初始化;

(3)调整码率控制相关 QP 相关的值 qp_constant;

4.1 x264_ratecontrol_t


x264_ratecontrol_t 主要包含码率控制的各种参数集合,包括基本变量、当前码控帧的参数、VBV 相关的变量、ABR 模式相关参数、如果开始 2-pass 后相关参数以及 MB 宏块码控估计相关的参数、HRD 假设参考解码相关参数。所有参数集合都是为了更准确估计和预测当前视频帧的码率大小,并为编码提供合理的 QP 值,使得最后编码后的码率在预期范围内。不同的预设条件和默认参数的组合得出的码率大小是不一样的,所以需要针对每一种都有比较好的了解,才能更好的了解相关码控内容。

4.2 parse_zones

parse_zones 主要作用是可用于为视频的特定部分手动分配较低或较高的比特率。从名称上显而易见,完整的视频编码过程中会有多个 zone 生成,因此每一个 zone 都需要单独解析,也就有了 parse_zone 的被调用。

如果有多个 zone 被传递时,每个 zone 的组成格式是:起始帧,结束帧,可选项/...等键值对依次构成,任意两个键值之间用“,”隔开;可选项用“property=value”格式;任意两个 zone 之间是用“/”进行隔离。其中可选项中有两种可选项类型需要特别注意,和码率有强相关性:“b=<float>”和"q=<int>"。其中 b 指示的意思是:当前 zone 的比特率变量;而 q 指示的意思是:当前 zone 的常量量化值。start Frame,End Frame,property = value/start Frame,End Frame,property = value/start Frame,End Frame,property = value.....

实例说明:0,1024,b=8/1024,2000,q=12

这部分可以从代码中清晰看出。


4.3 x264_open

x264_fopen 是为了验证输出文件或者临时生成的文件是否正常,如果输出文件无法打开,则编码失败;


有用过 FFMPEG 的知道,我们用 2-pass 参数时,在同目录下会生成两个文件,

x264_2pass.log 和 x264_2pass.log.mbtree。如果 2-pass 中中间临时文件无法打开,则 2-pass 中第二通是没有办法再进行的。特别是 2-pass 开启后,在码率控制中如果中间两个文件无法开启,则后续的码控是无法进行的,因此要进行 OPEN 验证。

5 x264_ratecontrol_start

x264_ratecontrol_start,就是开启真正的码率控制流程了,主要作用就是在一个视频帧开始编码之前,完成 QP 量化值的选定,以便能够满足输入的码率或者编码模式的约束特性。主要包含步骤如下:

(1)获取视频特定 Zone 区域,以便进行码率预测;

(2)更新当前所有视频帧原计划的 VBV 值;

(3)依据输入的各种参数,已经 qscale 值的估计和预测;该步骤是核心部分,直接决定整个码率控制效果的成败。

(4)转换 qscale 为 qp 值;

(5)更新 accum_p_qp 的值;


这部分算是真正开始的地方,下一篇中我们完成该部分解读。

发布于: 1 小时前阅读数: 6
用户头像

Fenngton

关注

明天取得的所有成就, 都源于今天的不将就 2019.06.18 加入

Android音视频开发者; 致力于交流和学习音视频相关内容。 知乎专栏:《音视频学习》

评论

发布
暂无评论
音视频学习--X264码率控制起航