H264编码参数漫谈

/*本文来源[Adobe Devnet],原本是分析录制f4v文件(flash player video)时, H264编码参数的设置*/

H.264编码参数

虽然H.264的编解码器来自不同的供应商,但是他们都使用同样的编码技术以及相似的比较有代表性的编码参数。 在这里,我讨论的是最常见的h.264编码选项。

了解概况和级别

图1 编码技术纵览(来自:Wikipedia)

正如你猜想的,越高级别的编码方式使用的编码算法就越先进,并且因此会生产出质量更好的文件。为了凸显这种差异,我使用同样的源文件并设置了同样的编码参数。 左边的文件采用Main方式,而右面的使用Baseline. 在图1中的表格里我们可以很容易查出,Main方式是支持B-切片技术的(也叫做B-帧),并且也支持高质量CABAC编码,我将在文章的后面部分做详细讲解 正如你所看到的,这样做有助于Main方式实现比Baseline更高质量的视频。

图2.使用Main方式编码的视频(左边)比使用Baseline方式编码的视频(右边)质量要好得多。

    所以,Main以及High方式比Baseline产出的视频质量更高;我们有什么收获呢? 收获就是,因为你使用了更加先进的编码技术,这个文件变得更加难解压,并且也许在老一点的电脑上播放的会很缓慢,并且不平滑。

    这个观察说明一个目前H.264编码参数的典型的需要权衡的问题,较高的文件质量带来的问题是文件很难被解压,另一方面,使用高质量的参数编码,会花费更多的时间。在某些罕见情况下,你决定在流中包含B-帧编码,等同于同时触发了两个问题,增加了解码难度和编码时间。

    回到方式上来:在高的标准下,可以编码方式将看成是厂商和视频生产者共同遵守的适应点。手机生产商A需要生产一款能够播放h.264视频的手机,但同时需要控制成本,发热量和尺寸。于是,狡诈的首席工程师通过搜索,发现了功能足以播放用Baseline层级方式生产出的h.264视频的最佳处理器。如果你是一个被找来要为这样一款设备生产视频的视频制作人员,你会知道如果你采用Baseline方式编码,这个视频将是可以被正常播放的。

    因此,当生产h.264视频时,通常我们会使用目标播放平台所能支持的最高层级的方法来生产视频,因为这样可以在任何给定的码率下提供最好的视频质量。如果生产用于移动设备的视频,那么这就特指的是Baseline方式了,不过还是查看一下设备的相关文档确认为佳。如果是生产用于工作在Window或者Macintosh操作系统的电脑上的Flash player的视频,那么指得就是High方式了。

    这听起来又明了又好,但是要明白一点:虽然使用Baseline方式编码可以确保在你的移动设备上平滑的播放,但是使用High方式生产在电脑上播放的视频文件并不能提供这样的保证。 因为High模式下生产的h264视频,最高支持像素分辨率可以达到4096 x 2048,码率可以达到720Mbps。 只有很少的桌面电脑是可以进行完整帧频的播放的,更少的是在以每秒30帧的帧频进行播放流。

    因此,为生产移动设备使用的视频全在于你使用什么方式,而生产电脑使用的视频则全在于你怎样进行视频属性配置。这里,关键点是在于,是以VP6,还是Windows Media的计算方式解码。只要你用其他两种编码器以同样的分辨率和同样的码率生成h.264视频,在同一类型的电脑上播放都是没有问题的。(关于 H.264,VP6和VC-1更详细的比较统计,请阅读StreamingMedia.com 上我的另外一篇文章《Hi-Def视频产品解码的真相》)

    一般情况下,这意味着,只要你以640 × 480的分辨率和较低的码率生成SD视频,应该可以在2003年之后生产的电脑上很好的播放如果你以720p或者更高的分辨率生产,产出的流将不能在这些电脑中的任何一台上平滑的播放。 你应该为这些观看者提供一个SD流来替代过高参数的流。

    关于H.264的标准呢?如果生产用于移动设备的有限的屏幕分辨率和带宽的视频,你应该选择正确标准,这也是厂商应该指定的标准。 然而,由于Flash Player可以处理任何一种支持的标准下,任意一种方法生产的视频,所以在你为Flash Player生产在个人电脑上播放的视频时无需有任何担心。

