H.264(九)Slice数据和宏块结构

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_40732350/article/details/89606483

1 Slice的组成

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

 

2 Slice Data结构的定义

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

Slice Data语法表:

cabac_alignment_one_bit 当熵编码模式是 CABAC 时,此时要求数据字节对齐,即数据从下一个字节的第一个比特开始,如果还没有字节对齐将出现若干个 cabac_alignment_one_bit 作为填充。

mb_skip_run 当图像采用帧间预测编码时, H.264 允许在图像平坦的区域使用“跳跃”块, “跳跃”块本身不携带任何数据,解码器通过周围已重建的宏块的数据来恢复“跳跃”块。

在表 我们可以看到,当熵编码为 CAVLC 或 CABAC 时, “跳跃”块的表示方法不同。

  • 当entropy_coding_mode_flag 为 1,即 熵 编 码 为 CABAC 时 , 是 每 个 “ 跳 跃 ” 块 都 会 有 句 法 元 素 mb_skip_flag 指 明。
  • 当entropy_coding_mode_flag 等于 0,即熵编码为 CAVLC 时,用一种行程的方法给出紧连着的“跳跃”块的数目,即句法元素mb_skip_run。 mb_skip_run 值的范围 0 to PicSizeInMbs – CurrMbAddr 。

这两个语法元素都用于表示宏块结构是否可以被跳过。“跳过”的宏块指的是,在帧间预测的slice中,当图像区域平坦时,码流中跳过这个宏块的所有数据,不进行传输,只通过这两个语法元素进行标记。在解码端,跳过的宏块通过周围已经重建的宏块来进行恢复。mb_skip_run用于熵编码使用CAVLC时,用一个语法元素表示连续跳过的宏块的个数;mb_skip_flag用于熵编码使用CABAC时,表示每一个宏块是否被跳过。

mb_skip_flag 见上一条, 指明当前宏块是否是跳跃编码模式的宏块。

mb_field_decoding_flag 在帧场自适应图像中,指明当前宏块所属的宏块对是帧模式还是场模式。 0 帧模式; 1 场模式。如果一个宏块对的两个宏块句法结构中都没有出现这个句法元素,即它们都是“跳跃”块时,本句法元素由以下决定:

  • 如果这个宏块对与相邻的、左边的宏块对属于同一个片时,这个宏块对的 mb_field_decoding_flag的值等于左边的宏块对的 mb_field_decoding_flag 的值。
  • 否 则 , 这 个 宏 块 对 的 mb_field_decoding_flag 的 值 等 于 上 边 同 属 于 一 个 片 的 宏 块 对 的mb_field_decoding_flag 的值。
  • 如果这个宏块对既没有相邻的、上边同属于一个片的宏块对;也没有相邻的、左边同属于一个片的宏块对,这个宏块对的 mb_field_decoding_flag 的值等于 0,即帧模式。

end_of_slice_flag 在CABAC模式下的一个标识位,表示是否到了slice的末尾。

 

3 H.264的宏块Macroblock

宏块(Macroblock):

  • 编码视频信息的基本单元;
  • 在编码过程中提供了较强的灵活性;

一帧图像划分为多个宏块,每个宏块包含:

  • 1个16×16像素的亮度像素块
  • 两个8×8像素的色度像素块;

常用宏块类型:

  • I宏块:采用帧内预测宏块,可能位于I/B/P帧;
  • P宏块:采用单向帧间预测,只存在于P帧;
  • B宏块:采用双向帧间预测,只存在于B帧;

根据宏块类型的不同,宏块在码流中采用不同结构的语法元素表示

mb_type 指明当前宏块的类型。 H.264规定,不同的片中允许出现的宏块类型也不同。下表指明在各种片类型中允许出现的宏块种类。

                                                                                各种片中允许出现的宏块类型

片类型 允许出现的宏块种类
I (slice) I 宏块
P (slice) P 宏块、 I 宏块
B (slice) B 宏块、 I 宏块
SI (slice) SI 宏块、 I 宏块
SP (slice) P 宏块、 I 宏块

可以看到, I 片中只允许出现 I 宏块,而 P 片中即可以出现 P 宏块也可以出现 I 宏块,也就是说,在帧间预测的图像中也可以包括帧内预测的图像。其它片也有类似情况。
每一种宏块包含许多的类型。比起以往的视频编码标准, H.264 定义了更多的宏块的类型。

在帧间预测模式下,宏块可以有七种运动矢量的划分方法。
在帧内预测模式下,可以是帧内 16x16 预测,这时可以宏块有四种预测方法,即四种类型;也可以是 4x4 预测,这时每个 4x4 块可以有九种预测方法,整个宏块共有 144 种类型。

mb_type 并不能描述以上所有有关宏块类型的信息。事实上可以体会到, mb_tye 是出现在宏块层的第一个句法元素,它描述跟整个宏块有关的基本的类型信息。在不同的片中 mb_type 的定义是不同的,下面我们分别讨论 I、 P、 B 片中这个句法元素的意义。
a) I 片中的 mb_type

