x264_Encoding_Suggestions

=X264编码建议=

toc

常用提示

 * 别拿x264作为降噪滤镜的替代品. 确保输入与你想要的输出看起来一样(忽略压缩导致的质量损失). 否则会降低x264的运行效率.
 * 若编码时CPU占用率达不到100%，问题八成出在输入上：
 * Raw YUV输入很容易受IO速度的限制，raw输入的一帧体积大小=宽*高*位深(YV12为12) / 8(bits -> bytes) / 1024 (bytes -> kbytes) /1024 (kbytes -> mbytes)
 * Avisynth脚本运行于单线程，有些滤镜可以使用多余的线程，但速度增益不大.
 * ffmpeg (即ffms2)在x264中只支持单线程解码.
 * Flash h.264解码器 [|(及其它)] 不支持加权P帧预测(weighted P-frame prediction)--weightp，直至10.1版本，但截止至本文写成时，该版本目前使用率还不广. 若目前使用率还不广，则在编码Flash时，需设置
 * Apple的QuickTime播放器有诸多解码问题，特别是涉及到参考帧数目时. 若想保持对QuickTime的兼容性，请参考QuickTime编码建议，毕竟苹果用户数量庞大.

命令行使用建议
x264设置可分为三类： 1. **需要直接设定的** 如 --bitrate, --keyint, --slices等等. 取决于输出系统的要求，因此x264的预设会忽略这些设置. 2. **应该通过预设(preset)来设定的** 预设系统出现之前，编码者需要输入一大段代码，手工指定每一个参数. 很多人争论是--subme 搭配--me  好些，还是--subme --me --preset, --tune和--profile就好了. 3. **应该无视的** --qcomp, --scenecut等等. 这些设定早该内部设定死了. 它们对于现在的命令行来说，除了让人头疼外，根本毫无意义. 疯狂调冷门参数，觉得有用的人，省省吧.

VBV编码
x264中的VBV (视频缓冲验证Video Buffer Verifier)系统用于限制输出码率，以适用于低带宽环境下的流媒体. h.264的VBV模型基于解码端"VBV缓冲"的理念. h.264流由客户端下载保存于VBV缓冲内. 每一帧必须完整下载入缓冲中，方可解码. x264有三种控制VBV缓冲的选项： 使用VBV时，只需设置1和2项，永远不需要设置最后一项.
 * 1) 缓冲大小由--vbv-bufsize指定，单位是kbit
 * 2) 缓冲的填充速率由--vbv-maxrate指定，单位是kbit/sec
 * 3) 由--vbv-init指定缓冲必须填满一定的百分比，才可开始回放.

例 1

 * 用途:** 编码的视频用于硬盘上观看.
 * 建议:** 不要指定任何VBV设置. 硬盘的传输率足够快，无需设置VBV限制.

例 2
注：为兼容蓝光，x264还需要其它选项. 但这两项对于VBV部分的兼容，是足够了.
 * 用途****:** 编码的视频用于封装成蓝光兼容的文件.
 * 建议:** 蓝光规范限制最大视频码率为40mbit，最大缓冲为30mbit. 所以设定

例 3
注：在线视频的启动延时不仅仅是VBV设置，上述仅是理想情况下的假设.
 * 用途****:** 编码的视频通过在线Flash流媒体播放，如Youtube
 * 建议:** 你需要视频能很快开始，所以缓冲不能超过0.5秒(大概). 假设观看者的网速需求是512kbit/sec，且90%的带宽用于在线观看，另外96kbit/sec的带宽用于音频，那么只剩下364kbit/sec的带宽给x264. 所以指定

蓝光 编码
kierank已做了详细研究，详见 [|creating Blu-Ray compliant files with x264 here]. 对于1080p的简单例子如下： code x264 --bluray-compat --bitrate X --preset veryslow --weightp 0 --bframes 3 --nal-hrd vbr --vbv-maxrate 40000 --vbv-bufsize 30000 --level 4.1 --keyint X --b-pyramid strict --slices 4 --fake-interlaced --aud --colorprim "bt709" --transfer "bt709" --colormatrix "bt709" --sar 1:1 --pass 1 -o output.file input.file x264 --bluray-compat --bitrate X --preset veryslow --weightp 0 --bframes 3 --nal-hrd vbr --vbv-maxrate 40000 --vbv-bufsize 30000 --level 4.1 --keyint X --b-pyramid strict --slices 4 --fake-interlaced --aud --colorprim "bt709" --transfer "bt709" --colormatrix "bt709" --sar 1:1 --pass 2 -o output.file input.file

