x264 - 高品质 H.264 编码器

标签: none

H.264 / MPEG-4 AVC 是优秀的视讯编码格式
就目前已成熟的视讯编码格式而言,H.264的压缩率是最佳的。
压缩率极高,可以只用很低 bitrate 提供堪用画质。

而 x264 为免费开放原始码的 H.264 / MPEG-4 AVC 编码器,
是目前编码效率最高的开放原始码 H.264 编码器。

此文只是基础知识,说明只是大略而已。

H.264: Wiki
x264: 官网Wiki

索引:
.#1F: 下载、基本参数设定
.#2F: GUI - 图形接口 工具接口介绍
.#3F: CLI - 命令列接口 使用教学
.#4F: CLI - FFmpeg with libx264
.#5F: 其他 x264 (CLI) 编译版
.#6F: 常见设备的相容编码参数

H.264 Profiles

Baseline Profile (BP)
主要用于低成本应用,对播放设备的性能要求不高,此 profile 常见用于早期性能较低的行动设备 (如 Apple iPod)。现今行动设备性能比起以前强大许多,此 profile 已经没有什么必要性了。

Main Profile (MP)
此 profile 原本是用于 SD 分辨率数码电视广播,虽然没有实行,然而被用于 HD 分辨率的电视广播。在 2004 年 High Profile 被开发之后,此 profile 已经没有什么必要性了。
早期的高性能行动播放设备(如 Sony PSP),也是使用此 profile。

High Profile (HiP)
目前使用最广泛的 profile,由其是 HD 分辨率电视应用 (如 Blu-ray / AVCHD 光盘储存、游戏机等电视多媒体播放器、HDTV DVB 广播服务)。
现今的行动播放设备都可以流畅播放用此 profile 的 SD 分辨率影片,中阶等级可以上 720p 分辨率,高阶甚至可上 FullHD (软解可能会有点吃力,硬解完全没问题)。

High 10 Profile (Hi10P)
超越目前主流的消费型产品能力,此 profile 建立在 High Profile 之上,多了支援 10 bit 的精度,色彩更精准。
以影片压制而言,将 High Profile (8 bit) 影片重新编码输出为 H.264 High 10 Profile ,虽然色彩精度不会变,但至少压缩率比输出 High Profile (8 bit) 还要高。

High 4:2:2 Profile (Hi422P)
针对专业领域应用,此 profile 建立在 High 10 Profile 之上,多了支援 4:2:2 色彩取样,位元深度达 10 bit。

High 4:4:4 Predictive Profile (Hi444PP)
此 profile 建立在 High 4:2:2 Profile 之上,多了支援 4:4:4 色彩取样,位元深度达 14 bit,并且支援高效率无损重新编码,且每张画面编码为三个独立的色彩平面。

ps. 目前 x264 的 H.264 Hi444P 仅支援 8-10 bit

详细资料(Wiki)

H.264 Frame

影片是由许多连续的 Frames 所组成,但并不是所有 Frames 都是完整的画面,那些 Frames 需要参考其他 Frames 才能解码出一张完整的画面。

H.264 的 Frame types 有 I、B、P 三种。

I-frame:
不需要参考其他 Frames,是一张完整的画面。

I-frame (IDR):
不需要参考其他 Frames,是一张完整的画面。
IDR frame 为真正的 关键划格 (keyframes),
P-frame & B-frame 不会越过 IDR frame 去参考其他 Frames,
所以可以随意跳转到任意 IDR frame 开始播放/解码,而不会发生问题。

P-frame:
只纪录了与之前的 Frames 相异的区块,最多可以参考 "16 张" 之前的 Frames
播放/解码时需要参用到之前的 Frames 的部分资料,才能解码出完整画面。
在 x264 中,你不能控制 P-frame 数量,但你可以控制一个 P-frame 所能参考的 Frame 数量,
也就是 Reference frame (ref) 的数值。

B-frame:
只纪录了与前一张与后一张的 Frames 相异的区块,压缩率高(由其是在低动态/低变化的影片),
播放/解码时需要用到前后两张的 Frames 的部分资料,才能解码出完整画面。

(登入后即可检视图片)
从此图你可以发见 B-Frame 有用到前一张与后一张 Frame 的资料。

播放 Farme 的顺序是依照 Frame 的时间点,但解码顺序则不一定,
当 B-Frame 有用到后一张 Frame 的资料时,就必须预先解码后一张 Frame。
以上图为例
解码(处理)顺序: 1-2-4-3
显示(播放)顺序: 1-2-3-4

