既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
5.H264码流结构
我认为在具体讲述NAL单元前,十分有必要先了解一下H264的码流结构;在经过编码后的H264的码流如图4所示,
从图中我们需要得到一个概念,H264码流是由一个个的NAL单元组成,其中SPS、PPS、IDR和SLICE是NAL单元某一类型的数据。
图4
6、H264的NAL单元
6.1、H264的NAL结构
在实际的网络数据传输过程中H264的数据结构是以NALU(NAL单元)进行传输的,传输数据结构组成为[NALU Header]+[RBSP],如图5所示:
图5
从之前的分析我们可以知道,VCL层编码后的视频帧数据,帧有可能是I/B/P帧,这些帧也可能是属于不同的序列之中;同一序列也还有相应的序列参数集与图片参数集;综上所述,想要完成准确无误视频的解码,除了需要VCL层编码出来的视频帧数据,同时还需要传输序列参数集和图像参数集等等,所以RBSP不单纯只保存I/B/P帧的数据编码信息,还有其他信息也可能出现在里面。
上面知道NAL单元是作为实际视频数据传输的基本单元,NALU头是用来标识后面RBSP是什么类型的数据,同时记录RBSP数据是否会被其他帧参考以及网络传输是否有错误,所以针对NAL头和RBSP的作用以及结构与所承载的数据需要做个简单的了解;
6.2、NAL头
一、 NAL头的组成
NAL单元的头部是由forbidden_bit(1bit),nal_reference_bit(2bits)(优先级),nal_unit_type(5bits)(类型)三个部分组成的,组成如图6所示:
1、F(forbiden):禁止位,占用NAL头的第一个位,当禁止位值为1时表示语法错误;
2、NRI:参考级别,占用NAL头的第二到第三个位;值越大,该NAL越重要。
3、Type:Nal单元数据类型,也就是标识该NAL单元的数据类型是哪种,占用NAL头的第四到第8个位;
图6
二、 NAL单元数据类型
NAL类型主要就是下面图7中这些类型每个类型都有特殊的作用;
图 7
图 8
在具体介绍NAL数据类型前,有必要知道
NAL分为VCL和非VCL的NAL单元。在图8中有介绍(图表中DIR应该为IDR),其中SPS、SEI、PPS等非VCL的NAL参数对解码和显示视频都是很有用的。
而另外一个需要了解的概念就是
参数集(Parameter sets),参数集是携带解码参数的NAL单元,参数集对于正确解码是非常重要的,在一个有损耗的传输场景中,传输过程中比特列或包可能丢失或损坏,在这种网络环境下,参数集可以通过高质量的服务来发送,比如向前纠错机制或优先级机制。Parameter sets与其之外的句法元素之间的关系如图9所示:
图 9
每种类型都有代表一种数据类型,比较重要的以下几种做个简单的介绍:
1、非VCL的NAL数据类型:
1)、SPS(序列参数集):SPS对如标识符、帧数以及参考帧数目、解码图像尺寸和帧场模式等
解码参数进行标识记录。
2)、PPS(图像参数集):PPS对如熵编码类型、有效参考图像的数目和初始化等解码参数进行标志记录。
3)、SEI(补充增强信息):这部分参数可作为H264的比特流数据而被传输,每一个SEI信息被封装成一个NAL单元。SEI对于解码器来说可能是有用的,但是对于基本的解码过程来说,并不是必须的。
@:先标记一下,SPS、PPS内容是编码器给的。(出处的话,慢慢研究)
2、VCL的NAL数据类型
1)、 头信息块,包括宏块类型,量化参数,运动矢量。这些信息是最重要的,因为离开他们,被的数据块种的码元都无法使用。该数据分块称为A类数据分块。
2)、 帧内编码信息数据块,称为B类数据分块。它包含帧内编码宏块类型,帧内编码系数。对应的slice来说,B类数据分块的可用性依赖于A类数据分块。和帧间编码信息数据块不通的是,帧内编码信息能防止进一步的偏差,因此比帧间编码信息更重要。
3)、 帧间编码信息数据块,称为C类数据分块。它包含帧间编码宏块类型,帧间编码系数。它通常是slice种最大的一部分。帧间编码信息数据块是不重要的一部分。它所包含的信息并不提供编解码器之间的同步。C类数据分块的可用性也依赖于A类数据分块,但于B类数据分块无关。
以上三种数据块每种分割被单独的存放在一个NAL单元中,因此可以被单独传输。
6.3、
H264的
NAL单元
与片,宏之间的联系
其实到这里可能就比较难理解了,为什么数据NAL单元中有这么多数据类型,这个SLICE又是什么东西,为什么不直接是编码后出来的
原始字节序列载荷,所以
我觉得在这里再讲述帧所细分的一些片和宏的概念应该是比较合适的,也是能够参照上下文更能理解这些概念的位置,又能给这些困惑做一个合理一点的解释,所以在此做一个描述:
1帧(一幅图像) = 1~N个片(slice) //也可以说1到多个片为一个片组
1个片 = 1~N个宏块(Marcroblock)
1个宏块 = 16X16的YUV数据(原始视频采集数据)
从数据层次角度来说,一幅原始的图片可以算作广义上的一帧,帧包含片组和片,片组由片来组成,片由宏块来组成,每个宏块可以是4*4、8*8、16*16像素规模的大小,它们之间的联系如图10所示。每个片都是一个独立的编码单位。
图10
从容纳数据角度来说,NAL单元除了容纳Slice编码的码流外,还可以容纳其他数据,这也就是为什么有SPS、PPS等这些数据出现的原因,并且这些数据在传输H264码流的过程中起到不可或缺的作用,具体作用上面也是有讲到的。
那么也就可以对下面这些概念做一个大小的排序了:
序列>图像>片>宏>像素(当然还有片组、亚宏块等等这些概念,初步了解就不了解这么深了,后面再慢慢研究)
同时有几点需要说明一下,这样能便于理解NAL单元:
(1)、如果
不采用 FMO(灵活宏块排序)
机制,则
一
幅图像只有一个片组
;
(2)、如果
不使用多个片,则一个片组只有一个片;
(3)、如果
不采用
DP(
数据分割
)机制,则
一
个片就是一个 NALU,一个 NALU 也就是一个片
。
否则,一个片的组成需要由 三个 NALU 组成,也就是上面说到的A、B、C类数据块。
这时候在看下面这幅码流数据分层图11就比较能理解整体的码流结构组成了;
图11
如我们所见,每个分片也包含着头和数据两部分,分片头中包含着分片类型、分片中的宏块类型、分片帧的数量以及对应的帧的设置和参数等信息,而分片数据中则是宏块,这里就是我们要找的存储像素数据的地方;宏块是视频信息的主要承载者,因为它包含着每一个像素的亮度和色度信息。视频解码最主要的工作则是提供高效的方式从码流中获得宏块中的像素阵列。宏块数据的组成如下图12所示:
图12
从上图中,可以看到,宏块中包含了宏块类型、预测类型、Coded Block Pattern、Quantization Parameter、像素的亮度和色度数据集等等信息。
至此,我们对 H.264 的码流数据结构应该有了一个大致的了解。
需要注意的几点:
H.264/AVC标准对送到解码器的NAL单元顺序是有严格要求的,如果NAL单元的顺序是混乱的,必须将其重新依照规范组织后送入解码器,否则解码器不能够正确解码。
1.序列参数集NAL单元 必须在传送所有以此参数集为参考的其他NAL单元之前传送,不过允许这些NAL单元中间出现重复的序列参数集NAL单元。所谓重复的详细解释为:序列参数集NAL单元都有其专门的标识,如果两个序列参数集NAL单元的标识相同,就可以认为后一个只不过是前一个的拷贝,而非新的序列参数集。
2.图像参数集NAL单元 必须在所有以此参数集为参考的其他NAL单元之前传送,不过允许这些NAL单元中间出现重复的图像参数集NAL单元,这一点与上述的序列参数集NAL单元是相同
总结:
暂时就整理这么多,可能有些描述不准确、不合理或有误的地方,希望各位前辈多多指正,我会尽量完善,至于有些不够详尽的地方会在后面找时间填补上去;本篇只是结合我个人的理解习惯做的归纳整理,下面这些学习资料也在一些概念上更加详尽,想要更加深入的了解以上某些具体概念的,不妨点进去学习;
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
习资料也在一些概念上更加详尽,想要更加深入的了解以上某些具体概念的,不妨点进去学习;
[外链图片转存中…(img-77R49xGs-1715628528077)]
[外链图片转存中…(img-SVBIRrqX-1715628528078)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新