摘要:
本文作为“x264视频编码器应用与实现”系列博文的第二篇,主要讨论使用 x264 编码器的二进制可执行程序进行视频编码所需的参数和常用配置。
一. x264 编码基本命令格式
如本系列的第一篇博文中所述,x264 为 H.264 编码器的一种有效的工程实现,因此其主要的功能即为将像素格式的图像信息编码为符合 H.264 标准格式的二进制码流。x264 项目提供了二进制可执行程序形式的编码器命令行工具“x264”和动态或静态库形式的编码 SDK “libx264”,二者各有各自的优劣。从使用方便的角度,使用命令行工具形式的编码器工具更加便捷,因此本文首先以该编码器工具为例,讨论 x264 编码的命令格式和基本参数配置。
如同其他在终端或命令行中执行的工具(如 git、homebrew 或 ffmpeg 等)一样,执行 x264 的编码操作同样采用 “x264 -x param” 的形式实现,其典型格式如下:
1 | x264 [options] --output output.h264 inputfile.yuv --input-res width x height |
例如,如果我们希望将大小为 1280×720 的 YUV 图像序列按照指定质量、浮动码率的设置编码为 H.264 格式输出码流,则可采用以下格式:
1 | x264 input_1280x720.yuv —input-res 1280x720 —crf 24 -o output.h264 |
如果希望指定输出视频流的码率,采用浮动质量,则采用以下格式:
1 | x264 input_1280x720.yuv —input-res 1280x720 —bitrate 500 -o output500.h264 |
实际上,x264 还支持更多更复杂的参数配置,以实现更加复杂的编码操作,常用的具体参数将在下文中详述。
二. x264 编码帮助文档
由于 x264 中定义的编码参数众多,我们无法简单地将其全部记住,因此需要频繁查阅编码帮助文档。通过 x264 的可执行程序可轻易获取官方的帮助文档的内容,即通过以下命令:
1 | x264 -h #或者 x264 --help |
以上命令获取的只是简单的帮助信息,如果希望获取更加详细的参数文档可通过以下命令:
1 | x264 --longhelp #或者 x264 --fullhelp |
由于内容过多,通常建议将完整的参数文档保存到本地文件供日后查阅:
1 | x264 --fullhelp >> ./x264_help.txt |
三. x264 编码参数配置
通过查看 x264 提供的完整帮助文档,我们可很容地看出,x264 支持的各种参数可按照功能分为几大类,具体分类如下:
- 编码预设参数:将多个不同参数按照预定义的编码场景进行组合,作为一个参数提供;
- 编码帧类型:指定 x264 编码某一帧或部分帧的类型;
- 码率控制:设置编码器的码率控制参数;
- 编码分析:可对编码过程的内部参数进行微调;
- VUI 信息:指定输出码流的 VUI;
- 输入输出参数:指定编码器的输出输出文件及其类型等信息;
- 编码滤镜:支持在编码过程中对视频信息进行一定编辑;
3.1 x264 的编码预设参数
x264 中定义了多种编码预设参数,其主要意义为适应某一种常见的场景,将一组参数整合为某一个模式,方便用户使用,因此编码预设参数也是使用 x264 进行视频编码是最常用的选项,多数时候都会设置一个或以上的预设参数进行编码。
x264 中的编码预设参数总体上可分为以下几类:
- profile:编码器生成H.264码流的档次,对应部分 H.264 标准所规定的档次;
- preset:速度 vs 质量的参数集合;
- tune:“音调”,即为某个特殊场景预设的参数集合;
- slow-firstpass:在2 pass编码中禁用 1 pass 编码加速;
3.1.1 x264 编码档次
在 H.264 中定义了编码的档次 Profile,表示一组编码算法的集合,以及对编码参数施加的一定限制。在 H.264 标准中定义的档次主要有以下几项:
- baseline; constrained baseline;
- main; extended;
- high; high10; high422; high444predictive;
- high10intra; high422intra; high444intra; cavlc444intra;
在 x264 中可配置的 profile 参数并未支持 H.264 中的所有配置,仅实现了其中若干个最常用的选项。通过帮助文档可知,x264 可设置的编码 profile 有 baseline、main、high、high10、high422、high444 六种:
1 | --profile <string> Force the limits of an H.264 profile |
3.1.2 x264 编码预设模式
在 x264 中实现了多数 H.264 定义的编码技术,并提供了多种参数对其编码过程加以控制,其中部分参数设置提升了编码性能但同时提升了运算复杂度,另一部分参数设置优化了编码速度但是牺牲了编码性能,因此如何对各种参数加以组合使用以求更加满足不同场景下编码的需求至关重要。如果所有参数都必须由用户手动定义,不仅十分不便,而且容易出现设置错误导致无法发挥编码器原有的性能。
为了方便用户更加有效地使用,x264 定义了若干个编码预设模式 “preset”,以满足不同场景下的编码速度和 CPU 占用率与压缩性能的平衡。在帮助文档中 x264 定义了10种不同的 preset:
- ultrafast; superfast; veryfast;
- faster; fast; medium;
- slow; slower; veryslow; placebo;
其中,ultrafast 模式下编码速度最快但压缩性能最低,placebo 模式下压缩性能最高但编码速度最慢。x264 默认的编码预设模式为 medium 模式。每一个模式的背后都代表了一系列的参数设置,通过这些设置的组合实现对编码过程的影响,具体对应关系有:
1 | --preset <string> Use a preset to select encoding settings [medium] |
需注意的是,当在编码时指定了某个 preset 后,该 preset 所指代的配置项可被用户自定义配置覆盖。例如指定 preset 为 “placebo” 时,默认的 “bframes” 设置为 16,此时用户可直接使用 “–bframes 8” 修改 “bframes” 的取值而不影响 “placebo” 所指代的其他参数。
3.1.3 x264 特别场景参数
为了进一步方便 x264 在部分特殊场景下的编码使用,x264 预定义了若干个特别场景参数,指代部分常见的应用场景。x264 定义的特别场景参数 “tune” 同预设模式 ”preset“ 类似,每一个配置代表了适用于一个场景的若干个配置项。x264 预定义的 ”tune“ 主要有:
- film:电影片源;
- animation:动画片源;
- grain:胶片颗粒噪声场景;
- stillimage:静态图像;
- psnr:峰值信噪比参数优先;
- ssim:结构相似性优先;
- fastdecode:优先保证解码速度;
- zerolatency:低延迟,适用于直播等场景;
与 ”preset“ 不同的是,特备场景参数 ”tune“ 所指代的配置选项的主要目的并不是对编码的速度或压缩率做出分级,而是专门针对某种场景预定义的配置选项组合。每个 ”tune“ 与配置选项的组合对应关系如下:
1 | --tune <string> Tune the settings for a particular type of source |
与 ”preset“ 类似的是,”tune“ 选项所指代的参数同样可以由用户定义参数所覆盖。
3.1.4 禁用首轮编码加速
该预设参数无任何参数,使用方法为直接在命令行中使用 ”–slow-firstpass“。顾名思义,其作用为禁用首轮编码的加速运行。其定义为:
1 | --slow-firstpass Don't force these faster settings with --pass 1: |
3.2 x264 的编码帧类型选项
这一部分配置选项决定了 x264 在编码过程中对每一帧图像的编码类型以及部分对图像帧编码过程中的参数,是 x264 编码工程应用时最常用的配置类型之一。该部分参数的选择可能对编码结果产生巨大的影响。
3.2.1 GOP 设置项
这一部分配置项决定了输出的 H.264 码流的 GOP 结构,包括 GOP 长度和场景切换设置等。常用的配置项有:
GOP 结构
通过以下参数可设置 GOP 的最大和最小长度等信息:
- -I 或 –keyint <integer or “infinite”>:设置 GOP 的最大长度,默认为250帧;可设置为任意正整数或 infinite 表示只有首帧为关键帧;
- -i 或 –min-keyint
:设置 GOP 的最大长度,默认为 auto 表示自动切换; - –intra-refresh:是否启用 Periodic Intra Refresh;
- –open-gop:是否采用开放式 GOP;
场景切换
x264 支持在编码画面内容出现场景切换时按照需要插入关键帧,通过以下参数可进行相关设置:
- –no-scenecut:禁用场景切换功能,严格按照 GOP 设置插入关键帧;
- –scenecut
:设置场景切换的强度阈值,默认为40;
3.2.2 B 帧设置
视频序列中 B 帧的引入不仅大幅提升了编码的效率,也为视频流的帧结构提供了巨大的灵活性。在 x264 中提供了多项关于 B 帧的设置项,其中常用的有:
- -b 或 –bframes
:设置 I 或 P 帧之间插入 B 帧的数量,默认为3; - –b-adapt
:自动判断采用 B 帧编码,可选值为 0、1、2,分别表示关闭、快速判决和最优判决,默认为1; - –b-pyramid
:是否采用 B 帧作为参考帧,可选值为 “none”、“strict”、”normal”,分别表示关闭、严格模式和普通模式,默认为2;
3.2.3 条带参数设置
这一系列的参数影响的是 H.264 输出码流中的 slice 结构,主要有以下几项:
- –slices
:指定每一帧包含几个 slice,可被其他选项覆盖; - –slices-max
:每一帧包含 slice 的上限值; - –slice-max-size
:每个 slice 所占字节数的上限; - –slice-max-mbs
、–slice-min-mbs :每个 slice 最多和最少包含多少个宏块;
3.2.4 其他帧或场编码设置
- -r 或 –ref
:指定编码参考帧数量; - –no-deblock:禁用去块滤波器;
- –no-cabac:禁用 CABAC;
- –tff/–bff:启用交错编码,顶场或底场优先;
- –constrained-intra:启用受限制的帧内预测;
3.3 x264 的编码码率控制选项
码率控制在视频编码实践中至关重要,决定了视频系统整体的带宽耗费和用户观看体验,其调优质量的高低通常直接影响业务的应收等指标。在 x264 中提供了多种不同的码率控制选项,既可以使用简单的配置进行粗略控制,也可以通过复杂的配置组合对码率控制得更加精细。
3.3.1 基本码率控制
使用 x264 码率控制大致可分为指定码率、指定质量和指定 QP三大类,分别可使用一个选项实现:
- -B 或 –bitrate
:指定编码视频流的输出码率,单位为 kbit/s; - –crf
:质量优先的编码率模式,默认值为 23; - -q 或 –qp
:指定恒定量化参数,可选范围为[0, 81],选择 0 表示无损编码;
3.3.2 设置编码过程的 QP 规则
在未指定固定的 QP 编码时,可设置对编码 QP 的约束条件。以下为部分常用的参数设置:
- –qpmin/–qpmax
:设置编码过程中 QP 的最小值和最大值; - –qpstep
:设置 QP 步长; - –ipratio/–pbratio
:I 帧与 P 帧之间、P 帧与 B 帧之间 QP 比例值; - –chroma-qp-offset
:色度分量与亮度分量编码 QP 的差值; - –aq-mode
:设置自适应 QP 模式,0 表示禁用,1、2、3 分别表示不同的 QP 自适应算法,默认为1; - –qpfile
:以文件的形式指定每一帧所采用的的 QP 值;
3.3.3 设置编码过程的码率和质量规则
多数时候,在使用 x264 编码时不会直接指定 QP,而是更加关注编码质量和输出码率的效果。在 x264 中提供了多种设置来控制编码的码率和质量,常用的有:
- –rc-lookahead
:帧类型前瞻预测所需的帧数,默认为40; - –vbv-init
:初始化 vbv 缓存; - –vbv-maxrate
:设置 vbv 码率上限值; - –vbv-bufsize
:设置 vbv 缓存大小; - –crf-max
:在 vbv 缓存中设置质量因子最大值(可能会导致 vbv 缓存溢出); - –ratetol
:设置码率浮动限制范围;
3.3.4 设置多轮编码的码率控制
为了对输出码率进行更加精细的控制,一个常用的操作是对同一段输入图像序列进行多轮编码,通过前几轮编码估算输出的码率并调整参数,在最后一轮中执行实际的编码操作。在 x264 中,若希望使用多轮编码可采用以下选项:
- -p 或 –pass
:设定编码轮次,可选值为1、2或3;1表示第一轮创建统计文件,2表示最后一轮根据统计文件进行输出,3表示中间轮对统计文件进行修改升级; - –stats
:指定统计文件的文件名,默认为 “x264_2pass.log”;
3.4 x264 的编码分析选项
使用这部分选项可控制 x264 在编码过程中的部分细节,如宏块划分、运动矢量预测方法和运动搜索方法等。
- -A 或 –partitions
:编码过程所支持的宏块划分方法,可选以下几种:p8x8、 p4x4、 b8x8、 i8x8、 i4x4、 none 和 all;默认设置为 “p8x8,b8x8,i8x8,i4x4”; - –direct
:直接模式下运动矢量预测方法,可选 “none”、“spatial”、“temporal” 和 “auto”;默认设置为 “auto”; - –weightp
:设置 P 帧加权预测方法,可选值为0、1或2;0表示禁用,1表示甲醛参考,2表示加权参考+复制;默认为2; - –no-weightb:禁用 B 帧加权预测;
- –me
:设置运动估计方法;可选值有 “dia”、“hex”、“umh”、“esa”、“tesa” 分别表示菱形搜索、六边形搜索、非对称多六边形搜索、完全搜索和 Hadamard 完全搜索,速度由快及慢;默认为 “hex” 即六边形搜索; - –merange
:设置运动矢量搜索最大范围,默认为16; - –mvrange
:设置运动矢量最大长度,默认为 -1,表示自动设置; - -m 或 –subme
:亚限速运动搜索与模式判决方法,可选值为[0, 11],取值越高,运动搜索约复杂;默认值为 7; - –no-chroma-me:禁用色度分量的运动估计;
- –no-8x8dct:禁用变换编码的自适应变换块大小;
3.5 x264的编码输入输出选项
在 x264 编码时,输入输出选项不仅用于指定输入和输出文件名,而且可以指定如输入图像大小、编码帧数、输入图像格式和日志级别等信息。
- -o 或 –output
:指定输出文件路径; - –muxer
:指定输出文件的容器格式,可选值有 “auto”、“raw”、“mkv” 和 “flv”,默认为 “auto”; - –demuxer
:指定输入文件的容器格式,可选值有 “auto”、“raw”、“mkv” 和 “flv”,默认为 “auto”; - –input-csp
:指定输入 raw 格式图像的颜色空间类型,可支持 “i400”、“i420” 等15种; - –output-csp
:指定输出视频流的颜色空间类型,可支持 “i400”、“i420”、“i422”、“i444” 和 “rgb” 5种,默认值为 “i420”; - –input-depth
:指定输入 raw 格式图像的位深; - –output-depth
:指定输出视频流的图像位深; - –input-res
:指定输入数据的宽高; - –fps <float|rational>:指定编码帧率;
- –frames
:指定最大编码帧数; - –level
:指定输出码流的级别; - -v 或 –verbose:逐帧输出详细的编码信息;
- –quiet:开启静默模式;
- –log-level
:设置输出日志的级别; - –psnr/–ssim:编码过程中开启 PSNR 和 SSIM 计算;
- –no-asm:禁用汇编指令集优化