H.264编解码(NAL)
在我们的日常生活中,比如有缓存电影或者是发送视频的需求。如果没有视频压缩,一部手机只能存几分钟视频,1TB 硬盘也装不下几部电影,用 4G 网络发一段 1 分钟视频,可能需要几十分钟(甚至传不完),在线看视频更是完全不可能。所以就引入了H264这样的压缩技术。这边文章更注重如何传输(NAL)。
如何进行压缩
空间冗余:一帧图像中可能会有一片像素是相似的,就可以进行压缩
时间冗余:几帧图像之间会有一些像素部分变化较小,可以进行压缩
视频编码关键点
压缩比:压缩比越高,视频文件越小。
算法复杂度:复杂度越高,对设备性能要求越高,但可能带来更高的压缩效率或画质。
还原度:指编码后的视频与原始视频的画质接近程度。
压缩比、算法复杂度、还原度并非孤立存在,而是形成 “不可能三角”,三者相互制约
H.264的2大组成部分(NAL VCL)
VCL:负责 “压缩视频内容”,通过帧内 / 帧间预测、变换量化等技术,去除视频中的冗余信息,生成高效压缩的核心视频数据。
NAL:负责 “适配网络传输”,将 VCL 生成的压缩数据打包成符合网络传输规则的单元(加起始码、头部信息等),确保数据能在网络中稳定传输和解码。
H.264编码相关的一些概念
宏块(macroblock):宏块内的像素相似度比较高,前面讲到的空间冗余就和这个有关
片(slice):片比宏块大是组成帧的一部分
帧(frame):一幅图像
I帧:只进行帧内压缩,图像较为完整
B帧:参考前后帧得出当前帧
P帧:只参考前一帧得出当前帧
帧率(fps):单位时间内视频显示的画面帧数
以下是一段H.264的文件进行解析,此处要用到工具winhex和SpecialVH264.exe
由实验结果可知海思平台编码出来的H.264码流都是一个序列包含:1sps+1pps+1sei+1I帧+若干p帧
对应以上两个实验结果继续详细的介绍H.264的NAL部分:
序列(sequence):给视频分段,一个序列就是一个视频段(每个段都参考一个I帧减小误差)
分隔符:可以看到转二进制之后都会用一个00 00 00 01进行分割,在数据段部分有两个00就会用一个03进行分割,以免数据段和分隔符出现重复
nal_ref_idc:表示该帧数据的重要性,因为网络传输难以避免会出现丢包的情况,定义标志位防止重要的包被丢弃
NALU:分隔符后一位就是NALU,用于标识该帧的类型和其重要性,具体可以参考H264(NAL简介与I帧判断)
SPS:规定整个视频的基础属性(比如多大尺寸、每秒多少帧),解码器先看它才知道怎么 “看懂” 整个视频。
PPS:针对每帧画面的编码方式做具体说明(比如怎么压缩、怎么去噪),指导解码器处理单帧数据。
SEI:不是必要的,不直接影响画面内容,但提供与视频相关的 “额外信息”(如时间戳、版权声明、画质增强提示等),辅助解码器更好地处理或显示视频
如何通过SPS和PPS看到详细的属性呢
上面是通过SpecialVH264.exe这个工具查看到的,关于每一项的具体意思可以参考H264码流中SPS PPS详解这一篇文章
其中有几个比较重要的属性
profile:可以理解为定义了编码工具的集合,不同的profile,包含了不同的编码技术
level:主要是对码流的关键参数的取值范围作了限定,与解码器的处理能力和存储能力相关联
对于profile和level可以看h264中profile和level的含义
pic_width_in_mbs_minus1:用于计算图像的宽度 frame_width = 16 × (pic_width_in_mbs_minus1 + 1);
pic_height_in_map_units_minus1:用来度量视频中一帧图像的高度计算公式和宽度一样
关于海思平台H.264的一些知识
p帧的个数等于fps-1;
I帧越大则P帧可以越小,反之I帧越小则P帧会越大,可以理解为参考的越少,自己要做的更多;
I帧的大小取决于图像本身内容,和压缩算法的空间压缩部分;
P帧的大小取决于图像变化的剧烈程度;
CBR和VBR下P帧的大小策略会不同,CBR时P帧大小基本恒定,VBR时变化会比较剧烈;