平均信息量编码

    当你选择了Main或者High方式,一些编码工具将给你两个关于平均信息量编码模式的选项。(见图3)

  • CAVLC :基于上下文的自适应可变长编码
  • CABAC :基于上下文的自适应二进制算术编码

    这两个选项中,CAVLC是低质量的,易于解码的选项,CABAC是高质量的,难于解码的选项。

图3 . 对平均信息量编码的选择: CABAC和CAVLC

    虽然结果是取决于源文件质量的,但通常来说CABAC被认为比CAVLC效率高5%-15%。这意味着,CABAC应该在码率低5-15%,的情况下,提供同等的,或者更高的视频质量。在我自己做的测试中,CABAC产出的视频质量要明显的好于CAVLC,虽然只是在高清晰视频编码测试中,采用非常低的码率的情况下。如图4显示,左边的是用CABAC 生产的720p文件,右面的是用CAVLC产出的文件,同样都是800k码率。图4显示出,16:9的720p视频被抽取了一些帧 现在800 kbps码率的画面质量是相当低了;相比之下,YouTube采用2m码率进行h.264编码,几乎是这里的2.5倍。

图4 . 采用CABAC 编码的720p文件(左边), CAVLC编码(右边)

虽然任何一个的画面质量都不是值得称赞的,但是左边的画面上的芭蕾舞演员的面部和其他细节明显地要清晰一些。 结论就是,CABAC会提供更加的画面质量,无论是多么细微的差异。 现在问题变成是,这样做究竟会给解码和播放增加多少难度呢?

答案是,不会很大。我在我的办公室里用两台运算能力都不是很强的多核cup电脑进行测试,一台是使用酷睿2处理器的惠普笔记本电脑,另一台是基于个人电脑配置的苹果台式机。正如你在表格2里面看到的,CABAC文件,在惠普的笔记本上增加了不到1%的CPU负载,在苹果机上增加了不到2%的负载。鉴于更佳的视频质量和细小的CPU负载差异,我建议,只要CABAC是可用的我都会选用它。

电脑

CABAC

CAVLC

区别

惠普Compaq 8710w 移动工作站 - 酷睿2 双核

31.1%

30.5%

0.6%

苹果PowerMac G5 2.7GHz 双核

35.5

33.7

1.8%

表2.播放采用CABAC 和CAVLC并使用h.264编码的视频文件的CPU消耗量对比。

I, P和B帧

这是一个常见的前言知识画面,帧与帧之间的切换的变化是很小的,编码的质量要高于动态的,运动式的视频。那是因为H.264像所有高质量的运动编码方式一样,目的是充分利用视频帧与帧之间的冗余帧。越高的帧冗余,将带来给定码率下越高的质量。

为了利用这种冗余, H.264流包含了三种类型的帧(见图5)

  • I-帧:也成为关键帧,I-帧完全自我指涉的,并且不使用任何其他帧的信息。它在三种帧中占最大的比例,并且具有最高的质量,但是压缩效率是最低的。
  • P -帧:P -帧是所谓的“预示”帧。当创建了一个P-帧时,编码器可以向后查看I-帧或者P-帧中冗余的图片信息。P-帧比I-帧效率高,但是没有B-帧的效率高。
  • B-帧:B-帧是双向预测帧,从图五你可以看到,这意味着当我们创建B-帧,编码器可以同时向前和向后查找冗余的图片信息。这使得B-帧在三种帧中具备最佳的效率。注意,B-帧在使用Baseline方式生产视频的时候是不可用的。

图5.H.264编码流中的 I,P,和B-帧

现在你知道了每种类型的帧的功能,我将会告诉你如何更优化的使用它们。

使用I-帧工作

尽管I-帧的压缩效率是最低的,但是它们同时也提供了两种不可取代的功能。首先,所有的h.264视频文件的播放都开始于I-帧,因为它是唯一在编码期间不依赖于其他帧的帧类型。

