🍉 加载中...


音视频基础知识小记 - 视频篇

11 minute read

前言

H.264对于计算机来说,本质上其实就是一连串随着时间推移的比特流,至于这些比特流分别代表什么意义,制定H.264标准的那帮家伙给定义好了,大家只要都遵守这个标准就可以了。

本文主要记述 H.264 相关内容。

基础知识

NALU 结构

NAL Unit

  • 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 帧组都是描述的一个图像目标的细微差别。其中帧与帧之间的差距很小,只会存储其中的差值。

其内部结构如下图所述:

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 内部结构,见以下图示:

Slice 与 MacroBlock

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中一个非常重要的概念。

Demo

Profile

Profile 用于确定视频编码过程中帧间压缩使用的算法(例如是否包含B帧、CABAC支持、颜色空间支持等),Profile越高,就说明采用了越高级的压缩特性,对应的对编解码硬件的要求也越高。

支持的选项及其支持的能力与特新:

H.264 Profile

各选项之间的关系:

H.264 Profile

H.264 Profile

Level

Level 是对视频本身特性的一些描述(码率,分辨率,fps等),Level越高,视频的码率、分辨率、fps越高。

支持的选项及其支持的能力与特新:

H.264 Level

分辨率相关参数

分辨率相关参数

场是隔行扫描,会产生两张图。

帧相关参数

- 帧数(GOP 中的最大帧数):log2_max_frame_num_minus4
- 参考帧数:max_num_ref_frames
- 显示帧序号:pic_order_cnt_type

PPS

PPS 参数

VCL 结构关系

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

参考资料