上传h264笔记

master
dezhihuang 2017-11-12 14:40:05 +08:00
parent 592f2a8bb1
commit f113a1f20d
10 changed files with 122 additions and 0 deletions

122
h264/h264.md Normal file
View File

@ -0,0 +1,122 @@
# NAL简介
> NAL全称Network Abstract Layer, 即网络抽象层。
在H.264/AVC视频编码标准中整个系统框架被分为了两个层面**视频编码层面VCL, Video Coding Layer和网络抽象层面NAL, Network Abstraction Layer。**其中,前者负责有效表示视频数据的内容,即编码处理的输出,它表示被压缩编码后的视频数据 序列。而后者则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输,即在 VCL 数据传输或存储之前,这些编码的 VCL 数据,先被映射或封装进 NAL 单元(以下简称 NALUNal Unit) 中。
因此我们平时的每帧数据就是一个NAL单元SPS与PPS除外。在实际的H264数据帧中往往帧前面带有00 00 00 01 或 00 00 01分隔符一般来说编码器编出的首帧数据为PPS与SPS接着为I帧……
# H.264码流组成
H.264 原始码流(又称为裸流)是由一个接一个的NAL单元组成每个NAL单元包括一组对应于视频编码数据的 NAL 头信息和一个原始字节序列负荷RBSP, Raw Byte Sequence Payload。而RBSP可能是SPSPPSIDR、Slice或SEI
![](./images/nalu.png)
上图中的 NALU头 + RBSP 就相当与一个 NALU (Nal Unit), 每个单元都按独立的 NALU 传送。 其实说白了H.264 中的结构全部都是以 NALU 为主的,理解了 NALU就理解 H.264 的结构了。
# NAL头部信息
> 起始码00 00 00 01(或00 00 01)的下一个字节就是NAL头部
7 | 6 5 | 4 3 2 1 0
--------------------|-------------|---------------
forbidden_zero_bit | nal_ref_idc | nal_unit_type
forbidden_zero_bit(1 bit)禁止位值为1表示语法出错。在H.264规范中规定了这一位必须为0。
nal_ref_idc(2 bit)参考级别。取0~3,似乎指示这个NALU的重要性,如00的NALU解码器可以丢弃它而不影响图像的回放,03取值越大表示当前NAL越重要需要优先受到保护。如果当前NAL是属于参考帧的片或是序列参数集或是图像参数集这些重要的单位时本句法元素必需大于0。
nal_unit_type(5 bit)NAL单元类型。这个NALU单元的类型,112由H.264使用2431由H.264以外的应用使用。
# NAL单元类型
NAL Type | Description | VCL
---------|-----------------------------------------------------|-----
0 | 未规定 | N/A
1 | 非DIR图像中不采用数据划分的Slice。不分区、非IDR图像的片 | Yes
2 | 非DIR图像中A类数据划分Slice。片分区A | Yes
3 | 非DIR图像中B类数据划分Slice。片分区B | Yes
4 | 非DIR图像中C类数据划分Slice。片分区C | Yes
5 | DIR图像的SliceCoded Video Sequence 的 Access Unit | Yes
6 | 补充增强信息SEI | No
7 | 序列参数集SPS | No
8 | 图像参数集PPS | No
9 | 分隔符Access Unit Delimiter | No
10 | 序列结束符End of Sequence | No
11 | 流结束符End of Stream | No
12 | 填充数据Filler | No
13-23 | 保留 | N/A
24-31 | 未规定 | N/A
# NALU起始码
如果 NALU 对应的 Slice 为一帧的开始,则用 4 字节表示,即 0x00000001否则用 3 字节表示,0x000001。
# H264码流分层结构
![](./images/h264bitstream.png)
编码后视频的每一组图像GOP图像组都给予了传输中的序列PPS和本身这个帧的图像参数SPS所以我们的整体结构应该如此
![](./images/h264encode.png)
GOP (图像组)主要用作形容一个 i 帧 到下一个 i 帧之间的间隔了多少个帧,增大图片组能有效的减少编码后的视频体积,但是也会降低视频质量,至于怎么取舍,得看需求了。
# SPS、PPS
用 NALU 作载体的还有 SEI、SPS、PPS 等等。
NAL_SPS = 7, // 序列参数集 (包括一个图像序列的所有信息,即两个 IDR 图像间的所有图像信息,如图像尺寸、视频格式等)。
NAL_PPS = 8, // 图像参数集 (包括一个图像的所有分片的所有相关信息, 包括图像类型、序列号等,解码时某些序列号的丢失可用来检验信息包的丢失与否)。
![](./images/spspps.png)
![](./images/h264dataunit.png)
H.264 中,句法元素共被组织成 序列、图像、片、宏块、子宏块五个层次。
# 什么是宏块
> 宏块是视频信息的主要承载者,因为它包含着每一个像素的亮度和色度信息。视频解码最主要的工作则是提供高效的方式从码流中获得宏块中的像素阵列。
>
组成部分一个宏块由一个16×16亮度像素和附加的一个8×8 Cb和一个 8×8 Cr 彩色像素块组成。每个图象中,若干宏块被排列成片的形式。
宏块的结构图:
![](./images/macroblock.png)
从上图中可以看到宏块中包含了宏块类型、预测类型、Coded Block Pattern、Quantization Parameter、像素的亮度和色度数据集等等信息。
# 什么是切片slice
> 片的主要作用是用作宏块Macroblock的载体。片之所以被创造出来主要目的是为限制误码的扩散和传输。
> 如何限制误码的扩散和传输每个片slice都应该是互相独立被传输的某片的预测slice内预测和片slice间预测不能以其它片中的宏块Macroblock为参考图像。
slice的具体结构
![](./images/slice.png)
我们可以理解为一 张/帧图片可以包含一个或多个分片(Slice),而每一个分片(Slice)包含整数个宏块(Macroblock)即每片slice至少一个 宏块(Macroblock),最多时每片包含整个图像的宏块。
上图结构中,我们不难看出,每个分片也包含着头和数据两部分:
1、分片头中包含着分片类型、分片中的宏块类型、分片帧的数量、分片属于那个图像以及对应的帧的设置和参数等信息。
2、分片数据中则是宏块这里就是我们要找的存储像素数据的地方。
# 一帧图片跟 NALU 的关联
一帧图片经过 H.264 编码器之后就被编码为一个或多个片slice而装载着这些片slice的载体就是 NALU 了,我们可以来看看 NALU 跟片的关系slice
![](./images/frame_slice.png) ![](./images/nalu_slice.png)
slice的概念不同与帧frameframe是用作描述一张图片的一帧frame对应一张图片而片slice是 H.264 中提出的新概念是通过编码图片后切分通过高效的方式整合出来的概念一张图片至少有一个或多个片slice
上图中可以看出slice都是又 NALU 装载并进行网络传输的,但是这并不代表 NALU 内就一定是切片,这是充分不必要条件,因为 NALU 还有可能装载着其他用作描述视频的信息。
<br >
<br >

BIN
h264/images/frame_slice.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
h264/images/h264encode.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
h264/images/macroblock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

BIN
h264/images/nalu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
h264/images/nalu_slice.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

BIN
h264/images/slice.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

BIN
h264/images/spspps.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB