1 Slice基本概念

一个视频图像可编码成一个或更多个条带(slice),每个条带(slice)包含整数个宏块(MB),即每个条带至少一个 MB,最多时每个条带包含整个图像的宏块。总之,一幅图像中每个条带的宏块数不一定固定。 设条带的目的是为了限制误码的扩散和传输,每个编码条带相互间是独立的。某个条带的预测不能以其它条带中的宏块为参考图像,这样某一条带中的预测误差才不会传播到其它条带中去。

一帧有多少个条带,是根据PPS中的num_slice_groups_minus1决定的。一般来说,都是一帧是一个Slice。

alt text

2 Slice类型

根据码流中不同的数据类型,H264 中定义了 5 中 slice 类型:

alt text

  • I Slice:是指每个块或宏块是通过其所在的 Slice 中的之前的(帧内)已经编码过的数据进行预测的;

  • P Slice:是指宏快或宏块分割是通过 List0 中的一个参考图像来进行预测的;

  • B Slice:是指宏快或宏块分割是通过 List0 和 / 或 List1 中的参考图像来进行预测的;

  • SI Slice:切换I条带,用于扩展档次中码流切换使用;

  • SP Slice:切换P条带,用于扩展档次中码流切换使用;

3 Slice每个字段含义

  • first_mb_in_slice:当前slice中包含的第一个宏块在整帧中的位置;

  • field_pic_flag:场编码标识位。当该标识位为1时表示当前slice按照场进行编码;该标识位为0时表示当前slice按照帧进行编码。

  • bottom_field_flag:底场标识位。该标志位为1表示当前slice是某一帧的底场;为0表示当前slice为某一帧的顶场。

  • idr_pic_id:表示IDR帧的序号。某一个IDR帧所属的所有slice,其idr_pic_id应保持一致。IDR 图像的标识。不同的 IDR 图像有不同的 idr_pic_id 值。值得注意的是, IDR 图像有不等价于 I 图像,只有在作为 IDR 图像的 I 帧才有这个句法元素,在场模式下, IDR 帧的两个场有相同的 idr_pic_id 值。 idr_pic_id 的取值范围是 [0, 65535],和 frame_num 类似,当它的值超出这个范围时,它会以循环的方式重新开始计数。

  • pic_order_cnt_lsb:可以用来计算帧的显示顺序POC。

  • delta_pic_order_cnt_bottom:表示顶场与底场POC差值的计算方法,不存在则默认为0。

  • slice_qp_delta:出在用于当前片的所有宏块的量化参数的初始值。

  • frame_num:当参数集中的句法元素gaps_in_frame_num_value_allowed_flag不为1时,每个图像的frame_num值是它前一个参考帧的frame_num值增加1.比如:

    alt text

  • slice_typealt text

4 如何区别IDR帧和I帧

上图中,查了资料也不知道 slice_type == 2 是I帧,slice_type == 7 是IDR是否正确。

但是通过NALU Header判断,nal_unit_type == 5 一定是IDR帧。

参考

参考1:H.264数据解析

参考2:H264 编码 —slice