由于 P-/B-frame 不是完整的画面,解码时必须参考其他 Frames,
所以你不能随意跳转到 P-/B-frame 上播放/解码。
也就是说你如果播放 MPEG 视讯格式,当你跳播放时间点时,
正常而言,并不会跳到你所选的时间点上,而是最近的 IDR / I-frame。

就压缩率而言...
由于 P-/B-frame 并不是完整的画面,所以占用的资料量较少,
提高这类 Frame 使用量可以有效提升压缩率,但对画质几乎不会降低,
这代表可以使用较少的 bitrate (位元率)达到维持一定画质。

由以上得知,在 bitrate 充足的情况下,则不需要使用较多 B-frame、Reference frame (ref) ,
多少 bitrate 为充足依影片内容为定,高动态影片需要较多 bitrate,低动则较少。

至于使用时机...
提高 B-frame/ref 使用量可以降低 bitrate 的需求,使用较少 bitrate 达到目标品质。
低动态的影片可以使用较多的 B-frame,高动态或是纯静态则是 P-frame 效果较好。

对于相容性与硬件负担...
提高 B-frame/ref 使用量的副作用是降相容性以及提高硬件负担,请先保证相容性再来追求压缩率。
而 ref 的副作用要比 B-frame 强,例如 ref=16 这代表解码一个 P-frame 必须要连跳回 1~16 张之前的 Frames 取用资料。

x264 参数设定

Maximun B-frame:
当设定 B-frame 时,重复部分比较多/变化较少的 Frames 会被编码为 B-frame
此值限制 B-frame 的最大连续数量。

Reference frame (ref):
设定一个 P-frame 所能参考的 Frames 数量。
ref 会影响播放相容性,请参考下文 H.264 Level 部分

推荐设定
‧Reference frame (ref): 3 - 5
‧Maximun B-frame: 3 - 6

GOP 长度:
一个 keyframe (IDR frame) 到下一个 keyframe 的范围。
所以将 GOP 设为无限大虽然可以大幅增加压缩率,但这样就不能随意跳转到其他时间点播放/解码。
建议维持 default 即可。

H.264 Profile (x264)

Profile 越高 压缩率 也越高,但编码复杂度也越高,对播放硬件性能要求较高

x264 支援输出的 H.264 Profile:
baseline, main, high, high10, high422, high444

没有特殊需求使用 High Profile 即可。

无法直接指定输出 Profile 的话,可以手动设定参数值。

H.264 Profile 对应的参数

ps. 空字段代表无限制
完整表格(Wiki,下拉至 Profiles 底部)

参数说明:

bframes (Number of B-frames):
设定 I-frame P-frame 之间连续 B-frames 的最大数量。

cqm (custom quantization matrices):
设定所有自订量化矩阵(custom quantization matrices)为内建的默认之一。内建默认有 flat 和 JVT。

weightp (explicit weighted prediction):
使 x264 能够使用明确加权预测(explicit weighted prediction)来改善 P-frame 的压缩率。亦改善淡入/淡出的品质。模式越高越慢。

8x8dct (Adaptive 8x8 DCT):
弹性 8x8 离散余弦转换(DCT)使x264能够弹性使用 I-frame 的 8x8 转换。

cabac (CABAC: Context Adaptive Binary Arithmetic Coder):
弹性内容的二进制算数编码资料流压缩,禁用 CABAC 会切换回效率较低的弹性内容的可变长度编码(CAVLC:Context Adaptive Variable Length Coder)系统。大幅降低压缩效率(通常10~20%)和解码的硬件需求。

interlaced:
支援编码输出 interlaced 的视讯。

x264 preset

Preset 是一个选项集合,这设定一编码速度来决定压缩比。速度越慢则会得到更好的压缩编码效率 (画质-位元率比 或 画质-档案大小比)。也就是说,若你设定一个目标位元率或是档案大小,则越慢的 Preset 将会得到更好的输出品质。而对于设定一个恒定品质 (CRF) 或是恒定量化值 (QP),你可以透过选择更慢的 Preset 来简单的节省位元率 (也就是得到更小的档案大小)。

一般而言是使用你所能忍受的最慢 Preset。目前 Presets 依速度递减排序是: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, placebo。该默认 Preset 是 medium。忽略 placebo 因为它会比 veryslow 浪费更多时间而且效果差异太小。

