H264结构详解
frame
视频的一张图片就叫一帧,H264分为I帧,P帧,B帧。
slice
一个frame可以切成多个slice,slice之间在解码过程中是相对独立的,能够限制产生花屏时的影响范围
NALU
NALU = NAL HEADER + NAL Payload(slice data);
NAL HEADER
NAL HEADER = Forbidden_zero_bit(1bit)必须为0 + nal_ref_idc(2bit)重要程度,越大越重要 + nal_unit_type(5bit)NALU类型[0,31];
nal_unit_type = {6(SEI), 7(SPS), 8(PPS), 5(IDR帧), 1(非IDR帧), 28(FU-A分片)}
NAL Payload
SODB
编码器原始输出的比特流(非字节对齐)
RBSP
SODB + 补齐字节,凑齐到8bit整数倍(停止位1 + n个0)
EBSP
RBSP中的 0x00 00 XX (XX = {00, 01, 02, 03}), 替换为 0x00 00 03 XX
NALU交界
NALU之间的边界标识方式有两种
- Annex B : 用起始码
0x00 00 01或0x00 00 00 01标识一个新的NALU的开始 - AVCC : 在 NALU 之前添加4字节表示该NALU的实际长度
Annex B适合网络传输,AVCC适合本地存储
FU-A分包
如果一个NALU长度超过了MTU,此时就需要FU-A分包
1 | struct NAUL_HEADER { |
假设原始IDR帧 NAUL_HEADER idr_header = {0, 11, 00101} = 0x65;
FU-A分包会构造两个结构,FU identifier 和 FU Header
1 | struct FU_identifier { |
则有第1片
1 | FU_identifier fi1; |
中间n片 Start_bit = 0, End_bit = 0;
最后1片 Start_bit = 0, End_bit = 1;
还原时即将收到的第一个分片的2byte还原为1byte NAUL_HEADER,后面的分片前2byte直接丢弃
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 ciiki的博客!
评论




