文章目录
- 一、核心名词区分
- 1. NALU(Network Abstraction Layer Unit,网络抽象层单元)
- 2. AnnexB 格式(带起始码的裸流,你平时文件/摄像头输出的标准裸流)
- 定义:NALU 前面拼接 **起始码前缀**
- 3. AVCC / AVCC Annex(不带起始码,长度前缀封装)
- 二、一句话总结对应关系
- 三、结合你之前FFmpeg推流场景重点
- 四、示例对比
- AnnexB(标准264裸流,带起始码)
- 纯NALU(剥离起始码)
- AVCC(RTMP/MP4内部,长度头代替起始码)
从这讲开始,我们进入了编码的深水区,这些内容的概念一定要头脑清楚,否则后面开发容易混淆。
一、核心名词区分
1. NALU(Network Abstraction Layer Unit,网络抽象层单元)
NALU = 去掉起始码后的一段纯载荷二进制
- 内部结构:1字节NALU头 + 视频数据(SPS/PPS/I/P帧等)
- 特征:不带
00 00 01/00 00 00 01起始码 - 所有H264最小数据单元都叫NALU:
NALU Type=7 → SPS;Type=8 → PPS;Type=5 → I帧;Type=1 → P帧
2. AnnexB 格式(带起始码的裸流,你平时文件/摄像头输出的标准裸流)
定义:NALU 前面拼接起始码前缀
起始码两种:
- 3字节:
0x00 00 01(普通NALU前缀) - 4字节:
0x00 00 00 01(码流第一个NALU、分片开头常用)
结构:[起始码] + NALU
- 后缀文件:
.h264/.264 - 场景:海康/大华RTSP输出裸流、本地保存的裸流文件、FFmpeg
-f h264识别的流 - 关键词:AnnexB裸流、AnnexB格式H264、带起始码裸流
3. AVCC / AVCC Annex(不带起始码,长度前缀封装)
没有0001起始码,取而代之用4字节大端长度描述NALU长度
结构:[4字节NALU长度] + NALU
- 场景:MP4容器、FLV/RTMP内部封装、MP4文件内部存储H264
- RTMP协议内部传输H264时,内部是AVCC格式,不带起始码
二、一句话总结对应关系
- 不带任何起始码,纯载荷→ NALU
- NALU + 0001/000001起始码→ AnnexB H264裸流(标准.264文件)
- NALU + 4字节长度头,无起始码→ AVCC格式(MP4/RTMP内部)
三、结合你之前FFmpeg推流场景重点
- 本地
.h264文件、摄像头RTSP原始码流 =AnnexB(带起始码NALU)
FFmpeg 参数-f h264专门识别这种格式; - 推RTMP到SRS时:
FFmpeg内部会自动把AnnexB → 转成AVCC封装进FLV Tag,自动去掉起始码,替换成长度头,你不用手动处理。
四、示例对比
AnnexB(标准264裸流,带起始码)
00 00 01 67 xx xx ...00 00 01 68 xx xx ...00 00 01 65 xx xx ...
纯NALU(剥离起始码)
67 xx xx ...(SPS NALU)68 xx xx ...(PPS NALU)65 xx xx ...(I帧 NALU)
AVCC(RTMP/MP4内部,长度头代替起始码)
00 00 00 12 67 xx xx ...
前4字节00 00 00 12= 后面NALU字节长度。根据大端规则,表示后面18个字节。
补充规则(AVCC/FLV/RTMP 统一)
- 长度字段固定 4 字节、大端存储;
长度只包含 NALU 本体,不包含这 4 字节长度头自己; - 和 AnnexB 区别:
AnnexB:00 00 01 起始码分割 NALU
AVCC:4 字节长度头声明 NALU 长度,无起始码