音视频基础知识小记 - 视频篇
前言
H.264对于计算机来说,本质上其实就是一连串随着时间推移的比特流,至于这些比特流分别代表什么意义,制定H.264标准的那帮家伙给定义好了,大家只要都遵守这个标准就可以了。
本文主要记述 H.264 相关内容。
基础知识
NALU 结构
- SODB(String of data bits)
由 VCL 层产生的原始数据比特流,长度不一定是8的倍数,故需要补齐。
- RBSP(Raw Byte Sequence payload)
SODB + trailing bits,算法是如果 SODB 最后一个字节不对齐,则进行补位(补 0 或 1)。
- NALU(NAL Unit)
NAL Header(1B) + RBSP。
GOP 帧组
GOP 按相关性(相似性)将帧分为若干组,每个 GOP 帧组都是描述的一个图像目标的细微差别。其中帧与帧之间的差距很小,只会存储其中的差值。
其内部结构如下图所述:
I/P/B 帧
-
I 帧(Intraframe Frame):关键帧
- GOP 组中的第一帧。
- 采用帧内压缩技术,解码时不需要依赖其他帧。
- 如果一组帧的大小超过一定范围,H.264 编码中会强制插入一些 I 帧。
- IDR 帧也属于 I 帧。
-
P 帧(Forward Predicted Frame):向前参考帧
- 采用帧间压缩技术,依赖前一帧(即前一帧解码成功后才能解码 P 帧)。
- 大小约为 I 帧的 1/2。
-
B 帧(Bidirectionally Predicted Frame):双向参考帧
- 采用帧间压缩技术,同时依赖前一帧和后一帧。
- 优先解码 B 帧后一帧(P 帧),即在一个 GOP 组中,B 帧是最后进行解码的。
- 大小约为 I 帧的 1/4。
-
IDR 帧(Instanstaneous Decoder Refresh):解码器立即刷新帧
- IDR 帧是一种特殊的 I 帧。
- 采用帧内压缩技术,解码时不需要依赖其他帧。
- 每个 GOP 组中的第一帧就是 IDR 帧。
- 遇到 IDR 帧时,解码器会清空内部参考缓存(Buffer)中的内容。
IDR 帧目的之一是减小出现错误时造成的影响,即起到防止错误传播的作用。
在对延时较为敏感的实时视频会议应用场景中,通常只使用 I 帧和 P 帧。在需要进行大量的转码或存储时,则会大量的使用 B 帧。
Macro Block
用于对数据处理区块进行划分。
关于宏块的尺寸,如下图所示:
H.264 中每个宏块即其子块的尺寸(划分颗粒度)都可以单独控制,相较 MPEG 要更加强大灵活。
进行编解码时,都是以宏块为单位进行。
Slice
H.264 官方标准允许一个图像(一帧)产生多个 Slice(片),实际使用中通常一个图片只有产生一个 Slice。
Slice Header
- 帧类型
- GOP 中解码帧序号
- 预测权重(可选)
- 滤波(可选)
Slice Data
一个完整的 Slice 由 Header 和 Data 组成,其中 Data 由众多 Macro Block 组成。
Data 内部结构,见以下图示:
Data 内部的 Macro Block 中,各字段的描述如下:
- mb_type: 宏块类型
- mb_pred: 宏块预测值
- coded residual: 残差值
帧内压缩
属于有损压缩。
理论
- 相邻宏块差异较小,所以可以进行宏块预测。
- 人类对亮度的敏感度超过色度。
- YUV 很容易将亮度和色度分开。
帧内预测
预测模式
预测图像与实际图像
预测模式与残差值压缩
帧间压缩
- GOP
- 参考帧
- 运动估计(宏块匹配 + 运动矢量)
- 通过宏块匹配找到运动矢量。
- 运动矢量指从一个坐标到另一个坐标的方向。
- 运动补偿(解码)
- 找到残差值,在解码时进行补偿。
属于有损压缩。
相对帧内压缩,帧间压缩拥有更高的压缩比。
宏块查找
查找并记录黄色球球所在宏块移动的距离及方向。
宏块查找算法
- 三步搜索
- 二维对数搜索
- 四步搜索
- 钻石搜索
运动估计
估算运动矢量。
运动矢量与补偿压缩
无损压缩
DCT 变换
进行滤波处理,将分散的数据集中到一起(左上角或右下角)。
变换前:
变换后:
VLC 压缩
根据使用频率赋予长码或短码。
CABAC
TODO…
SPS 与 PPS
SPS(Sequence parameter set)
与 PPS
通常是同时出现的,不会单独出现。SPS 和 PPS 同属于 IDR 帧的一部分,每个 IDR 帧前面都会有一个 SPS 跟 PPS。
- SPS:序列参数集
- 作用于一串连续的视频图像(即对 GOP 帧组的参数设置)。
- 内含 seq_parameter_set_id、帧数、POC(picture order count)约束、参考帧数量、解码图像尺寸、帧场编码模式选择标识等数据。
- PPS(Picture parameter set):图像参数集
- 作用于视频序列中的图像(即对 GOP 帧组中的每一幅图像的约束)。
- 内含 pic_parameter_set_id、熵编码模式选择标识、片组数量、初始量化参数、去方块滤波系数调整标识等数据。
H.264 标准中,Profile 和 Level 信息是定义在 SPS NALU 中的,SPS 又是 H.264 的第一个 NALU,所以知道了 SPS 这个 NALU 中每一个字节的意义就可以很快地从中分辨出 Profile 和 Level。
SPS
Profile和Level是H.264中一个非常重要的概念。
Profile
Profile 用于确定视频编码过程中帧间压缩使用的算法(例如是否包含B帧、CABAC支持、颜色空间支持等),Profile越高,就说明采用了越高级的压缩特性,对应的对编解码硬件的要求也越高。
支持的选项及其支持的能力与特新:
各选项之间的关系:
Level
Level 是对视频本身特性的一些描述(码率,分辨率,fps等),Level越高,视频的码率、分辨率、fps越高。
支持的选项及其支持的能力与特新:
分辨率相关参数
场是隔行扫描,会产生两张图。
帧相关参数
- 帧数(GOP 中的最大帧数):log2_max_frame_num_minus4
- 参考帧数:max_num_ref_frames
- 显示帧序号:pic_order_cnt_type
PPS
VCL 结构关系
码流分层
- NAL 层
Network Abstraction Layer,视频数据网络抽象层。
- VCL 层
Video Coding Layer,视频数据编码层。
Annexb 格式用于在文件中保存,每个 NALU 单元起始位置都包含一个 StartCode(NALU 单元分隔符)。RTP 格式用于网络传输,直接传输 NALU 单元。
即 NALU 单元既可直接保存成文件,也可直接在网络上进行传输。
压缩技术分类
-
有损压缩
- 帧内压缩:解决空域数据沉余问题
- 帧间压缩:解决时域数据沉余问题
-
无损压缩
- 整数离散余玄变化(DCT):将空间上的相关性变为蘋域上无关的数据然后进行量化。
- CABAC 压缩。
常见问题
视频画屏原因
如果 GOP 帧组中有帧丢失,意味这该帧相关的运动矢量和残差值都已丢失,会造成解码端的图像发生错误(画屏)。
视频卡顿原因
为避免画屏问题,当发现有帧丢失时,直接丢弃掉该 GOP 帧组内余下所以帧,直到下一个 IDR 帧。
IDR 帧需要一个相对较长的时间周期,在下一个 IDR 帧到来之前视频将保持静止,也就出现了所谓的卡顿。
帧率计算
framerate = (float)(sps->vui.vui_time_scale) / (float)(sps->vui.vui_num_units_in_tick) / 2;
压缩比
条件: 1. YUV 420 2. 分辨率 640x480 3. 帧率 15
建议码流 640 * 480 * 1.5 * 15 * 8 = 500kbps(未压缩码流)
压缩比: 1/100