音视频(四)视频流H264的组装原理切片NAL单元,视频流H264码流分析实战

·  阅读 367

这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

视频流H264的组装

音视频高手进阶(四),争取让小白都能看懂,由于篇幅原因,一次无法完全整合成一篇文章,所以分几次发表,如有需要完整PDF文档,可去我主页简介联系我拿PDF版本

1 H264介绍

我们了解了什么是宏快,宏快作为压缩视频的最小的一部分,需要被组织,然后在网络之间做相互传输。

如果单纯的用宏快来发送数据是杂乱无章的,就好像在没有集装箱 出现之前,货物总是随意被堆放到船上。

上货,下货是非常痛苦的。 当集装箱出现之后,一切都发生了改变,传输效率大大增高。

集装箱可以理解成H264编码标准,他制定了相互传输的格式,将宏快 有组织,有结构,有顺序的形成一系列的码流。这种码流既可 通过 InputStream 网络流的数据进行传输,也可以封装成一个文件进行保存

H264: H264/AVC是广泛采用的一种编码方式。 主要作用是为了传输

1.1 H264码流组成

组成H264码流的结构中 包含以下几部分 ,从大到小排序依次是

H264视频序列,图像,片组,片,NALU,宏块 ,像素。

类似 地球 国家 城市 镇 村落

1.1.1 H264编码分层
  • NAL层:(Network Abstraction Layer,视频数据网络抽象层) : 它的作用是H264只要在网络上传输,在传输的过程每个包以太网是1500字节,而H264的帧往往会大于1500字节,所以要进行拆包,将一个帧拆成多个包进行传输,所有的拆包或者组包都是通过NAL层去处理的。
  • VCL层:(Video Coding Layer,视频数据编码层) : 对视频原始数据进行压缩
1.1.2 H264的传输

H264是一种码流 类似与一种不见头,也不见尾的一条河流。如何从和流中取到自己想要的数据呢,

在H264的标砖中有这样的一个封装格式叫做"Annex-B"的字节流格式。 它是H264编码的主要字节流格式。

几乎市面上的编码器是以这种格式进行输出的。起始码0x 00 00 00 01 或者 0x 00 00 01 作为分隔符

两个 0x 00 00 00 01之间的字节数据 是表示一个NAL Unit

1.1.3 编码结构

切片头:包含了一组片的信息,比如片的数量,顺序等等

1.1.4 H264码流分层结构图

视频流H264码流分析实战

1.1 H.264编码格式

H.264的功能分为两层:

  • 视频编码层
  • 网络提取层

VCL数据即编码处理的输出,它表示被压缩编码后的视频数据序列。在VCL数据传输或存储之前,这些编码的VCL数据,先被映射或封装进NAL单元中。

每个NAL单元包括一个原始字节序列负荷(RBSP)、一组对应于视频编码的NAL头信息

RBSP的基本结构是:在原始编码数据的后面填加了结尾比特。一个bit“1”若干比特“0”,以便字节对齐。

1.2 H.264网络传输

H.264的编码视频序列包括一系列的NAL单元,每个NAL单元包含一个RBSP

见表1。编码片(包括数据分割片IDR片)和序列RBSP结束符被定义为VCL NAL单元,其余为NAL单元。

典型的RBSP单元序列如图2所示。

每个单元都按独立的NAL单元传送。单元的信息头(一个字节)定义了RBSP单元的类型,NAL单元的其余部分为RBSP数据。

  1. 2.1 H.264码流结构图

起始码:如果NALU对应的Slice为一帧的开始,则用4字节表示,即0x00000001;否则用3字节表示,0x000001。 NAL Header:forbidden_bit,nal_reference_bit(优先级),nal_unit_type(类型)。 脱壳操作:为了使NALU主体不包括起始码,在编码时每遇到两个字节(连续)的0,就插入一字节0x03,以和起始码相区别。解码时,则将相应的0x03删除掉。

H.264解码 NAL头信息的nal_referrence_idc(NRI)用于在重建过程中标记一个NAL单元的重要性,

  1. 值为0表示这个NAL单元没有用预测,因此可以被解码器抛弃而不会有错误扩散;
  2. 值高于0表示NAL单元要用于无漂移重构,且值越高,对此NAL单元丢失的影响越大。
  3. NAL头信息的隐藏比特位,在H.264编码器中默认为0,当网络识别到单元中存在比特错误时,可将其置为1。隐藏比特位主要用于适应不同种类的网络环境(比如有线无线相结合的环境)。

NAL单元解码的流程为:首先从NAL单元中提取出RBSP语法结构,然后按照如图4所示的流程处理RBSP语法结构。输入的是NAL单元,输出结果是经过解码的当前图像的样值点。 NAL单元中分别包含了序列参数集和图像参数集。图像参数集和序列参数集在其他NAL单元传输过程中作为参考使用,在这些数据NAL单元的片头中,通过语法元素pic_parameter_set_id设置它们所使用的图像参数集编号;而相应的每个图像参数集中,通过语法元素seq_paramter_set_id设置他们使用的序列参数集编号。

分类:
Android
分类:
Android