由于几乎所有的视频流都可以进行交互式的播放,当观看者在视频不同的片段之间推动滑块时,你应该在视频中包含规则的I-帧来确保灵活的播放控制。这在使用Flash Media Server发布的流,以及使用分布渐进式下载发布的流中,是可行的。虽然这没有什么所谓的魔法数字,我通常每隔10秒使用一个I-帧,意味着在生产每秒播放30帧的视频时,每隔300帧有一个I-帧。(24fps和 15fps分别为每隔240帧,和每隔150帧一个I-帧)

I-帧的另外一个功能是帮助在场景切换时重置画面质量 试想,从一个场景到另外一个切换时图像急剧变化。如果新场景的第一个帧是一个I-帧,这是最好的状况了,对于随之而来的P-帧和B-帧能查找到冗余的信息来说,这是一个绝佳的起始点。因为这个原因,许多编码工具都提供了一个特性叫做“场景变化监测”或者“自然关键帧”,你应该永远都开始这些功能。

图6显示了在Flash Media Encoding Server中I-帧的相关控制 你可以看到场景变化检测是默认被启用的,并且视频编码序列的大小为300,即300帧。 如果这样说的话可能理解起来会更简单:“I-帧,间隔”,不过,这已经足够显而易见了。

图6.Flash Media Encoding Server中 I-帧相关控制

IDR 帧

具体说来,视频编码序列指的是“图片组”,或者简称为GOP,它是组成H.264流的组成部分,每个H.264流都是由很多个静态的GOP组成的。每个GOP都是由一个I-帧开始的,并包含了所有的帧,但是并不包含下一个I-帧。通过选择视频编码序列为300,你是在告诉 Flash Media Encoding Server创建一个包含300帧的GOP,或者基本等同于说每隔300帧一个I-帧。

我在向你进一步描述B-图片的数量设置时,同时也就已经在向你描述平均信息量编码模式了;但是我想解释的是最小IDR间隔,和IDR频率。 首先我要定义IDR帧的意义。简单的说,H.264规格使用两种类型的I-帧:普通I-帧和IDR帧。对于IDR帧来说,在IDR帧之后的所有帧都不能引用任何IDR帧之前的帧的内容,与此相反,对于普通的I-帧来说,位于其之后的B-和P-帧可以引用位于普通I-帧之前的I-帧。

从随机存取的视频流中,播放器永远可以从一个IDR帧播放,因为在它之后没有任何帧引用之前的帧。 但是,不能在一个没有IDR帧的视频中从任意点开始播放,因为后面的帧总是会引用前面的帧。

由于在你的视频中插入关键帧是使互动播放成为可能的一个关键原因,我使用了默认的设置值1,这使得每一个关键帧都成为了一个IDR帧。如果你设置这个值为0,只有第一个I-帧会成为IDR帧,这使得文件不能支持随机访问。设置这个值为2会使得每一个第二位置的I-帧变成IDR帧,当设置为3时使得每一个第三位置的I-帧变成IDR帧。 再说一次,我只使用默认的设置值1.

最小的 IDR间隔定义了一组图片中的最小帧数量。虽然你已经设置了视频编码序列为300,你也选择了开启场景切换监测,使得编码器在场景切换时插入一个I帧。在一个非常动感的包含一连串动态变化的MTV 中,这将会导致非常频繁的I帧出现,这可能会降低整个视频的质量。对于这种类型的视频,你可以尝试将最小IDR间隔增加到30-60帧,现在看看这个是不是提高了视频质量吧。 但是,对于大多数影片,默认的间隔1提供给编码器频繁插入I-帧的必要的灵活性,高度活跃的部分,例如开启或关闭logo. 出于这个原因,我也在默认的控制设置中将这个值设置为1。

使用B-帧工作

    B-帧是效率最高的帧,因为他们可以同时进行双向的冗余帧搜索。虽然不同的编码器之间的控制和控制命名不同,但是最常见的B帧相关空是是简单的B-帧数量设置,或者像图片6中所示的“B-图片”。注意图片6中的数字实际上指得是I-帧和P-帧之间的连续帧。