而越慢的 Preset 其 Reference frame (ref) 值也越高,例如 veryslow preset 的 ref 为 16。由于通常不需这么高的 ref,你可以透过指定一个 Level 来限制 ref,或是手动指定一个合理的 ref 值 (1 ~ 6)。

x264 tune

针对特定类型的影片微调参数设定值,以获得更好的品质或压缩率。

Film (电影): 胶片电影、真人类型。
Animation (动画): 例如卡通/日本动画。
Grain (胶片颗粒): 颗粒感很重的影片。需要保留大量的grain时用
Still Image (静止影像): 例如幻灯片效果的影片。静态图像编码时使用
PSNR: 优化 PSNR 值。 Wiki为提高psnr做了优化的参数
SSIM: 优化 SSIM 值。 Wiki为提高ssim做了优化的参数
Fast Decode (快速解码): 用于低性能播放设备。可以快速解码的参数 (※ 压缩率极低)
Zero Latency (零延迟): 处里时间低延迟。主要用于直播等。用在需要非常低的延迟的情况下,比如电视电话会议的编码。 (※ 压缩率极低)

H.264 Level

Level 、 MaxDpbMbs 直接表示了对播放设备的解码性能要求
值越高,代表播放设备解码性能要求越高,相对的输出影片的压缩率也越越高

MaxDpbMbs 对应的 Level

举例说明:
Level 3.2: MaxDpbMbs 20480 以下
Level 4.1: MaxDpbMbs 32768 以下

关系方程式:

强制指定 Level (限制 MaxDpbMbs),则
ref = Min(Floor(MaxDpbMbs / (PicWidthInMbs * FrameHeightInMbs)), 16)

ps. 1. Floor(x): 取整数,小数码直接舍去。 ex. Floor(1.9) = 1
ps. 2. Min(x, y): 取比较小的数值。 ex. Min(2, 5) = 2

强制指定 ref,则
MaxDpbMbs = PicWidthInMbs FrameHeightInMbs ref

PicWidthInMbs = Width / 16
FrameHeightInMbs = Height / 16
(小数直接进制)

举例 1:
当我设定输出为
‧Resolution: 1280x1720
‧Level: 不指定(自动)
‧Reference frame (ref): 4

则 MaxDpbMbs = 80 45 4 = 14400
对照上表,得 Level = 3.1

举例 2:
当设定输出为
‧Resolution: 1280x1720
‧Level: 3.1
‧Reference frame (ref): 不指定(自动)

ref = Min(Floor(18000 / (80 * 45)), 16) = Min(Floor(5.0), 16) = Min(5, 16) = 5

则输出 H.264 的 ref 可能为 4 或 5

同上,如果要同时强制指定 ref 与 level
则 ref 设定值不能大于 5
(强制指定 ref 不能大于 Level 的限制)

详细说明(Wiki)

x264 Bitrate Control

指定输出品质: QP (VBR) 、 CRF (VBR)
指定输出 Bitrate / 档案大小: Single pass (ABR) 、 2-pass (VBR)

通常只会使用两种速率控制: Constant Rate Factor (CRF) 或 2-Pass Bitrate。速率控制是指决定多少位元将被用于每个划格的方法。这将决定档案大小且品质如何分布。而 CRF 的位元率分配效果是最佳的,若无控制输出大小的需求则使用 CRF 即可。

Constant Quantizer (QP)

设定x264以恒定量化值(Constant Quantizer)模式来编码视讯。此方法可以让每一个划格获得相同品质 (设定值)。
设定值范围为 0–69,0 为最无损,默认值为 23。比较低的数值会得到比较高的品质,合理的范围 21 - 28。

Constant Ratefactor (CRF)

此方法允许编码器自动分配位元速率来试着达到一定输出品质。让每个划格得到它需要的位元数来保持所需的品质等级。CRF 会得到最佳的位元速率分配结果,缺点是你不能直接指定一个目标位元率或是档案大小。
设定值范围为 0–51.0,0 为最高品质,默认值为 23。比较低的数值会得到比较高的品质,合理的范围 18 - 28。考虑 18 为视觉无损 (或接近),所以它看起来应该与输入相同 (或接近) 但它技术上不是无损。

Bitrate

自订 Bitrate 控制输出 Size,直接编码输出视讯。由于没有先扫描过一次,x264 无法得知影片各时间点的复杂程度。所以 x264 只能在编码中不断猜后之后的复杂程度,这样将不能精准依各时间点的复杂程度等比例分配位元率,因为如果之前分配了过多流量,那么之后就必下修流量来使输出位元率平均值等于使用者设定值。

