一帧视频可以编码成一个或多个片slice,每个slice包含有一个或多个宏块MB(最多时一个slice包含整帧的宏块)。具体来说有三种关系:
-
每个编码图像一个切片,这是许多H.264编码应用程序的常见做法。
-
每个图片有N个切片,每个切片包含M个宏块,N和M个整数。每个编码切片中的字节数将根据图像区域的运动量和细节而变化。
-
每个图片有N个切片,包含不同数量的宏块,选择这些切片来保持每个切片的字节数大致不变。例如,如果将每个片映射到固定大小的网络包,这可能很有用。
设置slice的目的是为了限制误码的扩散和传输(编码的片之间有最小的数据依赖关系,这有助于限制错误在片之间的传播。怪不得搞编码速度/性能的paper大都不考虑多个slice,只考虑一帧只有一个slice,因为这些paper不会考虑出现误码的情况),使得每个slice之间是相互独立的,不能互相作为预测时的参考。
slice的结构如下图所示:
slice头用于确定slice的类型、slice的参考帧以及slice属于哪帧图像
slice数据包含一系列宏块,每个宏块里包含当前块的预测模式、参考图像索引、编码残差等数据
slice这东西再细分有这么几种,下面的三种都被基础/扩展的profile支持:
1. Redundant Slices
标记为redundant的slice包含部分或全部的编码帧的冗余表示。
在正常的流程里,解码器只会通过non-redundant的slice来重建frame,不会管redundant slice的东西。如果流程不正常,比如primary decoded frame因为网络传输的原因出问题了,那么decoder就会从redundant slice里掏出一些数据来替换掉出问题的数据。
总的来说,redundant slice可以保证传输出问题的时候提供数据来修补问题,但代价是降低了压缩性能。
2. Arbitrary Slice Order(ASO)
ASO makes it possible for slices in a coded frame to be arranged in any decoding order.
如果当前解码帧里的一个slice的第一个宏块的地址小于当前解码帧里先前解码的slice的第一个宏块的地址,ASO就会被调用。因此,slice就会以非光栅顺序传输。ASO主要用于帮助decoder error concealment(解码错误掩盖)。下图是一个ASO的例子。如果在传输中出现了丢包,slice0和1没了,那么解码器通过使用slice2和3能够掩盖错误的影响。
3. Flexible Macroblock Order
这个其实是用于slice groups的,FMO允许讲编码帧中的宏块分配给多个slice group中的一个,每个slice group包含组成一帧的宏块的子集,并且每个slice group包含一个或多个slice。
在slice group里,宏块按照光栅顺序编码,但silce里连续的宏块不一定是相邻的。
如果一个编码帧里包含多个slice group,那么FMO就会用到。
宏块的分配由macroblock allocation map决定,这个东西指示了每个宏块属于哪个slice group。
FMO可以提高错误恢复的能力,因为每个slice都可以独立解码。例如,如果在使用interleaved ordering(交错排序)的图像中丢失了一个slice或slice group,则可以通过在剩余的slice group里的已解码宏块之间进行插值,隐藏错误。
然后扩展的profile会支持下面几种,但这三种没有被很广泛的支持,暂时不做介绍了吧。
1. Partitioned SLices
2. SI Slices
3. SP Slices
--------------------------
在最后吐槽一下中文版264教程,有些地方(比如slice这部分)不知道怎么翻译的,我直接google翻译都比它通顺……