H264---封装格式:字节流格式(AnnexB)、AVCC 、RTP打包格式
H.264的两种打包/封装方法:字节流AnnexB格式 AVCC格式
放用于网络发送时,要封装成RTP格式
slice(即单帧多个NALU)之间间隔
②4字节0x00000001 帧之间,或者SPS等之前
4字节类型的开始码在在连续的数据传输中非常有用,因为用字节来对齐、分割流数据,比如:用连续的31个bit0后接一个bit1来分割流数据,是很容易的。
AnnexB格式每个NALU都包含起始码,且通常会周期性的在关键帧之前重复SPS和PPS
??????所以解码器可以从视频流随机点开始进行解码,实时的流格式
原始码流NALU格式
3.0 RTP单次发送有上限??2种RTP打包:拆包or不拆包
在IP网络中,当要传输的IP报文大小超过【最大传输单元MTU】时就会产生IP分片情况。(若交给底层协议拆包容易出问题→主动拆分NALU再打包成RTP包后发送)
3.1 不分包进行RTP打包:nalu_head(不分包时的包头)
在IP网络中,当要传输的IP报文大小超过【最大传输单元MTU】时就会产生IP分片情况。(若交给底层协议拆包容易出问题→主动拆分NALU再打包成RTP包后发送)
即NALU自身原本的nalu_header
1-12是NALU数据类型
24-31是RTP打包头类型
一个NALU_header解读:
3.2 分包进行RTP打包:FU_indicator和FU_head(RTP分包时的包头)
H264的RTP中有三种不同的封包模式(Single NAL,Non-interleaved,Interleaved)
通过SDP参数中指定,如:
m=video 49170 RTP/AVP 98
a=rtpmap:98 H264/90000
a=fmtp:98 profile-level-id=42A01E; packetization-mode=1; sprop-parameter-sets=Z0IACpZTBYmI,aMljiA==
1、packetization-mode决定封包模式:
1、单一NAL单元模式( Single NAL unit mode):packetization-mode = 0 或者无此字段时缺省
2、非交错模式(Non-interleaved mode): packetization-mode = 1
3、交错模式(Interleaved mode): packetization-mode = 2
2、sprop-parameter-sets: SPS,PPS
这个参数可以用于传输 H.264 的序列参数集和图像参数 NAL 单元. 这个参数的值采用 Base64 进行编码. 不同的参数集间用","号隔开。
//若不用Base64则可能会有数据丢失
3、profile-level-id:
这个参数用于指示 H.264 流的 profile 类型和级别. 由 Base16(十六进制) 表示的 3 个字节. 第一个字节表示 H.264 的 Profile 类型, 第三个字节表示 H.264 的 Profile 级别
3种打包模式–7种打包方式对应关系
另一种看待角度:
①single NAL unit packet 单包(1个RTP包:1个NALU)
②aggregation packets 聚合(组合)包(1个RTP包:多个NALU,提高传输效率),需要解包时在重组。
①STAP (Single-time aggregation packet)
STAP-A
STAP-B
② MTAP (Multi-time aggregation packet)
MTAP16
MTAP24
③Fragmentation Unit 拆包处理【一个NALU→多包 NALU>最大传输单元MTU】
FU-A //非交错模式
FU-B //交错模式
1、单一NALU的RTP包:
2、组合NALU的RTP包:
3、分片NALU的RTP包:
2、FU-A的分片格式
数据比较大的H264视频包,被RTP分片发送。12字节的RTP头后面跟随的就是FU-A分片:
FU_indicator:
F 禁止位
NRI 重要标识位??即拆包的nalu自身的NRI
type RTP打包头类型,FU-A时type=28
FU_header:
S 开始位 1表示分片NAL单元的开始,反之=0
E 结束位 1表示分片NAL单元的结束,反之=0。
R 保留位 必须为0,接收者必须忽略该位。
type NALU数据类型 ??NALU_header
拆包和解包:
发送端—拆包:NAL_header与分片后的FU的单元头有如下关系:
NAL_header前三位为FU_indicator的前三位
NAL_header后五位为FU_header的后五位
接收端—解包:将所有的分片包组合还原成原始的NAl包
nal_unit_type = (fu_indicator & 0xe0) | (fu_header & 0x1f)