MP4介绍与基本AVC编码(x264)教程(最后更新: 2006.03.25)
为日益增加的对MP4 H264/AVC编码的需求,本人做了一个简单的MP4介绍与基本AVC编码(使用x264)教程
最后更新日期:2006年3月25日
注×:这是本人第一次写这样的教程,知道的也不是很多,所以里面肯定会有很多错误,请内行多多指正,我好及时更新省得误人子弟。
首先简单介绍一下MPEG是什么: MPEG是Motion Picture Expert Group的缩写,简单讲就是个行业里的组织,专门对数字内容做出业界规范的组织。其实从MPEG1开始我们就广泛认识到这个组织和他们的标准了。VCD就是其中最主要的代表。在当时亚洲国家VCD格式十分流行,如果没记错VCD这个具体的格式是从日本而来的,并遵守MPEG1规格。 之后便是MPEG2,具体代表是DVD。知道现在都是主流数码格式。 说道这里大家应该开始明白MPEG这个组织其实他的责任就是推广每一代新的数字媒体规范或是规格,而不是实际的产品。换句白话就是说,*来规定符合什么样标准的汽车可以上路,然后各个汽车公司按照这个具体的标准来制作自己的汽车,通过*规定的汽车才可以上路。张三李四都可以开发自己符合mpeg规格的codec和container(这个是什么我之后会解释),并且理论上拿到别人同样按照这个规格开发的产品上照样可以工作。具体例子就好比制作DVD的方法千千万万,好莱坞用来做大片,个人也可以把自家拍的DV刻成DVD。理论上讲都可以在放在任何DVD机里播放(这里不考虑个别不兼容问题)。这也是为什么明明XVID编码的dvdrip大家用ffdshow也可以照样看。所以说这就是规格统一的好处!!
说了这么多转入正题:我们要讨论的MP4格式。从名字就可以看出来她是高于MPEG1、2的新一代数字媒体格式(本人到现在还不知道为什么没有3直接从2跳到4了,知道达人请在后面的帖子里补充) 现在就具体介绍一下MP4的具体规格:(很多内容来源与doom9.org,英文好的朋友我强烈建议去那里看看,消费层用户里面那里是很权威的) - ISO 14496-1 (Systems) - 户动界面(有点像DVD里的菜单) - ISO 14496-2 (Video) - ASP(Advanced Simple Profile)就是其中一种,代表产品有Xvid,Divx5等等。 - ISO 14496-3 (Audio) - AAC (Advanced Audio Codec)。 - ISO 14496-10 (Video) - Advanced Video Coding (AVC),也被叫做H.264。代表产品有x264。(看好这里,不要把h.264和x264搞混了,一个是规格的名字,一个是实际产品的名字) - ISO 14496-14 (Container) - 文件格式,后缀名为.MP4。这个MP4规格唯一官方指定的格式。 - ISO 14496-17 (Subtitles) - 字幕。
下面我对上面的规格做一下简单的解释: system和subtitle我就不多说了,这个很直观。就好像dvd里的菜单和字幕。这个我还没有实际接触,因为就目前来讲在HD-DVD和blue-ray没出来之前也没多大意义。 细心的朋友可能发现,这个MP4规格里有两个是关于video的。对,一个是ASP一个AVC。就时间来看,ASP发布时间较长,实际的产品有大家熟悉的xvid等等。也正是因为发布时间较长,技术相对不是那么新。这也是为什么AVC规格被引入的重要原因。至于具体哪些地方比ASP高级和先进,由于我的这个帖子主要是针对像初步了解MP4和avc的朋友的,所以如果你想深入了解的话,可以在这里查询: http://forum.doom9.org/showthread.php?p=674815#post674819
在AVC的基础上,这个规格又细分为4个小的预先规范的等级(这个实在不知道怎么翻译,英文是profile)。分别是: - Baseline profile - Extended profile - Main profile - High profile
要是之前有对ASP(xvid)规格了解朋友,AVC规格在ASP原有的功能基础上又增加了两个新的功能: CAVLC和CABAC: Context-Adaptive Variable Length Coding (CAVLC) 和 Context-Adaptive Binary Arithmetic Coding (CABAC)。 光听这名字就够恐怖了吧?我是不打算解释了,反正就是一堆算法,想深入了解的人还是到上面的那个网址里去看,都在里面。
接下来是container(容器)的介绍了。稍微对视频格式有些了解朋友应该都知道这是什么,就不用多看了,直接跳过。这里给还不清楚的朋友简单解释一下: 就我们消费者层次上看,一个媒体文件是由最基本的两个要素组成的:容器(俗话说的视频格式)和codec(copressor/decompressor的缩写,也被成为encoder/decoder,中文为编码、解码器)组成的。那他们是什么关系呢?举个最简单的例子:容器顾名思义就好像一间大房子,空空的。现在的任务是是要往里面堆箱子(就是往里面做视频、音频文件的过程)。这个过程是由encoder完成。encoder就好像一个搬运工一样,每个人堆箱子的方法都不一样,好比有的人井井有条,一个挨着一个摆箱子。有的不拘小节,随便往里面扔。方正堆中的目标就是把箱子都放到屋子里。这也就是说明了为什么有的codec编码效果好,有些稍微差一些。容器有很多,好比avi,rmvb,rm,mov,mp4等等,就好比屋子的形状也有不同一样,有的方形,有的圆形等等。我希望我的这个比喻还算直观,能让不懂的朋友理解。
说完video再说说audio。AAC(Advanced Audio Coder)区别于ac3,mp3(全称MPEG1 Layer3,可不是MPEG3的缩写哦)等等,aac是Mp4官方指定的mp4音频规格。和video一样,她也有两个profile: - LC-AAC (Low Complexity) 也被叫做MAIN @ Level 2 - HE-AAC (High Efficiency) 也被叫做AAC SBR/AAC+/aacplus 再次抛开技术性的数据,HE比LC更高级一些,允许你在相同音质下已更低的bitrate编码。 LC编码器有FAAC(Free Advanced Audio Coder)和winamp HE编码器有ahead的nero。
实战H264/AVC编码篇
希望高手在看到下面的教程后能作出补充、建议和更改,谢谢!
在这篇教程里我将着重以MeGUI这个软件为中心介绍AVC文件的制作过程。MeGUI是一款开源(免费)软件,之所以我以它为主介绍是因为它免费,谁都可以获取,另外还有一个更大的好处是它是集合多款第三方开源软件,可以充分利用其它软件在各自领域的长处和优点。严格来讲MeGUI其实是一个“搭桥”性质的软件,它把分散的功能“单一”的软件紧密结合起来以此发挥他们的最大效能。
所需软件列表: MeGUI (需要MS .NET Framework 2.0)- http://sourceforge.net/projects/megui avisynth - http://www.avisynth.org besweet - http://dspguru.doom9.net/ belight(besweet的GUI界面程序,功能强大)- http://corecodec.org/projects/belight/
我之所以没有给出具体的下载地址是因为开源软件的一大特点就是更新速度极快,如果我给出某一特定版本的下载地址,很容易造成读者读到我这片文章的时候已经有更新的版本的出来了,这是还使用我的下载连接的话就不是最新版本了。 另外还有很多辅助软件和一些DLL文件,会在下面的文章里提到他们,并尽量给出下载地址。
下图是MeGUI的主界面。 很简单的,视频、音频分的一清二楚。稍微有压缩经验的朋友应该都能立刻上手。 首先我们点击菜单里的Tools->settings来做一些基本设置。 在main这个菜单里我们主要设置两个选项:Default Priority和x264 encoder。 Default Priority(默认级别)- 这个是设置CPU占用率的,一般不要设置超过normal。选择low如果你在编码的过程中还想在电脑上做其它事情(不过本人不建议你这么做)。 x264 encoder - 当然是选x264.exe啦
xvid encoder也可以作出相应选择,不过本人不建议读者在MeGUI里编码xvid格式的视频。原因有二:一是他使用的是xvid_encraw程序为xvid编码器,他的选项没有我们平时用的xvid.org的codec选项丰富。二是最新的“官方”xvid编码器在几个月前开始支持多线程编码了,就是说拥有多核、多处理器的朋友可以100%发挥他们机器的全部性能了!而这个xvid_encraw举我所知好像还不能。
设置完后点击“program paths”。在这里设置MeGUI需要用到的所有外挂程序的路径。 mencoder - (http://www.aziendeassociate.it/cd.asp?dir=/mplayer) - 上面说了,这个可要可不要 BeSweet - 最上面给出链接了 mp4box - (http://kurtnoise.free.fr/mp4tools/) - mp4容器(container)muxer。(muxer可以简单理解为将视频和音频压缩到一起的一个工具,比如说把xvid的视频和mp3的音频放到avi格式的文件里的过程) mkvmerge - (http://www.bunkus.org/videotools/mkvtoolnix/downloads.html) - 如果要生成mkv格式文件就需要这个。 x264 - (http://forum.doom9.org/showthread.php?t=89979) - 这个不用多说了吧,开源软件里最好的h264规格编码器,必须要用这个!! xvid_encraw - (http://forum.doom9.org/attachment.php?attachmentid=5390&d=1138913945) - xvid编码器 DGIndex - (http://neuron2.net/dgmpgdec/dgmpgdec.html) - mpg2 frameserver,可以理解为vob转mpg2的工具。vob格式是dvd视频承载格式,如果你要从dvd上rip片子的话就需要这个程序。 faac - (http://pessoal.onda.com.br/rjamorim/faac.zip) - free的aac音频编码器 neroraw - (http://www.savefile.com/files/1985242) - nero的aac音频编码器 lame - (http://rarewares.org/dancer/dancer.php?f=64) mp3音频编码器 avisynth plugins - 默认是在C:\Program Files\AviSynth 2.5\plugins
这里对MeGUI音频编码做一下补充: MeGUI在编码音频的时候会有两种模式提供选择:avisynth脚本和BeSweet模式。 使用avisynth模式的时候,你需要将NicAudio.dll(http://www.avisynth.org/warpenterprises/files/nicaudio_25_dll_20050704.zip)和mpaSource.dll(http://www.avisynth.org/warpenterprises/files/mpasource_25_dll_20040109.zip)文件放在C:\Program Files\AviSynth 2.5\plugins的目录里。aacenc32.dll和aac.dll放到neroraw.exe所在目录。这两个dll是nero burning rom自带的,如果你的系统装有此软件,你可以在c:\program files\common files\ahead\AudioPlugins里找到他们。如果你的dll是nero6的话,请把“I'm using Nero6 AAC DLL's to encode”打上钩,要是nero7的话,不打钩,但是需要再把c:\program files\common files\ahead\lib\MFC71.dll这个dll放到neroraw.exe所在目录下。 BeSweet也同样需要NACC(Nero ACC)和FACC(Free ACC)的支持,所以上面的aacenc32.dll、aac.dll、facc.exe外加bse_FAAC.dll(http://corecodec.org/frs/download.php/413/bse_FAAC.zip)都需要。把他们同时也安放到BeSweet的目录里。
都设置好后,再下载Helix YUV codecs(http://www.lillevold.com/files/yuvcodecs-1.2.exe)。这个decoder是个“中间者”。可能大家不知道,任何视频时间的转换都不是直接的,而是需要介于“中间”的codec搭桥的。YV12是其中一种,特点是在两头的格式(目标文件和生成文件)都支持的情况下可以做到无损转换并可以达到最高到30%速度上的提高。所以安装这个绝对有好处。
Ok,到这里为止程序路径的设置就算告一段落了。我希望没吓到大家 - 下载安装并设置了这么多软件:P
现在开始实际示范制作过程!
MeGUI有别于其它传统编码软件的地方在于它只支持avisynth格式的文件输入,很多朋友在这里可能会碰到疑问。比如我有个avi或者mpg格式的文件要怎么让MeGUI识别呢?这里就必须要用到avisynth的avs文件格式了。首先检查你的avisynth是否成动安装:打开“记事本”或是任何你喜欢的文本编辑器(text editor),在里面写入
然后保存为avs后缀的文件(记住不是txt格式)。然后在你的播放器里(我这里使用Media Player Classic)打开这个文件。如果可以看到一段视频显示avisynth的版本信息的话就说明你的安装成功了,否则请重新安装。
从这里大家可以看出avisynth是一个基于脚本编辑的frameserver。这里大家可能又要问,frameserver是什么?要解释这个不容易,最直观的解释是比如你用virtualdub编辑好了一段视频准备制作成rmvb格式的片子。可是不巧virtualdub不支持rmvb输出,而只有avi。传统的方法是用virtualdub生成avi,然后把它输入到另外一个支持avi输入的rmvb压缩软件里。这个过程中费了两遍力不说,还浪费了时间因为中间要生成avi,还浪费了空间因为生成的avi要占硬盘空间,而且通常很大(有时要无损压缩)因为你要保证输入到rmvb压缩软件里的avi质量要好。virtualdub的frameserver在这里的作用就是欺骗系统让它认为avi已经生成了,输入到rmvb压缩软件里后软件开始压缩,然后virtualdub就一帧一帧的生成avi然后“喂”给这个rmvb压缩软件。 avisynth和virtualdub最大的区别就在于一个是基于脚本的一个是基于GUI的。脚本的坏处是上手难,需要一定的脚本编写能力(其实avisynth脚本还是不算很复杂的);长处就是功能远远强大于GUI的程序,并且有很多人在给她编写插件,功能日益强大。
看到这里没有编程经验的朋友根本不用害怕,因为MeGUI的脚本生成器完全能够应付我们大多数的需要了。点击菜单上的Tools->Avisynth Script Generator,见到如下窗口:
首先在video input里指定你想导入的视频文件,这里默认只支持avi,mpg2,d2v和virtualdub frameserver文件。不要着急,点击“edit”标签,这里显示的就是你实际的脚本。比如我导入了G:\Jaspreet\Mummy_01\VTS_01_0.d2v这个文件后,默认在“edit”里生成的具体脚本如下:
现在我们简单分析一下这个脚本: 第一行“loadplugin”,将一个叫“dgdecode.dll"的dll加载到了avisynth里,上面提到这是一个DVD的VOB文件转MPEG2格式的frameserver。 第二行”mpeg2source“,是将dgdecode.dll生成的.d2v文件导入。这里我假设读者已经掌握基本的dvd decrypt的知识,具体就是将加密的dvd解密并拷贝到硬盘上。DVD Decrypter就是个不错的免费程序,应付95%以上的加密足够了。这一步是生成.vob文件,可是普通程序无法直接读取,我们需要一个叫做”DGIndex”的程序来作frameserver。这里我也假设读者已经掌握使用这个软件的技巧,如果日后有需要我会再补充到教程里。 3、4、5行是avisynth里加入的虑境(filter)。他们的具体功能就是对视频进行编辑。这时你可以切换回“options”标签,看到“output resolution”,你可以利用这个来resize你的video。比方说你原本的video是800X600的,你想缩小到400X300,就在这里面输入。这时你在切换回“edit”标签,倒数第二行由“LanczosResize(800,600) # Lanczos (Sharp)”变成了“LanczosResize(400, 300) # Lanczos (Sharp)”。 依此类推,crop是裁剪用的,比方说你的video里上下都有黑边,可以直接在MeGUI的preview窗口里裁剪,然后身成相应的脚本。大家可能注意到了有些filter前的“#”号标志,有这个符号的filter代表被禁止了,没有的代表会被使用。有编程经验的朋友都知道这其实就是avisynth里的comment标识符。 在这里再向大家介绍一下avisynth里rm和rmvb的导入方法:
fps是frame per second的缩写,就是规定一个视频文件一秒种能播放多少帧。如果你是用MPC看rm文件的话,可以在File->properties->detail里看到视频的fps。realplayer里记不清了,好像是file->clip info或是property里面,反正很好找的。 ××还要提醒大家的一句就是,如果你是安装real alternative codec的话,那按照上面说的就可以直接导入了。要是你直接用realplayer看的话,还要到网上下载一个叫realmediasplitter.ax的文件(http://sourceforge.net/project/showfiles.php?group_id=82303&package_id=87719&release_id=373769)。将它存放在c:\windows\system32\目录下,执行regsvr32 c:\windows\system32\realmediasplitter.ax注册就可以了。
在做完所有操作以后save成avs文件,然后在MeGUI的video->AviSynth script里导入就可以了。再在“video output”里输入你输出文件的地址。 codec当然选择x264。 file type我在这里简单解释一下。我不建议大家使用avi作为mp4格式文件的容器,因为avi从一开始就不是为mp4文件规格设计的,它的“岁数”太老,使用的是相对较过时的技术。至于具体为什么我可能会在以后加入到教程中。 raw格式生成的是后缀名为.h264或是264的文件可以。这是以纯流媒体(stream)形式存在的可是,不是最终格式,需要时候mux到相应的容器里。 MKV是一种开源公开的媒体文件容器,它当初设计的理念就是可以包容万千,容器设计极具灵活性几乎可以兼容市面上所有的codec。你甚至可以把rmvb编码的视频原封不动的植入到mkv容器里,播放的时候当然还是需要real自己的decoder。说到这里也就不难想象mkv可以支持avc编码的视频一点也不奇怪。 最后MP4是MPEG组织官方规格里唯一正式认可的容器格式,当然也是强烈建议大家使用的。 这里我建议大家使用raw或是mp4格式。可以使用raw格式的原因是反正之后还要把video/audio mux到一起,所以理论上讲现在使用raw格式没问题,只要确保最终形成的是mp4格式就可以了。
下面进入x264编码的实际设置过程。这是整个制作Mp4文件最核心的部分,但其实也是最简单的部分。为什么这么说那,这个过程本来很复杂,4个标签栏(分别是Main, Zones, Rate Control, Quantizaion)里的选项五花八门。看到这里有过xvid或是其他编码经验的朋友可能会对其中的一些选项比较熟悉,可是仍有相当一部分的选项是没有见过的。
Main 先说一下最常用的选项: Mode 这个和xvid差不多, abr是average bitrate的意思。就是所码率被设定在一个平均数上下浮动。 constant quality,每帧画质恒定 constant quantizer,恒定的quantizer(这个理解有些难度,我在后面会着重介绍) 各种pass,是一种高级的算法,现是1st pass不进行实际编码,而是分析视频生成统计文件(.stats),然后在2nd或是3rd pass里进行实际编码。 Bitrate这个大家都知道,就是率码的大小。
PSNR建议关掉,这是个画面质量的校验机制,关掉不会影响画质,还会缩短压缩时间。 number of thread很重要,你的电脑要是双核或是双CPU的话,可以设置到2。四核的就是4。这个理论上可以增加60%以上的速度。 fourCC是媒体文件识别符号,xvid时代就是xvid,现在x264当然就选x264了。
现面的AVC profile和我最上面提到的完全吻合。这些设置主要是针对兼容性的,一些特定的硬件播放器需要指定的profile编码才能被识别,具体的例子有PSP,iPOD视频等,他们都有自己指定的profile。 要是这些profile已经把你搞糊涂了的话,AVC Level就更多了。level有十来个,每个profile都对应这些level。因此可以有更细致的分类。
注×:读者要是只是准备在自己PC上播放的话,可以不去管这些实际的profile和level,因为pc的好处就是通杀,无所谓。
Zones zone的概念是具体微调。你可以具体指定某一段的frame(比如frame 200到frame 600)然后对这段frame做具体的设定。这个功能理论上是可以最大的优化你的压缩率的设置,可是太过复杂。一般人很难把一段视频分析到这么透彻,具体到每一段frame的优化工作量是在太大。这里几乎只能是个摆设,过多的解释我就不作了。在这里我的教程是不对这里做任何设置的。
Quantizer和Quantization matrix 这里个人认为是视频编码的重点,也很难设置好。这里我简单简单解释一下他们是什么: 编码器在实际编码的过程中,是一帧一帧的进行的。一帧就是一张静止的画面,然后编码器再把它划分为8X8或是16X16(或是其他可以被2整除的小块,不过这两个应该最常用)的小块。这种算法的好处是可以按照这些小块(block)独立进行画面分析。比如说通常还面的中心部位画面最复杂,需要更多的时间去分析,因为通常大家拍摄片子的时候都是把要具体拍摄的人物、物体放置在画面中间的位置。至于画面四周一般是背景,相对不需要那么多的时间去分析。按照以上的基本思路,quantization matrix(一个数学矩阵)的概念就被引入了。比如说一个被分为8X8个block的画面,就会有一个8X8的矩阵相对应。quantizer是这个矩阵的系数,控制着这个矩阵(整个画面)总体的精确度。系数越大理论上画质损失约大。 又说了这么多,不知道大家糊涂没有。由于这个系数和矩阵的具体数值是通过复杂的算法(并不断尝试)得到的,一般都是只有编码器的制作者和一些精通视频编码(在数学算法级别的精通)人才可能真正知道最优化的数值,因为这些数值都是随着不同视频而变化的。一个针对某个视频优化的矩阵和系数不代表就是另一个视频的最佳优化。庆幸的是有doom9上有高手(sharktooth)已经制作了一些事先优化好的设置,并提供免费下载。 这里是他的下载连接: http://files.x264.nl/Sharktooth/force.php?file=./megui/profiles/MeGUI-x264_generic_profiles_v24.7z 这里说一下如何使用他们: 下载回来的文件里都是一些.xml格式的data文件,将他们解压缩到MeGUI安装目录里的\profiles\video\下。重启MeGUI后就可以在x264的设置里看到这些profile了。如图:
介绍(英文翻译的)
最高画质设置并且可以规定最终生成文件大小,对想把文件刻录到cd/dvd上的朋友可以用到这个。(多pass编码,速度最慢) HQ-Slow: Pretty slow but not much. Quality is near the best. HQ-Slower: Slower than HQ-Slow but it tries to squeeze some more compression thru the use of more reference frames. HQ-Slowest: Same as HQ-Slower with more reference frames. HQ-Insane: All settings maxed out. (这里我就不作翻译了,看到slow,slower,slowest这几个比较级就明白了,越慢画质相对越好。insane代表疯狂模式,是编码速度最慢的。具体慢到什么程度,我那我自己的例子出来好了。我得PC是AMD 4200+ X2,2GB双通道ram外加300GB RAID0配置,使用slowest模式压缩电影Mummy大约是长度是3小时,7G容量的DVD。足足压缩了13个小时生成700MB左右的文件。所以这里建议大家使用slow就可以了,算是极限了。再慢的profile画质也也不会有什么明显的提高了)
通用2-passes设置 CE-Highprofile: high profile设置 (不兼容QuickTime) CE-Mainprofile: main profile设置 (不兼容QuickTime) CE-QuickTime: QuickTime 7兼容设置 CE-Baseline: baseline profile设置 (兼容QuickTime 7)
快速编码设置使用1-pass,对要求快速编码的朋友适用 1P-Maxspeed: 最快速度,几乎所有优化指令都关闭了,最求最快速度。适合编码视频流放到web上实时观看 1P-Intermediate: 中等速度 1P-Goodquality: 速度画质兼顾
恒定画质(constant quality)设置 CQ-Lossless: 无损编码,适合采集视频时用 CQ-ASP_Q2_equiv: 模拟ASP编码设置 CQ-ASP_Q2_eq(crf): 这个不太懂,英文原意是和上边的一样只是增加了constant rate factor
卡通编码设置(2 pass),编码动画片的时候用的 AE-Standard: main profile,2 pass,标准画质(这个标准的定义应该是0day里动画编码的标准) AE-Goodquality: High Profile, 高画质,速度慢于standard编码 AE-Maxquality: 速度最慢,画质最好
游戏机、PSP和iPOD video编码设置 PD-PSP: 按照PSP指定规格的设置 PD-Xbox_Hires: XBOX高分辨率设置(需要XBMC),不知道XBMC是什么,有XBOX的朋友可能已经知道了 PD-Xbox_LoRes: XBOX低分辨率设置(需要XBMC) PD-iPod: iPOD的视频编码设定
选择好自己喜欢的profile后还要到tools->bit calculator进行最后生成文件容量的计算。通常在你加入avs文件后,打开这个bit calculator后,video里会自动加载你的源文件的总长度(时:钟:秒),framerate等等的信息。剩下的可要自己设置的了。 audiotrack里指定你压缩好的audio格式,可以有两个track(轨道),比如一个普通话一个广东话。 codec当然是x264,container是mp4或是mkv。再次说明不建议avi格式。 totalsize:指定你的最终文件大小。你还可以指定CD或是dvd之类的常用媒体介质,十分方便。 results是依靠平均码率来计算最终容量的,相对没有totalsize直接指定生成文件大小的方法来得准确。
都设置好后就可以点击”Enqueue“了。然后点击到”Queue“标签栏里再点击”start“就大功告成了!!
http://hi.baidu.com/todayz/blog/item/e4b64e4a4c21082208f7ef7f.html