mb_type 类型名称 预测方式 帧内16x16的预测模式 CodedBlockPatternChroma CodedBlockPatternLuma
0 I_4x4 Intra_4x4
1 I_16x16_0_0_0 Intra_16x16 0 0 0
2 I_16x16_1_0_0 Intra_16x16 1 0 0
3 I_16x16_2_0_0 Intra_16x16 2 0 0
4 I_16x16_3_0_0 Intra_16x16 3 0 0
5 I_16x16_0_1_0 Intra_16x16 0 1 0
6 I_16x16_1_1_0 Intra_16x16 1 1 0
7 I_16x16_2_1_0 Intra_16x16 2 1 0
8 I_16x16_3_1_0 Intra_16x16 3 1 0
9 I_16x16_0_2_0 Intra_16x16 0 2 0
10 I_16x16_1_2_0 Intra_16x16 1 2 0
11 I_16x16_2_2_0 Intra_16x16 2 2 0
12 I_16x16_3_2_0 Intra_16x16 3 2 0
13 I_16x16_0_0_1 Intra_16x16 0 0 15
14 I_16x16_1_0_1 Intra_16x16 1 0 15
15 I_16x16_2_0_1 Intra_16x16 2 0 15
16 I_16x16_3_0_1 Intra_16x16 3 0 15
17 I_16x16_0_1_1 Intra_16x16 0 1 15
18 I_16x16_1_1_1 Intra_16x16 1 1 15
19 I_16x16_2_1_1 Intra_16x16 2 1 15
20 I_16x16_3_1_1 Intra_16x16 3 1 15
21 I_16x16_0_2_1 Intra_16x16 0 2 15
22 I_16x16_1_2_1 Intra_16x16 1 2 15
23 I_16x16_2_2_1 Intra_16x16 2 2 15
24 I_16x16_3_2_1 Intra_16x16 3 2 15
25 I_PCM

表中 , Intra_4x4 表示使用帧内 4x4 预测, Intra_16x16 表示使用帧内 16x16 预测。 当使用帧内 16x16时,类型名称由了如下的结构组成:                                                                 I_16x16_x_y_z

其中, x 对应于表中“帧内 16x16 的预测模式”字段的值, y 对应于表中“色度 CBP”字段的值, z 对应于表中“亮度 CBP”的值。

  • 帧内 16x16 的预测模式:当使用帧内 16x16 预测时,指定使用何种预测方式,帧内 16x16 共有四种预测模式,第八章中会详细介绍这些预测模式的算法。
  • CodedBlockPatternLuma:指定当前宏块色度分量的 CBP, CBP(CodedBlockPattern)是指子宏块残差的编码方案。该变量详细语义见 coded_block_pattern 条目。
  • 亮度 CBP:指定当前宏块亮度分量的 CBP,详细语义见 coded_block_pattern 条目。

我们看到,帧内 16x16 宏块类型的 mb_type 语义原比其它宏块类型的复杂,这是因为当使用帧内 16x16 时,整个宏块是一个统一的整体,宏块中各子宏块、 4x4 小块的预测模式信息都是相同的,所以可以把这些信息放入 mb_type ,以减少码流。其它宏块类型的这些信息必须在各子块中另外用句法元素指明。

b) P 片中的 mb_type 。

mb_type 类型名称 宏块分区数目 预测模式
( mb_type,0 )
预测模式
( mb_type, 1 )
宏块分区宽度
( mb_type )
宏块分区高度
( mb_type )
0 P_L0_16x16 1 Pred_L0 16 16
1 P_L0_L0_16x8 2 Pred_L0 Pred_L0 16 8
2 P_L0_L0_8x16 2 Pred_L0 Pred_L0 8 16
3 P_8x8 4 8 8
4 P_8x8ref0 4 8 8
P_Skip 1 Pred_L0 16 16

在表 7.26 中,Pred_L0 表示用 L0,即前向预测。如果当前宏块的 mb_type 等于 0 到 4, mb_type 的含义见 表 7.26;当 mb_type 等于 5 到 30 时, mb_type 的含义见 表 7.25, 用 mb_type-5 所得到的值来进行查找。预测模式(mb_type,n)预测模式是 mb_type 的函数, n 是宏块的第 n 个分区。

c) B 片中的 mb_type
如果当前宏块是属于 B 片且 mb_type 等于 0 到 22, mb_type 的含义见 表 7-11;当 mb_type 等于23 到 48 时, mb_type 的含义见 表 7-8, 用 mb_type-23 所得到的值来进行查找。

