切片中保存的是原始的图像数据
一个切片包含一帧图片的部分或全部数据,即一帧视频图像可以编码为一个或若干个切片

H.264标准中共定义了5种Slice类型:

  • I slice: 帧内编码的条带;
  • P slice: 单向帧间编码的条带;
  • B slice: 双向帧间编码的条带;
  • SI slice: 切换I条带,用于扩展档次中码流切换使用;
  • SP slice: 切换P条带,用于扩展档次中码流切换使用;

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

Slice格式
image.png

image.png

image.png
image.png

slice header

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

first_mb_in_slice 当前slice中包含的第一个宏块在整帧中的位置
slice_type 指示当前slice的类型,如下表。当slice_type为5~9的时候,就表明要求当前图像的其他slice为slice_type%5,也就是要求当前图像slice_type一致
image.png
pic_parameter_set_id 当前slice所依赖的pps的id
colour_plane_id 当标识位separate_colour_plane_flag为true时,colour_plane_id表示当前的颜色分量,0、1、2分别表示Y、U、V分量
frame_num 用于POC计算
field_pic_flag 当前slice是否进行的是场编码。当该标识位为1时表示当前slice按照场进行编码;该标识位为0时表示当前slice按照帧进行编码。
bottom_field_flag 当前slice是否在低场。该标志位为1表示当前slice是某一帧的底场;为0表示当前slice为某一帧的顶场。
idr_pic_id 表示IDR帧的序号。某一个IDR帧所属的所有slice,其idr_pic_id应保持一致。该值的取值范围为[0,65535]。
pic_order_cnt_lsb
delta_pic_order_cnt_bottom
delta_pic_order_cnt
用于POC的计算
redundant_pic_cnt 冗余图像编码相关
direct_spatial_mv_pred_flag 1:B帧direct编码采用空域预测方式
0:B帧direct编码采用时域预测
num_ref_idx_active_override_flag 当前slice的参考帧列表是否采用以下两个长度而不用PPS规定的长度
num_ref_idx_l0_active_minus1 前向参考帧列表长度
num_ref_idx_l1_active_minus1 后向参考帧列表长度
ref_pic_list_modification 参考帧列表重排序的参数结构语法
见参考帧列表重排序语法分析
pred_weight_table 加权预测的参数结构语法
dec_ref_pic_marking 解码的参考图像标识语法
cabac_init_idc cabac中m、n表的索引
slice_qp_delta pic_init_qp_minus26 + 26 + slice_qp_delta将成为当前slice的初始QP
disable_deblocking_filter_idc
slice_alpha_c0_offset_div2
slice_beta_offset_div2
deblocking相关参数

slice body

一个Slice的body部分主要是一个个的宏块结构Macroblock组成,此外还存在一些辅助的信息。标准文档中规定的slice_data()结构如下图:
image.png

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

cabac_alignment_one_bit 表示如果码流启用了CABAC算法,那么码流在这里必须使用若干个比特1实现字节对齐。
mb_skip_run
mb_skip_flag
这两个语法元素都用于表示宏块结构是否可以被跳过。“跳过”的宏块指的是,在帧间预测的slice中,当图像区域平坦时,码流中跳过这个宏块的所有数据,不进行传输,只通过这两个语法元素进行标记。在解码端,跳过的宏块通过周围已经重建的宏块来进行恢复。mb_skip_run用于熵编码使用CAVLC时,用一个语法元素表示连续跳过的宏块的个数;mb_skip_flag用于熵编码使用CABAC时,表示每一个宏块是否被跳过。

- mb_skip_run 如果当前采用的是CAVLC编码方式,则会采用这个语法元素来表达skip宏块(P_Skip,B_Skip),mb_skip_run代表的是当前这个宏块以及它的后面共有多少个跳过宏块,并且后面的skip宏块都不会被编码。
- mb_skip_flag 如果当前采用的是CABAC编码方式,则会采用这个语法元素来表达skip宏块(P_Skip,B_Skip),跟mb_skip_run不同的是,每个skip宏块都有一个mb_skip_flag
macroblock_layer 如果不是为skip宏块的话,则表明本宏块有编码的数据,因此会进去macroblock_layer
mb_field_decoding_flag 标识位,用于在帧场自适应的码流中标识某个宏块是帧模式还是场模式
end_of_slice_flag 如果采用的是CABAC编码方式,还会用这个标记来表达当前宏块是否为这个slice的最后一个宏块

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