使用在图6中所示的值2,你将会创建一组这样的图片组:IBBPBBPBBPBB ... 就这样一直排列300帧。如果B-图片的数量设置为3,编码器将会在每一个I-帧个P-帧之间插入三个B-帧。 虽然没有神奇的数字,我通常使用两个顺序的B-帧。

    插入多少个B-帧可以提高你视频的质量呢?图7说明了这个问题。作为背景,这是一系列高运动率的滑板动作的结尾帧,同时也包含很重要的细节描写,特别是在栅栏后面的选手。 这种结合了高运动率和高细节描绘的情况是不多见的,使得对这进行编码变得非常难。正如你看到的图片,采用B-帧保存的文件明显比不使用B-帧保存的文件细节表现要好。 总之,B-帧确实提高了质量。

图7.使用(左)和不使用(右)B-帧编码的文件对比

    在解码方面有什么性能上的损失么?我做了一个跨平台的电池测试,尤其针对那些老化的,低性能的电脑,测量在播放使用Baseline方式生产的视频(不采用B-帧),以及使用High方式生产的视频(采用B-帧)是的CPU负载量。我看到最大的差距是10%,这并不足以动摇我建议你,除了在为移动设备生产视频时使用Baseline方式,其他的时候就都使用High方式进行编码吧。

高级B-帧选项

   

图8 .其他B帧相关的选项

B-帧自适应设置(use adaptive B-frame placement):允许编码器覆盖已经编码过的B-图片数量以提高质量,例如,当它监测到场景变化或者最后而来的帧是I-帧时。 我总是启用此设置。

参考B-图片(reference B-pictures):让编码器使用B帧作为P帧的引用帧,当开始锥形B-帧编码时,编码器使用B-帧作为其他B帧的引用帧。 我通常不开启这个选项,因为质量的差别是微不足道的,这些选项可能会使视频在某些环境下的播放变得不稳定。

参考帧数量(reference frames),是编码器在编码时可以搜索的冗余帧的数量,它会影响编码时间和解码难度;在使用B-帧和P-帧进行编码时,如果你将这个值设置为10,编码器将会一直搜索冗余帧信息直到第10个帧上,这增加了搜索时间。此外,如果编码器在10帧之内发现了冗余资源,每一帧都必须在解码和回放时被存放在内存中,从而提高了解码的难度。

直观的说,对于大多数视频,绝大多数的冗余资源在离帧最近的位置被编码。 这就是说,只要设置这个值超过4或者5,就会增加编码时间,同时带来的价值并不大。 我通常使用的值是4.

切片数量(number of  slece per picture),虽然不是与B帧相关的技术,考虑到每张图片的切片数量,可以是1,2,或者4,以设置为4为例,编码器将每一帧划分为4个区域,并且只在其他帧指定的区域内搜索冗余信息。这可以加速在多核处理器电脑上的编码速度,因为编码器可以指定不同的内核作为指定的编码区域。然而,由于冗余信息可能已经转移到了帧之间的不同区域----平移或倾斜移动----多切片编码可能会丢失一些信息,因而降低视频的整体质量。

与此相反,默认值1的情况下,编码器将每一个帧作为一个完整的区域,并整体的搜寻潜在的引用帧。因为这样做并不利于多核CPU分担这个任务,所以这种设置导致的结果是很慢,但同时也是视频质量最高的。除非你真的那么着急,否则我建议你将这个值设置为默认值1.

其他编码参数

一旦你越过了I-和B-帧的相关控制,H.264提供了一系列额外的编码参数,我将在稍后进行讲述。目前的这些设置,我估计还有90-95%的选项会影响h.264视频质量。而我们本节讨论的设置,仅仅能改变其中的5%,这意味着大多数用户可以接受默认的值并且没有注意到其中的任何差别。不过,如果你想要尝试探求H.264的终极质量,你可以使用如图9所示的控制设置。

图9.Flash Media Encoding Server提供的其他H.264编码参数

首先是搜索形状,它可以是16 × 16或8 × 8 。 后者( 8 × 8 )是高品质的选择,而编码时间较长。接下来的三个“快速”选项允许您在允许的质量损耗范围内进行高速编码。 本人通常禁用这些选项。