mb_type 类型名称 宏块分区数目
( mb_type )
预测模式
( mb_type, 0 )
预测模式
( mb_type, 1 )
宏块分区宽度
( mb_type )
宏块分区高度
( mb_type )
0 B_Direct_16x16 Direct 8 8
1 B_L0_16x16 1 Pred_L0 16 16
2 B_L1_16x16 1 Pred_L1 16 16
3 B_Bi_16x16 1 BiPred 16 16
4 B_L0_L0_16x8 2 Pred_L0 Pred_L0 16 8
5 B_L0_L0_8x16 2 Pred_L0 Pred_L0 8 16
6 B_L1_L1_16x8 2 Pred_L1 Pred_L1 16 8
7 B_L1_L1_8x16 2 Pred_L1 Pred_L1 8 16
8 B_L0_L1_16x8 2 Pred_L0 Pred_L1 16 8
9 B_L0_L1_8x16 2 Pred_L0 Pred_L1 8 16
10 B_L1_L0_16x8 2 Pred_L1 Pred_L0 16 8
11 B_L1_L0_8x16 2 Pred_L1 Pred_L0 8 16
12 B_L0_Bi_16x8 2 Pred_L0 BiPred 16 8
13 B_L0_Bi_8x16 2 Pred_L0 BiPred 8 16
14 B_L1_Bi_16x8 2 Pred_L1 BiPred 16 8
15 B_L1_Bi_8x16 2 Pred_L1 BiPred 8 16
16 B_Bi_L0_16x8 2 BiPred Pred_L0 16 8
17 B_Bi_L0_8x16 2 BiPred Pred_L0 8 16
18 B_Bi_L1_16x8 2 BiPred Pred_L1 16 8
19 B_Bi_L1_8x16 2 BiPred Pred_L1 8 16
20 B_Bi_Bi_16x8 2 BiPred BiPred 16 8
21 B_Bi_Bi_8x16 2 BiPred BiPred 8 16
22 B_8x8 4 8 8
B_Skip Direct 8 8

表中, Pred_L0 表示使用 L0,即前向预测, Pred_L1 表示使用 L1,即后向预测, Bipred 表示双向预测, Direct 表示直接预测模式。预测模式(mb_type,n)预测模式是 mb_type 的函数, n 是宏块的第n 个分区。

pcm_alignment_zero_bit 等于 0。
pcm_byte[ i ] 像 素 值 。 前 256 pcm_byte[ i ] 的 值 代 表 亮 度 像 素 的 值 , 下 一 个
( 256 * ( ChromaFormatFactor - 1 ) ) / 2 个 pcm_byte[ i ] 的 值 代 表 Cb 分 量 的 值 . 最 后 一 个
( 256 * ( ChromaFormatFactor - 1 ) ) / 2 个 pcm_byte[ i ]的值代表 Cr 分量的值。

coded_block_pattern 即 CBP,指亮度和色度分量的各小块的残差的编码方案,所谓编码方案有以下几种:
a) 所有残差(包括 DC、 AC)都编码。
b) 只对 DC 系数编码。
c) 所有残差(包括 DC、 AC)都不编码。
这个句法元素同时隐含了一个宏块中亮度、色度分量的 CBP,所以第一步必须先分别解算出各分量各自 CBP 的值。其中,两个色度分量的 CBP 是相同的。变量 CodedBlockPatternLuma 是亮度分量的 CBP,变量 CodedBlocPatternChroma 是色度分量的 CBP:
对于非 Intra_16x16 的宏块类型:

CodedBlockPatternLuma = coded_block_pattern % 16;
CodedBlockPatternChroma = coded_block_pattern / 16;

对于Intra_16x16宏块类型, CodedBlockPatternLuma 和CodedBlockPatternChroma 的值不是由本
句法元素给出,而是通过mb_type得到。

  • CodedBlockPatternLuma:是一个16位的变量,其中只有最低四位有定义。由于非Intra_16x16的宏块不单独编码DC系数,所以这个变量只指明两种编码方案:残差全部编码或全部不编码。变量的最低位比特从最低位开始,每一位对应一个子宏块,该位等于1时表明对应子宏块残差系数被传送;该位等于0时表明对应子宏块残差全部不被传送,解码器把这些残差系数赋为0。
  • CodedBlockPatternChroma:当值为0、 1、 2时有定义,见下表。

                                                               CodedBlockPatternChroma 的定义

CodedBlockPatternChroma 定义
0 所有残差都不被传送,解码器把所有残差系数赋为0。
1 只有DC系数被传送,解码器把所有AC系数赋为0。
2 所有残差系数(包括DC、 AC)都被传送。解码器用接收到的残差系
数重建图像。

mb_qp_delta 在宏块层中的量化参数的偏移值。 mb_qp_delta 值的范围是 -26 to +25。 量化参数是在图像参数集、片头、宏块分三层给出的,最终用于解码的量化参数由以下公式得到:

QPY = ( QPY,PREV + mb_qp_delta + 52 ) % 52;

QPY,PREV 是当前宏块按照解码顺序的前一个宏块的量化参数,我们可以看到, mb_qp_delta 所指示的偏移是前后两个宏块之间的偏移。而对于片中第一个宏块的 QPY,PREV 是由 7-16 式给出

QPY,PREV = 26 + pic_init_qp_minus26 + slice_qp_delta;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

展开阅读全文

没有更多推荐了,返回首页