H264的两种封装
H.264 视频编码的封装方式主要分为 Annex B 和 AVCC(也称为 ISO Base Media File Format)两种,它们在结构、应用场景和解析方式上有显著差异。以下是详细说明:
一、Annex B 封装(基于起始码)
1. 核心特点
起始码分隔:每个 NALU(Network Abstraction Layer Unit)前添加固定的起始码作为分隔符,无显式长度字段。
3 字节起始码:0x000001(用于普通 NALU);
4 字节起始码:0x00000001(用于 SPS/PPS 或码流开头)。
自包含性:每个 NALU 可独立解析,无需依赖其他数据。
2. 结构示例
[0x00000001][SPS NALU][0x00000001][PPS NALU][0x00000001][IDR Slice NALU][0x000001][P Slice NALU]...
3. 关键参数位置
SPS/PPS:作为独立 NALU 存在于码流中,通常位于视频开头或关键帧前。
NALU 长度:通过扫描下一个起始码的位置间接确定。
4. 应用场景
实时流媒体:如 RTSP、RTP、TS 流(IPTV、直播);
文件格式:.264、.avi、.mkv 等容器格式;
硬件解码器:多数安防摄像头、机顶盒直接输出 Annex B 格式。
5. 优缺点
优点:
无需预先解析完整配置(如 SPS/PPS),可边接收边解码;
简单直观,便于流式解析。
缺点:
起始码占用额外空间(每个 NALU 至少 3 字节开销);
随机访问效率低(需扫描起始码定位特定 NALU)。
二、AVCC 封装(基于长度字段)
1. 核心特点
长度字段代替起始码:每个 NALU 前用 4 字节(大端序)表示其长度(不包含长度字段本身)。
extradata 头部:在码流开头或文件头部(如 MP4 的avcC box)存储 SPS/PPS 等配置信息,而非作为独立 NALU。
2. 结构示例
[extradata头部:包含SPS/PPS][NALU长度(4字节)][NALU数据][NALU长度(4字节)][NALU数据]...
3. extradata 格式(以 MP4 的avcC box 为例)
aligned(8) class AVCDecoderConfigurationRecord {unsigned int(8) configurationVersion = 1;unsigned int(8) AVCProfileIndication; // SPS中的profile_idcunsigned int(8) profile_compatibility; // SPS中的constraint_set[0-5]_flagsunsigned int(8) AVCLevelIndication; // SPS中的level_idcbit(6) reserved = '111111'b;unsigned int(2) lengthSizeMinusOne; // NALU长度字段的字节数减1(通常为3,表示4字节)bit(3) reserved = '111'b;unsigned int(5) numOfSequenceParameterSets; // SPS数量(通常为1)for (i=0; i< numOfSequenceParameterSets; i++) {unsigned int(16) sequenceParameterSetLength; // SPS长度bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit; // SPS内容}unsigned int(8) numOfPictureParameterSets; // PPS数量(通常为1)for (i=0; i< numOfPictureParameterSets; i++) {unsigned int(16) pictureParameterSetLength; // PPS长度bit(8*pictureParameterSetLength) pictureParameterSetNALUnit; // PPS内容}
}
4. 应用场景
文件存储:MP4、MOV、FLV 等容器格式;
API 接口:Android 的 MediaMuxer、iOS 的 AVAssetWriter;
点播系统:如 YouTube、Netflix 等视频平台。
5. 优缺点
优点:
节省空间(无起始码开销);
便于随机访问(通过长度字段直接定位 NALU);
配置信息集中存储,适合文件格式的元数据管理。
缺点:
需先解析 extradata 才能正确解码,不适用于无完整头部的实时流;
结构较复杂,解析成本高于 Annex B。
三、两种封装的转换
在实际应用中,两种封装常需相互转换:
Annex B → AVCC:
提取所有 SPS/PPS NALU,放入 extradata;
移除每个 NALU 前的起始码,添加 4 字节长度字段。
AVCC → Annex B:
从 extradata 提取 SPS/PPS,添加 4 字节起始码作为独立 NALU;
将每个 NALU 前的长度字段替换为 3 字节起始码。
例如,FFmpeg 中的h264_mp4toannexb滤镜可实现 AVCC 到 Annex B 的转换,常用于 RTSP 流传输前的预处理。
四、应用场景选择
实时流媒体(如直播、IP 摄像头):优先使用 Annex B,因其无需预先获取完整配置信息,可边接收边解码。
文件存储(如 MP4、点播视频):优先使用 AVCC,因其结构紧凑,便于文件索引和快速定位。
理解两种封装方式的差异,对 H.264 视频的解析、转码和播放至关重要。例如,在 WebRTC 通信中,视频数据通常以 Annex B 格式传输;而在浏览器播放 MP4 文件时,则需遵循 AVCC 格式。