FFmpeg与音视频流媒体工程开发相关

H264系列十七 Slice(条带或片层)

2018-09-18  本文已影响369人  合肥黑

参考
《新一代视频压缩编码标准 毕厚杰 第7章 H.264的句法和语义》
【H.264/AVC视频编解码技术详解】十一、H.264的Slice Header解析
【H.264/AVC视频编解码技术详解】十二、解析H.264码流的宏块结构(上)
【H.264/AVC视频编解码技术详解】十二、解析H.264码流的宏块结构(下):H.264帧内编码宏块的预测结构

一、Slice的概念

我们已经知道,整个H.264的码流结构可以分为两层:网络抽象层NAL和视频编码层VCL。在NAL层,H.264的码流表示为一系列的NAL Units,不同的NAL Units中包含不同类型的语法元素。前面两篇中所解析的序列参数集SPS和图像参数集PPS就是其中重要的两个部分,其中包含了控制解码过程的一些通用的参数。

实际保存原始视频的图像数据的部分保存在其他的VCL层的NAL Units中。这部分数据在码流中称作是条带(Slice)。一个Slice包含一帧图像的部分或全部数据,换言之,一帧视频图像可以编码为一个或若干个Slice。一个Slice最少包含一个宏块,最多包含整帧图像的数据。在不同的编码实现中,同一帧图像中所构成的Slice数目不一定相同。

在H.264中设计Slice的目的主要在于防止误码的扩散。因为不同的slice之间,其解码操作是独立的。某一个slice的解码过程所参考的数据(例如预测编码)不能越过slice的边界。

二、Slice的类型

根据码流中不同的数据类型,H.264标准中共定义了5种Slice类型:

在I slice中只包含I宏块,不能包含P或B宏块;在P和B slice中,除了相应的P和B类型宏块之外,还可以包含I类型宏块。

三、Slice的组成

每一个Slice总体来看都由两部分组成,一部分作为Slice header,用于保存Slice的总体信息(如当前Slice的类型等),另一部分为Slice body,通常是一组连续的宏块结构(或者宏块跳过信息),如下图所示:


image.png
四、Slice Header结构

Slice header中主要保存了当前slice的一些全局的信息,slice body中的宏块在进行解码时需依赖这些信息。其中比较常见的一些语法元素有:

slice_type Name of slice_type
0 P (P slice)
1 B (B slice)
2 I (I slice)
3 SP (SP slice)
4 SI (SI slice)
5 P (P slice)
6 B (B slice)
7 I (I slice)
8 SP (SP slice)
9 SI (SI slice)

IDR 图像时, slice_type 等于 2, 4, 7, 9。

五、Slice Body——宏块结构(Macroblock)的解析

在已经实现了一个slice的header部分之后,下面的工作将是研究如何解析一个slice的主体,即Slice Body部分。一个Slice的body部分主要是一个个的宏块结构Macroblock组成,此外还存在一些辅助的信息。标准文档中规定的slice_data()结构如下图:


image.png

从文档中我们可以看出,Slice_data结构中独立的语法元素并不多,主要只有以下几个:

上述的几个语法元素毫无疑问仅仅占用了全部数据很少的一部分,其他大部分的数据都包含在宏块结构中,即上表中的macroblock_layer()结构

六、宏块(Macroblock)结构

从上表中我们可以看出,一个Slice结构中宏块实际上占据了绝大部分。在标准中一个宏块的结构定义为下表:


image.png
(1). mb_type:

在一个宏块中,最开始的语法元素为宏块的类型:mb_type。从表中我们可以看出,根据mb_type的值是否等于I_PCM,整个解析方法分为两大类:PCM类型和非PCM类型,判断依据是当mb_type为25时为I_PCM模式,否则为非I_PCM模式。

当这个宏块为I_PCM模式时,宏块中以差分编码的形式保存宏块原始的像素值。此时存在如下几个语法元素:

除了mb_type等于25时可以确定为I_PCM格式之外,其他的mb_type值可能根据帧类型(或slice类型)的不同而不同。比如对于I slice,mb_type的非PCM模式可以选择0~24这些值之一;对于P slice,mb_type只能取0~4这5个值;对于B slice,mb_type可以取0~22这些值之一。目前我们所处理的码流全部由I帧构成,因此我们暂时只考虑I slice的情况。下图是标准文档中规定的I slice的mb_type列表的一部分,完整列表在协议文档的表7-11中:


image.png

从上表中我们可以看出,mb_type不仅仅表示了宏块的分割方式,还包含了一些其他的附加信息,如帧内预测模式、亮度和色度分量的coded_block_pattern。当帧内预测使用16×16模式时,宏块整个宏块的预测信息相同,因此不需要为各个子宏块分别指定预测模式,这样可以有效减少消耗的码流。

(2). transform_size_8x8_flag

该语法元素为一个标识位,用于表示在环路滤波之前,预测残差的变换系数解码时依照的尺寸。当该标识位为1时,预测残差按照8×8像素块进行解码;当该标志位不存在或者为0时,预测残差按照4×4像素块进行解码。

(3). coded_block_pattern

coded_block_pattern语法元素常简称做cbp,用于表示当前宏块内的4个8×8子块编码对其中的哪个的残差系数进行编码。值得注意的是该语法元素仅仅在宏块为非I_16x16模式时才存在,因为在I_16x16模式时cbp的有关信息已经在mb_type中体现。

(4). mb_qp_delta

mb_qp_delta表示宏块层的量化参数偏移值,取值范围为[-26, 25]。我们在前面已经在PPS中获取了整个序列的量化参数初始值(由pic_init_qp_minus26计算),在slice header中获取slice层的量化参数偏移slice_qp_delta,因此每一个slice第一个宏块的量化参数可通过下面的公式计算: QP_0=pic\_init\_qp+26+slice\_qp\_delta+mb\_qp\_delta
从第二个宏块开始,每个宏块实际量化参数的计算方法为:
QP_n = (QP_m+mb\_qp\_delta+52)\%52

在以H.264格式编码的视频码流中,宏块结构必然包含预测结构(I_PCM模式除外),该结构中包含了像素块的预测模式等信息。对于不同预测模式的宏块,其预测结构是不同的。从上篇的宏块结构中,可以看出,对于部分模式,预测信息保存于mb_pred()结构中,而对于另一部分模式则采用sub_mb_pred()结构。

在我们本系列的H.264分析器SimpleH264Analyzer项目中默认的全I帧测试码流中,我们所分析的第一个IDR帧的第一个宏块,其mb_type为I_NxN。实际上,对于除了I_PCM模式之外的所有Intra宏块,其预测结构均采用mb_pred()结构。

在标准文档中,mb_pred()的定义如下表所示(只看Intra模式下):


image.png

从表中可以看出,Intra预测模式的结构主要有两组,分别表示4×4和8×8模式,每一组包含两个元素,分别表示预测模式标识位和预测模式值,以及最后的色度分量预测模式。

上一篇 下一篇

猜你喜欢

热点阅读