目录
三、网络抽象层(NAL,Network Abstraction Layer)
H.264 视频生产流程
工序 | 步骤 | 操作 | 详细说明 |
0 | 图像采集 | 图像采集 | 从摄像头或其他设备获取原始图像数据。 |
1 | 图像滤镜 | OSD、锐化、 合并、提色 | 对图像进行叠加文字(OSD)和锐化处理, 将处理后的图像数据合并并进行色彩提取。 |
2 | 编码 | H.264 编码 | 使用 H.264 编码器对图像数据进行压缩。 |
3 | 生产者消费者 | Ring Buffer | 使用环形缓冲区(Ring Buffer)存储编码数据,实现高效传输。 |
4 | 封装 | TS/MP4 | 将编码后的数据封装为 TS 或 MP4 格式。 |
5 | 传输 | TCP/UDP | 通过 TCP 或 UDP 协议传输封装后的数据。 |
一、概述
H.264(即MPEG-4 Part 10/AVC)是一种高效视频编码标准,广泛应用于视频存储、流媒体传输等领域。
1.1 编码本质
视频编码的核心目标是去除冗余信息。视频数据中通常包含大量冗余,主要体现在以下几个方面:
空间冗余:图像中相邻像素之间具有较强的相关性。
时间冗余:视频序列中相邻帧之间的内容往往高度相似。
视觉冗余:人眼对某些细节(如高频信息)不敏感。
视频编码的本质就是通过技术手段(如预测、变换、量化等)对这些冗余信息进行处理,从而减少数据量,实现高效压缩。
1.2 压缩原理
视频原始数据量极大,例如一帧1920x1080@YUV420的未压缩图像需3.1MB,1秒30帧视频需约89MB。编码的目标是通过压缩技术减少存储和传输负担。
H.264 采用了 16×16 的宏块(Macroblock) 作为基本处理单元,对视频帧图像进行相似性比较和压缩编码。
(图片来源于网络)
宏块的定义与作用
- 宏块大小:每个宏块包含至多 16×16 像素,涵盖亮度和色度信息(通常为 YUV 格式)。
- 功能:宏块是 H.264 编码的基本单位,用于帧内预测、帧间预测、运动估计和运动补偿等操作。
- 分割:16×16、16×8、8×16、8×8、8×4、4×8、4×4 等多种分割模式。
帧内压缩:空间冗余的去除
帧内预测:在帧内压缩中,H.264 利用宏块内像素的空间相关性进行预测。
- 亮度分量支持 16×16 和 4×4 两种预测模式:
- 16×16 模式:适用于平滑区域,提供 4 种预测方向(垂直、水平、DC、平面)。
- 4×4 模式:适用于细节丰富区域,提供 9 种预测方向。
- 色度分量采用 8×8 预测模式。
残差编码:通过预测值与实际值的差值(残差)进行编码,进一步减少数据量。
帧间压缩:时间冗余的去除
通过运动估计和补偿技术,利用相邻帧的相似性,生成P帧(参考前向帧)和B帧(双向参考)。
- 运动估计:在帧间压缩中,H.264 通过比较当前帧与参考帧的宏块,找到最佳匹配块,并计算运动矢量(Motion Vector)。
- 支持 1/4 像素精度 的运动估计,提高匹配精度。
- 运动补偿:利用运动矢量对参考帧的宏块进行位移补偿,生成预测帧。
- P 帧:参考前向帧进行预测。
- B 帧:参考前后双向帧进行预测,进一步压缩数据。
二、分层结构与语法元素
2.1 分层结构
H.264 分为 视频编码层(VCL,Video Coding Layer)和 网络抽象层(NAL,Network Abstraction Layer):
- VCL:负责核心编码流程,生成压缩后的语法元素(如宏块、片、帧等)。
- NAL:将VCL数据封装为 NALU(NAL Unit),适配不同传输场景,通过添加起始码 Start code(00 00 01或00 00 00 01)分隔单元,增强容错性。
2.2 语法元素
图像组(GOP,Group of Pictures)
- 定义:一组连续的帧,以 I 帧(关键帧) 起始,确保解码重新同步。
- 作用:
- 提供随机访问点,便于视频的快速定位和播放。
- 限制错误传播范围,避免因帧间依赖导致的长时间解码错误。
- 结构:典型的 GOP 结构为 I-B-B-P-B-B-P-...,其中 I 帧为起始帧,P 帧和 B 帧为后续帧。
帧(Frame)
帧是视频的基本单位,分为以下三种类型:
- I 帧(Intra-coded Frame)
- 特点:
- 独立编码,不依赖其他帧。
- 采用帧内压缩技术,去除空间冗余。
- 分类:
- 普通 I 帧:独立解码,但不强制清空参考帧队列。
- IDR 帧(Instantaneous Decoding Refresh Frame):特殊 I 帧,强制清空参考帧队列,确保后续帧不会参考 IDR 帧之前的帧。
- 特点:
- P 帧(Predictive-coded Frame)
片(Slice)
- 定义:将一帧图像划分为若干独立编码的片(如 I 片、P 片、B 片),每片包含整数个宏块。
- 作用:
- 防止误码扩散,增强容错性。
- 支持并行编码和解码,提高处理效率。
- 类型:
- I 片:仅包含帧内预测的宏块。
- P 片:包含帧内预测和帧间预测(前向参考)的宏块。
- B 片:包含帧内预测和帧间预测(双向参考)的宏块。
宏块(Macroblock)
- 定义:16×16 像素块,是 H.264 编码的基本单元。
- 组成:
- 亮度分量(Y):16×16 像素。
- 色度分量(U、V):8×8 像素(YUV 4:2:0 格式)。
- 功能:
- 支持帧内预测和帧间预测。
- 支持多种分割模式(如 16×16、16×8、8×16、8×8 等),适应不同图像内容。
子块(Subblock)
- 定义:宏块的进一步分割,用于提升运动补偿精度。
- 常见分割模式:
- 8×8、8×4、4×8、4×4 等。
- 作用:
- 提高运动估计的精度,适应复杂运动场景。
- 增强压缩效率,减少残差数据量。
三、网络抽象层(NAL,Network Abstraction Layer)
NALU 是 H.264 码流的基本单元,结构为:[Start Code] [NALU Header] [NALU Payload]。
3.1 NALU 结构
Start Code(起始码,Annex B 模式)
- 作用:标识一个 NALU 的开始。
- 格式:
- 00 00 00 01(4 字节起始码)
- 00 00 01(3 字节起始码)
- 使用场景:
- 4 字节起始码:通常用于标识流中的关键点,如 SPS、PPS、AUD(Access Unit Delimiter)和 IDR 帧。
- 3 字节起始码:用于普通 NALU,以减少数据量。
- 防止竞争机制:为了避免 NALU 内部出现与起始码相同的字节序列(如 00 00 01),H.264 引入了防止竞争机制(如插入 0x03 字节)。
NALU Header
1字节,包含以下字段:
- F(Forbidden Bit):通常为0,表示无错误。
- NRI(重要性指示):2位,值越大表示数据越关键(如SPS/PPS需高优先级传输)。
- Type(类型):5位,定义负载数据类型,如:
- 7: SPS(序列参数集,包含分辨率、帧率等全局信息)
- 8: PPS(图像参数集,编码模式参数)
- 5: IDR帧
- 1: 非IDR的I帧或P/B帧的Slice。
NALU Type value | 描述 |
0 | 未指定 |
1 | 非IDR图像的编码片 |
2 | 编码片数据分区 A |
3 | 编码片数据分区 B |
4 | 编码片数据分区 C |
5 | IDR图像的编码片 |
6 | 补充增强信息 (SEI) |
7 | 序列参数集 (SPS) |
8 | 图像参数集 (PPS) |
9 | 访问单元分隔符 |
10 | 序列结束 |
11 | 流结束 |
12 | 填充数据 |
13-23 | 保留 |
24-31 | 未指定 |
NALU Payload
- 内容:承载 VCL 编码数据(如 Slice)或参数集(SPS/PPS)。
- RBSP(Raw Byte Sequence Payload):NALU Payload 的实际数据部分,经过防止竞争机制处理。
3.2 NALU 的类型与作用
-
SPS(Sequence Parameter Set)
- 包含视频序列的全局参数,如分辨率、帧率、编码档次等。
- 解码器初始化时必须读取 SPS。
-
PPS(Picture Parameter Set)
- 包含单帧图像的局部解码参数,如熵编码类型、分片模式等。
- 解码每帧时依赖 PPS。
-
IDR 帧
- 特殊 I 帧,强制清空参考帧队列,确保后续帧不会参考 IDR 帧之前的帧。
-
Slice
- 包含帧内或帧间编码的宏块数据,分为 I 片、P 片、B 片。
四、封装模式
4.1 Annex B 模式
-
起始码(Start Code)
00 00 01(3 字节)或 00 00 00 01(4 字节)。
-
SPS 和 PPS
SPS(序列参数集)和 PPS(图像参数集)直接嵌入在码流中,通常位于 IDR 帧之前。
-
应用场景
常用于实时流媒体传输(如 RTSP、RTP)和裸流存储(如 .h264 文件)。
-
兼容性
大多数解码器(尤其是硬件解码器)原生支持 Annex B 模式。
4.2 AVCC 模式
-
无起始码:
NALU 之间没有起始码,而是通过长度字段分隔。
每个 NALU 前面有一个 4 字节的长度字段,表示当前 NALU 的大小,常见于MP4/MKV文件。
-
SPS 和 PPS
SPS 和 PPS 不直接嵌入在码流中,而是存储在容器的元数据部分(如 MP4 的 AVCC 盒子)。
-
应用场景
常用于文件存储格式(如 MP4、MKV)。
-
兼容性
需要容器格式(如 MP4)的支持,解码器需从容器中提取 SPS 和 PPS。
4.3 模式区别
特性 | Annex B 模式 | AVCC 模式 |
起始码 | 00 00 01 或 00 00 00 01 | 无起始码,使用 4 字节长度字段 |
SPS/PPS 存储 | 嵌入在码流中,位于 IDR 帧之前 | 存储在容器元数据中 (如 MP4 的 AVCC) |
应用场景 | 实时流媒体传输、裸流存储(如 .h264 文件) | 文件存储格式(如 MP4、MKV) |
兼容性 | 大多数解码器原生支持 | 需要容器格式支持 |
4.4 模式选择建议
- 实时流媒体:优先使用 Annex B 模式,因其兼容性更好,适合低延迟传输。
- 文件存储:优先使用 AVCC 模式,因其结构更紧凑,适合本地存储和播放。