转载自:http://vistb.net/2012/02/x264-video-compress-intro/

 

H264编码是目前最为先进的视频编码技术标准之一,能在较小的体积的情况下提供较高的视频质量。尤其是最近一两年来,随着电脑的性能的提升和蓝光的普及,H264已经成为压制蓝光和BDRIP的标准,形成了和一般用DivX或Xvid压制的DVDRIP均分天下的形势。未来几年,随着蓝光的进一步普及和DVD的逐渐淘汰,H264应该会成为视频编码领域内的大哥大。最近一段时间本人正好在用x264压制一些影片,就顺便简单介绍一下如何使用H264编码压缩蓝光原盘的视频部分。

首先下载安装编码器。x264是一个开源的H264编码器,对于Windows用户,可以直接在这里下载可执行程序(encoder下的32bit-8bit-depth即可)。对于Linux用户,可以先查查自己的发行版是不是已经预装了x264,或者是不是可以直接安装x264的二进制文件。如果想自己编译,我们可以在VideoLAN上下载源代码,然后按照相应的说明进行编译。需要注意的是,在Linux上进行编译,最好先预装yasm汇编器(以便x264能直接产生一部分汇编代码,更好的发挥CPU的性能提高编码速度)。另外,为了能够让x264直接解码各种视频文件(因为x264首先需要解码输入文件,然后才能进行编码),还需要libswscale/libavformat或者ffmpegsource这两个库中的至少一个。前一个由ffmpeg直接提供,后一个是在ffmpeg的基础上再进行了一些封装(但也依赖于ffmpeg)。前一个库(也就是lavf)在解码中会输出一些详细信息,方便用户及时发现源视频中是否有什么问题;后一个库(也就是ffms)并不会输出什么信息,但会提示用户所需的剩余时间。简单来说,各有所长吧,大家可以按需选择,反正功能性方面是没有什么巨大差别的。

下载或者编译完成以后,大家可以使用“x264 –version”命令查看一下是不是具有lavf和ffms库,我的输出如下。可以看见,这两个库我都有了。

x264 0.120.x
(libswscale 2.1.0)
(libavformat 53.24.2)
(ffmpegsource 2.17.0.0)
built on Jan 29 2012, gcc: 4.4.5
configuration: --bit-depth=8 --chroma-format=all
x264 license: GPL version 2 or later

接下来就是压制视频了。压制视频时x264有以下几个我觉得比较重要的选项:

  • -o:指定输出文件名
  • –preset:指定编码的配置。x264编码算法有很多可供配置的参数,不同的参数值会导致编码的速度大相径庭,甚至可能影响质量。为了免去用户了解算法,然后手工配置参数的麻烦。x264提供了一些预设值,而这些预设值可以通过preset指定。这些预设值有包括:ultrafast,superfast,veryfast,faster,fast,medium,slow,slower,veryslow和placebo。ultrafast编码速度最快,但压缩率低,生成的文件更大,placebo则正好相反。x264所取的默认值为medium。需要说明的是,preset主要是影响编码的速度,并不会很大的影响编码出来的结果的质量。压缩高清电影时,我一般用slow或者slower,当你的机器性能很好时也可以使用veryslow,不过一般并不会带来很大的好处。
  • –tune:提示x264输入影片的类型,帮助x264更好的编码。常用的有film和animation两个。如果你的片源是真人电影,可以使用film,如果是动画片一类的,可以使用animation。另外,如果你的片源大部分是相对静止的图像,也可以选用stillimage。
  • –crf:这是最重要的一个选项,用于指定输出视频的质量,取值范围是0-51,默认值为23,数字越小输出视频的质量越高。这个选项会直接影响到输出视频的码率。一般来说,压制480p我会用20左右,压制720p我会用16-18,1080p我没尝试过。个人觉得,一般情况下没有必要低于16。最好的办法是大家可以多尝试几个值,每个都压几分钟,看看最后的输出质量和文件大小,自己再按需选择。
  • –video-filter:可以用来裁剪和缩放视频。裁剪视频部分的语法是“crop:left,top,right,bottom”,四个参数分别制定左侧、上侧、右侧、下侧裁剪几个像素,最好是都用4的整数倍,例如“crop:8,8,8,8”。缩放视频的部分的语法是“resize:[width,height][,sar][,fittobox][,csp][,method]”。比较重要的只是width/height和method,用来指定缩放后的分辨率和缩放使用的方法,其他参数的具体含义可以参看此处。例如“resize:1280,720,,,,spline”,指定缩放视频原始视频到1280*720分辨率,缩放的方法采用spline(一般都使用这个方法)。最后,裁剪和缩放视频其实是可以一起指定的,用“/”连接这两部分就行,具体可以看我下面的例子。

其他一些也可能用到的选项是:

  • –level:x264压制视频时会用到很多技术,有的技术可能在有的设备上不被支持。这个选项就可以在输出的视频文件中做一个标识,表明一下解码视频需要解码器支持哪些特性。一般来说,现在的设备都支持Level4.1,因此这个值一般可以选4.1。
  • –fps:指定输出文件的帧率。一般来说没有必要指定。如果你确定自己需要指定的话,可以使用浮点数形式指定或者分数形式指定。例如取值“23.976”或“24000/1001”
  • –demuxer:指定解码器。例如,通过这个选项你可以在“lavf”和“ffms”这两个基本等价的解码器之间强制让x264使用一个。

下面写两个例子:

  • x264 –preset slow –tune animation –crf 18 -o output.264 input.mp4
  • x264 –demuxer ffms –preset slower –tune film –crf 20 –level 4.1 –fps 23.976 –video-filter crop:8,8,8,8/resize:1280,720,,,,spline -o output.264 input.mp4

这里还要特别谈谈隔行扫描视频的转换,也就是诸如1080i这样的视频的转换。貌似x264本身不能很好的进行反交错处理,尤其是在要缩放原始视频的时候(比如说用1080i压制720p)。这时我们需要使用ffmpeg来解码并进行反交错,然后再调用x264进行编码(前提是ffmpeg编译时必须打开了–enable-libx264这个选项,也即链接了x264的编码器)。下面给出一个例子:

  • ffmpeg -i input.mp4 -an -sn -r 29.97 -s 1280×720 -vf yadif -vcodec libx264 -preset slow -tune film -level 4.1-crf 18 output.264

其中,“-an”指定不输出音频,“-sn”指定不输出字幕,“-r”指定输出帧率(隔行转成逐行通常用29.97),“-s”指定输出分辨率,“-vf yadif”指定使用yadif进行反交错,“-vcodec libx264”指定用x264进行视频编码,后面的应该都很熟悉了。

最后提醒一句,x264仅仅只是一个视频编码器,编码好视频后,我们还需要提供音频(甚至字幕等),最后再用混流器(如tsmuxer、ffmpeg、mkvmerge等) 混流生成最后的影片。