code 设置keyint为帧率. 需要的话，用更快些的预设. 按需增加--tune参数. 关闭--weightp，仅因为某些硬件解码器会出问题，并非因为蓝光规范不支持.

编码延时
取决于编码设定，x264会把一些帧放进内部缓冲，以提升质量. 对于离线编码，延时无所谓. 但如果是用于广播或流媒体，此延时不可接受. 用下面的伪代码，可以计算出x264的缓冲帧数(即编码延时). 若用libx264 API，参见x264_encoder_delayed_frames code delay = 0

if b-adapt=2 and not (nopass or pass2): delay = MAX(bframes,3)*4 else: delay = bframes

if mb-tree or vbv: delay = MAX(delay,rc_lookahead)

if not sliced-threads: delay = delay + threads - 1

delay = delay + sync-lookahead

if vbv and (vfr-input or abr or pass1:   delay = delay + 1

code 降低x264的延时是可能的，但是会降低质量. 若需零延时，设置--tune zerolatency. 若你 可以接受一丁点儿小延时(如小于1秒)，最好还是允许延时. 下列步骤可以降低延迟，当延迟足够小时，就别再进行后续步骤了：
 * 1) 从初始值开始
 * 2) 关闭sync-lookahead
 * 3) 降低rc-lookahead，但别小于10
 * 4) 降低threads(比如从12降到6)
 * 5) 使用切片线程(sliced threads)
 * 6) 禁用rc-lookahead
 * 7) 禁用b-frames
 * 8) 实在不行，就用--tune zerolatency

=兼容QuickTime的编码=

对于如何编码能在QuickTime中完美播放的h.264视频，各种过时的错误信息随处可见，如“QT只支持1个B帧”、“QT不支持pyramidal B帧”两条，对于Quick Time Player 7.7就已不正确了. 早期版本的Quick Time Player还曾有一个qpmin/dct的问题，令播放器不能处理低量化值(小于4)结合8x8 DCT Transform，然而此问题已在Quick Time Player X中修复.

兼容QuickTime Player X
Apple发布的QuickTime Player X中的h.264解码部件是个很不错的解码器，只有一个大问题没解决. 你也许很奇怪，那些只能用老版本播放器，或是拒绝升级至QTX的用户怎么办？其实不必担心，因为OS X系统全局（包括QuickTime）所用的解码器并不是播放器自带的解码部件. 此全局解码器会随着系统的更新包而自动更新，无需用户更新QuickTime Player. 所以，当我们提到QuickTime Player X时，自动假设只要系统为10.6 Snow Leopard或更高版本，则自带了已修正了的Apple h.264解码部件，哪怕用户没有安装QTX. 现在，Apple h.264解码器还存在的唯一的大缺陷： 解决办法：
 * 较高的参考帧数（15或更高）结合较高的B帧，会导致画面出现马赛克及变形. 此问题在使用"veryslow" preset时会遇到，因为它使用了16个参考帧.
 * 将参考帧数目限制在1-14范围内. 查找对于所需h.264 level及分辨率所对应的可接受的参考帧数量，然后保证该值不超过14. 不过，使用超过5个参考帧就意义不大了，且4个参考帧是1080p视频最常见level所允许的最大值，因此不妨选择4个参考帧来编码你你所有的视频，不论分辨率：--ref 4 （对于编码Level 5以上的视频，你可以参见各level所需，挑选高一点的值，但不要超过14）.

兼容QuickTime Player 7.7
任何版本的操作系统，若有“安装QuickTime Player X”的选项，就会拥有已更新的QTX解码器. 不幸的是，这意味着只包括OS X 10.6 Snow Leopard及更高版本系统的用户. 所以，若想让10.5 Leopard的用户能播放你的视频，你就要再阅读下边的内容了，因为他们只能用QuickTime Player 7.7. 不过，Leopard用户已经小于<10%且不断减少中，你也许不必在乎他们了. 但话说回来，想要兼容他们老旧的Apple h.264解码器也很容易，只需稍微牺牲一点质量，你八成会觉得这么做值得. 解码器缺陷： 解决办法：
 * 低量化值(小于4)结合8x8 DCT Transform在QuickTime Player 7.7及更低版本中会产生错乱的解码结果.
 * 设置--qpmin 4，以防止编码器使用更低的量化值. 会造成极小的质量损失，但远远好过禁用8x8 DCT.

结论
网上别处看来的全都无视，那些信息极其老旧，早已不属实多年了. 兼容QuickTime最简单的建议：结合上述两个解决办法，最大化兼容性，令10.5 Leopard及更高版本的用户都能完美播放，这样就覆盖了99%的Mac用户. 非想要让所有Mac用户都能播放的话，就用--ref 4 --qpmin 4来编码所有视频.