Bitrate, 2-Pass

此方法令编码器 1st-Pass 将会得知影片各个划格的复杂程度,2nd-Pass 时依照输入视讯各个划格的复杂程度等比例分配位元数输出,并且最终平均位元速率会等于设定值。2-Pass 位元速率分配结果会接近 CRF,缺点是耗费大量时间。

1st-Pass CRF + 2-Pass Bitrate

此方法令编码器在 1st-Pass 时将会得知影片各个划格所需要的位元数,2nd-Pass 时依照各个划格所需要的位元数等比例分配使最终位元速率总平均值会等于设定值。2-Pass 位元速率分配结果会接近 CRF,缺点是耗费大量时间。

x264 设定优先级

preset -> tune -> 使用者设定选项 -> fast first pass -> profile -> level

当参数冲突时,后者会取代前者或是影响前者

preset slower 的参数为:
--b-adapt 2 --direct auto --me umh
--partitions all --rc-lookahead 60
--ref 8 --subme 9 --trellis 2

当我设定:
‧ x264 Preset: Slower
‧ Reference frame (ref): 4

等同于:
--b-adapt 2 --direct auto --me umh
--partitions all --rc-lookahead 60
--ref 4 --subme 9 --trellis 2

输出 H.264 的 Reference frame (ref) 为 4

当我设定
‧x264 Preset: Slower
‧Level: 3.2

输出 H.264 的 Reference frame (ref) 为 5
(请参考上文 "H.264 Level" 部分)

基本用法

基本语法:
x264 [设定选项] -o <输出> <输入>

可以用 raw 输入,
或 YUV4MPEG (*.y4m)
或 Avisynth (*.avs, 需要有支援的编码版)
或 lavf / ffms 支援的输入格式

依指定附档名选择输出档案格式:
.264 -> Raw bytestream
.mkv -> Matroska
.flv -> Flash Video
.mp4 -> MP4 (需要有 GPAC 的编译版)

Piping

64bit的x264
如果用了64位的Windows,就可以用64位的x264。64位的x264大约能比32位的x264快上10%左右,能节省的时间还是比较可观的。但是用AviSynth输入时,64位的x264只接受64位的AviSynth输入,32位的x264只接受32位的AviSynth。虽然现在有64位的AviSynth和不少常用的滤镜,但是大多数人还是愿意用32位的AviSynth。那么如何用让64位的x264配合32位的AviSynth呢?

方法是用pipe。用命令行工具(如ffmpeg、mencoder或avs2yuv)打开avs,让输出的raw yuv画面直接输入给x264,期间不产生中间文件。这个操作也是在命令行里实现的。

用ffmpeg输入
先下载ffmpeg的Windows编译版,可以用static link版本。和x264一样,ffmpeg放在任何目录里都能运行,假设和x264、要进行编码的input.avs放在一个目录里。

>ffmpeg -i input.avs -f yuv4mpegpipe -an -v 0 - | x264 [options] --demuxer y4m -o output.264 -

先用ffmpeg打开input.avs,并不指定输出的文件,而是以-代替输出的文件。后面写|,再写x264,x264的选项和输出文件写法不变,但是输入文件写-

用mencoder输入(未测试)
mencoder有很多有价值的滤镜,用起来也很方便。libx264可以编译进mencoder本身,和单独的x264效果一样。mencoder也可以打开avs文件,pipe给64位的x264。mplayer-ww的命令行版里就带有mencoder。

同样假设mencoder、x264和要编码的的input.avs(1280x720)在一个目录里。

>mencoder input.avs -vf format=yv12 -of rawvideo -ovc raw -nosound -o - | x264 [options] --input-res 1280x720 --input-csp yv12 -o output.264 -

用avs2yuv输入
avs2yuv本来是为了给linux上wine来用的,因为AviSynth是运行在Windows的,在linux里必须wine avs2yuv来打开avs,再pipe给x264。当然也可以用来pipe给64位的x264。
同样假设avs2yuv、x264和要编码的的input.avs在一个目录里。

>avs2yuv input.avs - | x264 [options] --demuxer y4m -o output.264 -

avs2yuv的输出格式默认是yuv4mpeg,x264用y4m格式解码即可从中读取分辨率,所以无须再用--input-res指定分辨率。

以上介绍了3种方法,个人比较倾向于用ffmpeg。2pass的编码也是像上面所讲的方法一样。

X264使用介绍 关于pipe
x264 - 高品质 H.264 编码器


扫描二维码,在手机上阅读!

添加新评论