H264 over RTP 的打包


多媒体实时通信(如语音或视频通话)一般会使用RTP/UDP进行传输,本文对H264视频在RTP传输的数据格式进行总结,RFC6184 《RTP Payload Format for H.264 Video》是H264 over RTP的规范文档,详细的内容和细节请参考该规范;本文满足RFC6184,且只是其内容的一部分,但这部分对于视频通话来说已经足够了,我曾经所负责的一个实时视频通话项目就是这样实现的。


  • 打包流程

1)从H264编码器读出一帧数据(一个完整的H264帧)

2)然后遍历H264的所有NALU; H264帧数据结构见下章节

2.1)如果NALU长度小于MTU,则将该NALU打包为一个RTP包

2.2)否则,将NALU按照MTU大小进行分片(本文只用FU-A分片格式)


  • H264帧结构

H264帧由多个NALU组成和起始码(start code),NALU之间有一个称为“起始码”字段分开,就是上图所示的黑色部分,起始码有两种格式:0x000001和0x00000001;有了起始码,我们就可以将H264帧里面的每个NALU取出来进行处理了。细心的读者们可能会有一个疑惑,如果NALU这个数据里面也包含有0x000001或0x00000001那就有问题了,是的!你能想到的问题,H264的专家也会想到的,H264规范里面对这个有特殊处理的,会进行相应的转码,确保NALU里面内容是不会出现0x000001和0x00000001的。

一个NALU由Header和RBSP两部分构成。


  • NALU打包到RTP

上图展示了如何将一个NALU打包到RTP的payload;上图的左边的打包流程对应的场景是“NALU的长度 <= MTU”,直接将NALU的header拷贝到H264 RTP Payload Header上,将NALU的RBSP拷贝到H264 RTP Payload Content上。

上图右边的打包流程对应的场景是“NALU的长度 > MTU”,要将NALU的RBSP进行分片,以保证打包后的RTP报文长度不大于MTU,H264 RTP Payload Header由FU-identity + FU Header组成;FU-identity字段和NALU header字段的格式一样(如果不一样的话,接收端就搞不清这是一个NALU分片还是一整个NALU了),其最低的5bits表示payload的类型(不同的取值表示RTP的类型不同,见下表);FU payload就是NALU的RBSP(一部分);另外,属于同一H264帧的所有RTP头的时间戳都要打成相同的,接收端根据时间戳来判断哪些包是属于同一个H264帧的。

Payload Type Packet Type
0 reserved
1-23 NALU unit
24 STAP-A
25 STAP-B
26 MTAP16
27 MTAP24
28 FU-A
29 FU-B
30-31 reserved

  • 代码

以后有时间了再整理出来。

猜你喜欢

转载自blog.csdn.net/u010178611/article/details/82592393