在单帧中再次分派位数据的自适应量化模式和先进的量化强度设置,使用三个选择标准中的一个:亮度,对比度,或复杂性。我只会在实验时使用这些设置,这使得视频区域中有明显的块状显示。不幸的是,这个操作的内容相当的书面化,这使得它无法提供一般的关于使用价值的技术咨询意见。

无论是码率失真的优化,还是Hadamard变换设置都可以提高视频质量,但是编码时间会变得更长,我通常两者都选。最后,亚像素运动估算模式定义了搜索冗余资源的粒度:1/4像素代表最高的品质,但却是最慢的编码,全像素代表最快的但是质量最低的编码。在我的低急躁环境下,我总是用1、4。

理论应用到工作中去

现在您已经知道了H.265是如何工作的了,下面,我将简单的演示如何使用Adobe提供的工具制作H.264视频。

Adobe Media Encoder

这是Creative Suite 4中的一个引人注目的增强Flash视频编码的工具。现在有个独立操作和批处理编码功能。因此,您可以通过格式弹出菜单中选择不同格式存取H.264编码。如果是为Flash Player生成编码,那么您应该选择FLV或F4V选项,这将会为 Flash Player 生成VP6和 H.264滤镜。

特别的,您选择一个预设(preset )的编码,这个编码器使用了一个格式,也可以是其他格式。或者,您可以在格式选项卡上选择您的编码,如选择:FLV for VP6或F4V for H.264(见图10)。

图10.选择编码 VP6(FLV选项)或H.264(F4V选项)

Adobe Media Encoder中,最简单的工作方式是选择一个预设编码,它们有相同的大小或比目标分辨率达。这将确保合适的配置和正确的级别选择。

所有的预设都是在Adobe Premiere Pro 的默认配置文件中的,不是高级的。(All presets accessible through Adobe Premiere Pro default to the Main Profile, rather than High.)虽然任何质量上的差异可能是微小的,我们一般在进行编码之前将这个设定为高质量(见图11)。除了这一点,我唯一修改的一点是高级设置(Advanced Setting)中的 Set Key Frame Distance选项,我总是选中它,并且设定它的值为300。

图11.在Adobe Media Encoder中选择H.264编码参数

Flash Media Encoding Server

Flash Media Encoding Server的可控性要比Adobe Media Encoder要广阔的多,但是你还是要以同样的方式开始:选择您的容器格式和预设(见图12)。

图12. 在 Flash Media Encoding Server选择一个容器格式和预设

Flash Media Server 和 Flash Player 都可以播放流文件或回访任何H.264文件,实际上可以是任何格式,所以F4V或MP4容器都可以。如果你想使一个文件在 QuickTime Player 和 Flash Player里都能播放,你可以选择MP4;否则,使用F4V。选择一个预设,它使用与目标相同的或比目标更高的分辨率,以确保使用了合适的配置和级别。

图13 是H.264在Flash Media Encoding Server 中相关的参数。左边是预设的默认值。右边是我的设定值。红色的星号是预设的建议值,但是并不是必要的。

图13.修改H.264编码参数:默认值(左边),建议值(右边)

正如我之前讨论的,我将扩展GOP尺寸为300,并使用合适的 B-frame设定以提供最大灵活性的编码器。将参考帧从2提高到4可能略微提高编码时的质量和编码的复杂性,同时禁用快速内部(fast inter)和内部决策(intra decisions)可能再次提高质量,也增加了一些编码时间。

总的来说,我的建议值应该产生最优的质量,虽然这超出了编码时间。如果吞吐量是关键,那么我将做出以下改变:

  • 使用参考帧(reference frames)的默认值2。
  • 打开所有“fast”的编码选项
  • 使用16 × 16的搜索模式(Search shape)

·         设定运动估算子像素模式(Motion estimation subpixel mode)为全像素(Full pixel)

  • 如果你的机器是多核的,您可以使用2个或4个时间片(slice)

         如果您这样做,那么你可以比较一下两种参数的选则,看看是否快速编码参数会产生质量上的显著不同。

在音频方面,我将使用默认值,且只改变目标比特率和适合我目标的通道。H.264编码参数我也使用了默认值,比如时间戳和序列结束码,这些在Flash Media Encoding Server 中都提供。

你可能感兴趣的:(音视频)