ZigZag Sin
登 陆
后面没有了 上一篇:Slice 是什么

Slice Header

乔红
2021-2-9 15:26 阅读 4870

引言

上一小节我们大体将 Slice 分成了 Slice Header 和 Slice Body 两个部分,本小结我们来看一下 Slice Header 中存放了哪些东西。

先上标准文档

OPEN GOP

Slice Header 中的内容也全部是由指数哥伦布熵编码进行编码的,所以我们可以直接按照 SPS 和 PPS 的解析方式进行解析。这里就不做重复阐述了,我们选择几个比较重要的属性来看看。

first_mb_in_slice

我们先来看第一个属性,first_mb_in_slice,这个属性表示的是在这个 Slice 中第一个宏块的序号。我们在介绍 SPS 和 PPS 的时候,简单介绍了一下宏块的概念,我们已经有了一些宏块的概念,知道 H.264 是按照宏块来压缩的。那么 first_mb_in_slice 这个属性是什么意思呢?

要解释 first_mb_in_slice 这个属性,首先要讲明白一点,那就是 Slice 不是帧。我们经常在博客中看到一些说法,例如:这个 NALU 是一个 I 帧,这个 NALU 是一个 P 帧。其实这些说法严格意义上来说都是不太对的。

在编码的时候,一帧图像首先会被分割成若干宏块,然后对每个宏块进行编码压缩,之后,会将宏块写入到 Slice 里面,最后再加上一些修饰变成 NALU。这个过程中有一点要注意,那就是一帧图像产生宏块,不一定要写到一个 Slice 里面。

例如,我将一帧图像编码成了 99 个宏块,我可以把这 99 个宏块都写到一个 Slice 里面,也可以把 0 - 30 的宏块写到一个 Slice 里面,然后把 31-99 的宏块写到下一个宏块里。因此,first_mb_in_slice 这个属性要描述的,就是在当前这个 Slice 里面的第一个宏块,对应的是帧里的第几个宏块。

举个例子:

OPEN GOP

在上图中,我们把一帧图像分割成序号为 0-23 共计 24 个宏块。我们把蓝色背景的宏块放到一个 Slice 里面,这个 Slice 的 first_mb_in_slice 就是 0。然后我们把红色背景的宏块放到另外一个 Slice 里面,这个 Slice 的 first_mb_in_slice 就是 14。

slice_type

在 first_mb_in_slice 属性之后,就是 slice_type 了。很明显,这个属性来指明的是 slice 的类型。这个类型的可能的值如下表:

含义
0P(P Slice)
1B(B Slice)
2I(I Slice)
3SP(SP Slice)
4SI(SI Slice)
5P(P Slice)
6B(B Slice)
7I(I Slice)
8SP(SP Slice)
9SI(SI Slice)

注意,这张表里的 slice_type 其实 5-9 和 0-4 是完全相同的,因此在使用的时候,我们也常常直接用 slice_type 对 5 去余来处理。

可以看到 slice_type 规定了 slice 的类型,这也解释了之前的一些误区。有人说根据 NALU 的类型就能判读是 I Slice 还是 P Slice 还是 B Slice。其实是错误的,要判断这些必须要读到 slice_type 才行。

pic_parameter_set_id

slice_type 之后,是 pic_parameter_set_id,这个属性表明该 Slice 要依赖的 PPS 的 id。我们在解析 PPS 的时候,PPS 里面有一个 pic_parameter_set_id 的属性。当你解析出 Slice 中的 pic_parameter_set_id 之后,拿着这个 id 找到与之对应的 PPS 就可以了。然后 PPS 里还有个 seq_parameter_set_id,用这个 id 就可以找到依赖的 SPS 的 id。这样,你就可以为这个 Slice 查找到合适的 SPS 和 PPS 了。

SPS

后面没有了 上一篇:Slice 是什么
给我买个键盘吧。。。求打赏。。。
欢迎加群,一起交流~~~

643401840@qq.com

牛批!

2022-03-23 19:21:27

zekun@sina.cn

学习了,大赞!

2021-12-23 15:44:12