音视频学习从零到整(1)
音视频学习从零到整(2)
音视频学习从零到整(3)
音视频学习从零到整(4)
音视频学习从零到整(5)
音视频学习从零到整(6)
音视频学习从零到整(7)
一.H264结构图
H264视频压缩后会成为一个序列帧.帧里包含图像,图像分为很多片.每个片可以分为宏块.每个宏块由许多子块组成.这就是H264结构图.非常的情绪简单.
H264结构中,一个视频图像编码后的数据叫做一帧,一帧由一个片(slice)或多个片组成,一个片由一个或多个宏块(MB)组成,一个宏块由16x16的yuv数据组成。宏块作为H264编码的基本单位。
场和帧:视频的一场或一帧可用来产生一个编码图像。在电视中,为减少大面积闪烁现象,把一帧分成两个隔行的场。
-
片:每个图象中,若干宏块被排列成片的形式。片分为I片、B片、P片和其他一些片。
I片只包含I宏块,P片可包含P和I宏块,而B片可包含B和I宏块。
I宏块利用从当前片中已解码的像素作为参考进行帧内预测。
P宏块利用前面已编码图象作为参考图象进行帧内预测。
B宏块则利用双向的参考图象(前一帧和后一帧)进行帧内预测。
片的目的是为了限制误码的扩散和传输,使编码片相互间是独立的。
某片的预测不能以其它片中的宏块为参考图像,
这样某一片中的预测误差才不会传播到其它片中去
宏块:一个编码图像通常划分成若干宏块组成,一个宏块由一个16×16亮度像素和附加的一个8×8 Cb和一个8×8 Cr彩色像素块组成。
二. H264编码分层
H264编码分层,分为了2层.
-
NAL层: (Network Abstraction Layer,视频数据网络抽象层)
- 它的作用是H264只要在网络上传输,在传输的过程每个包以太网是1500字节. 而H264的帧往往会大于1500字节的.所以就要进行拆包. 将一个帧拆成多个包进行传输.所有的拆包或者组包都是通过NAL层去处理的.
VCL层:(Video Coding Layer,视频数据编码层) 它的作用就是对视频原始数据进行压缩.
三.码流的基本概念
SODB:(String of Data Bits,原始数据比特流),长度不一定是8的倍数.它是由VCL层产生的.因为非8的倍数所以处理比较麻烦.
RBSP:(Raw Byte Sequence Payload,SODB+trailing bits).算法是在SODB最后一位补1.不按字节对齐补0. 如果补齐0,不知道在哪里结束.所以补1.如果不够8位则按位补0.
EBSP:(Encapsulate Byte Sequence Payload).就是生成压缩流之后,我们还要在每个帧之前加一个起始位.起始位一般是十六进制的0001.但是在整个编码后的数据里,可能会出来连续的2个0x00.那这样就与起始位产生了冲突.那怎么处理了? H264规范里说明如果处理2个连续的0x00,就额外增加一个0x03 .这样就能预防压缩后的数据与起始位产生冲突.
每个NAL前有一个起始码 0x00 00 01(或者0x00 00 00 01),解码器检测每个起始码,作为一个NAL的起始标识,当检测到下一个起始码时,当前NAL结束。
同时H.264规定,当检测到0x00 00 01时,也可以表征当前NAL的结束。那么NAL中数据出现0x000001或0x000000时怎么办?H.264引入了防止竞争机制,如果编码器检测到NAL数据存在0x000001或0x000000时,编码器会在最后个字节前插入一个新的字节0x03,这样:
解码器检测到0x000003时,把03抛弃,恢复原始数据(脱壳操作)。解码器在解码时,首先逐个字节读取NAL的数据,统计NAL的长度,然后再开始解码。
- NALU: NAL Header(1B)+EBSP.NALU就是在EBSP的基础上加1B的网络头.
四. 详解NAL Unit
NAL 单元是由一个NALU头部+一个切片.切片又可以细分成"切片头+切片数据".我们之间了解过一个H254的帧是由多个切片构成的.因为一帧数据一次有可能传不完.
切片与宏块的关系(Slice & MacroBlock)
每个切片都包括切片头+切片数据. 那每个切片数据包括了很多宏块.每个宏块包括了宏块的类型,宏块的预测,残差数据.
图解H264切片
在一副压缩的H264的帧里,可以包含多个切片.至少有一个切换.
H264码流分层结构图.
- A Annex格式数据,就是起始码+Nal Unit 数据
- NAL Unit: NALU 头+NALU数据
- NALU 主体,是由切片组成.切片包括切片头+切片数据
- Slice数据: 宏块组成
- PCM类: 宏块类型+pcm数据,或者宏块类型+宏块模式+残差数据
- Residual: 残差块.
这个图比较重要.大家可以多看看.