H264编码原理
H264压缩比
相较于YUV格式大约 1/100
GOP
全称 group of pictures,指两个I帧之间的间隔
花屏的原因
若GOP分组中有帧丢失,会造成解码端的图像发生错误,这会出现马赛克(花屏)
卡顿的原因
为了避免花屏问题的发生,当发现有帧丢失时,就丢弃GOP内的所有帧,直到下一个IDR帧重新刷新图像
I帧是按照帧周期来的,需要一个比较长的时间周期,如果在下一个I帧之前不显示后来的图像,那么视频就静止不动了,这就是出现了所谓的卡顿现象
编码帧
I帧
全称 intraframe frame,关键帧,采用帧内压缩技术。IDR帧属于I帧
P帧
全称 forward predicated frame,向前参考帧。压缩时,只参考前面已经处理的帧,采用帧间压缩技术。它占I帧一半的大小
B帧
全称 bidirectionally predicated frame,双向参考帧。压缩时,即参考前面已经处理的帧,也参考后面的帧,帧间压缩技术。它占I帧1/4的大小
IDR帧
全称 Instantaneous Decoding Refresh,即时解码刷新,第一个I帧即为IDR帧,作用是立即刷新,使DPB(DecodedPictureBuffer 参考帧列表)清空,它是为了控制编解码的流程
H264压缩技术
有损压缩
- 帧内压缩:解决空域数据冗余问题
- 帧间压缩:解决时域数据冗余问题
无损压缩
- 整数离散余弦变换(DCT):将空间上的相关性变为频域上无关的数据然后进行量化,以方便接下来的无损压缩
- CABAC压缩:基于哈夫曼编码的一种压缩方式,同时还会根据上下文对数据进行压缩
宏块
视频压缩操作的基本单元
帧内压缩原理
- 相邻像素差别不大,可以进行宏块预测
- 人对亮度的敏感度超过色度
- YUV很容易将亮度与色度分开
9种帧内预测模式
前3种模式的预测结果
帧间压缩原理
- 在同一个GOP内
- 要有参考帧
- 运动估计(宏块匹配+运动矢量)
- 运动补偿(解码)
宏块匹配(查找)算法
- 三步搜索
- 二维对数搜索
- 四步搜索
- 钻石搜索
无损压缩步骤
- DCT变换:经过有损压缩后,二维数据是分散在各个点上的,处理分散的数据是很麻烦的,使用DCT处理数据会生成滤波,这种滤波能够使分散的数据集中在一起。这时再处理数据就很方便
- VLC压缩:基于哈夫曼编码的压缩方式,高频数据用短码表示,低频数据用长码表示
- CABAC压缩:基于哈夫曼编码的压缩方式,同时还会根据上下文对数据进行压缩
H264编解码流程示意图
码流分层
NAL层
全称 network abstraction layer,视频数据网络抽象层。主要用于数据传输,解决传输二进制数据时发生的乱序、重传、丢包
VCL层
全称 video coding layer,视频数据编码层。
码流
SODB
全称 String of data bits,原始数据比特流,由于它的长度不一定是8的倍数,故需要补齐。它是由VCL层产生
RBSP
全称 Raw byte sequence payload,实质是SODB + trailing bits,如果SODB最后一个字节不对齐,则补1和多个0
NALU
NAL Header(1B)+ RBSP
NAL层与VCL层示意图
Slice与MacroBlock分层示意图
Annexb格式或RTP格式整体分层示意图
如何判断当前帧为I帧、P帧、B帧?
在帧数据中,每一帧的开头都是固定的。而在实际的H264数据帧中,往往帧数据前面有00 00 00 01或00 00 01等固定的分隔符,一般来说编码器编出的首帧数据为PPS和SPS,接着为I帧。然后利用NALU类型作为参考便容易判断,官方参考示意图如下
- 第1位禁止位,值为1表示语法出错
- 第2~3位为参考级别
- 第4~8为是nal单元类型
但通过NALU是判断不了B帧和P帧的区别,需要在Slice层判断熵编码