RTP Header RTP协议中,RTP Header(报头)包括固定报头(Fixed Header)与报头扩展(Header extension,可选)。 RTP Fixed Header结构如下,其中前12字节内容必须包含的。 [crayon-69bcbaff2b36a076487072/] 但是这Fixed Header携带的信息满足不了更复杂的需求。所以引入了RTP Header Extension,可以携带更多的信息,同时方便各种扩展。 RTP Header Extension 如果RTP Fixed Header中,X字段为1,说明后面跟着RTP Header Extension。RTP Header Extension结构如下: [crayon-69bcbaff2b371468379591/] defined by profile:决定使用哪种Header Extension:one-byte或者two-byte header length:表示Header Extension的长度:length x 4字节 根据Header Extension中ID+len字段所占字节,RTP Header Extension分为One-Byte Header和Two-Byte Header类型。 One-Byte Header 对于One-Byte Header,"defined by profile"字段为固定的0xBEDE。接着后面的结构如下,占用1个byte: [crayon-69bcbaff2b373849753275/] ID:4-bit长度的ID表示本地标识符 len:表示extension data长度,范围:0~15,为0表示长度为1字节,15表示16字节 所以叫做One-Byte Header。 如下是一个One-Byte Header的示例: [crayon-69bcbaff2b374892626914/] 首先是0xBEDE固定字段开头,接着length长度为3,说明后面跟着3x4字节长度的header extension 。对于第一个header extension:L=0,表示data长度为1字节。对于第二个header extension:L=1,表示data长度为2字节。由于按4字节对齐,所以接着是值为0的填充数据。最后一个header extension:L=3,表示data长度为4字节。 WireShark抓包分析 如下是WireShark抓包WebRTC视频流解析的一个RTP包结构: Defined by profile字段为0xBEDE,表示One-Byte Header,Extension length为1,表示Header Extension长度为1x4字节,对于Header Extension:ID为3,Lengh为2。 相关代码Review 构造相关代码位于RtpPacket::AllocateRawExtension中 解析相关代码位于RtpPacket::ParseBuffer中 大家可以对着WebRTC相关代码熟悉下协议。 Two-Byte Header "defined by profile"字段结构如下: [crayon-69bcbaff2b375797782070/] 接着后面跟着的每个扩展元素结构如下,占用2个byte: [crayon-69bcbaff2b377818799676/] ID:本地标识符 length:表示extension data长度,范围1~255 如下是一个Two-Byte Header示例: [crayon-69bcbaff2b378826876812/] 首先"defined by profile"字段为0x1000,length为3,后面跟着3x4字节长度扩展,对于第一个header extension:L=0,数据长度为0,对于第二个header extension:L=1,data长度为1,接着是填充数据,对于第三个header extension:L=4,后面跟着4字节长度数据。 由于WebRTC中默认都是One-Byte Header,所以就不抓包分析了,具体构造解析代码跟One-Byte Header位于同一地方。 常见RTP Header Extension 在WebRTC中定义了很多RTP Header Extension,最常见的要数用于带宽估计的Transport-CC扩展,记录传输层序列号:TransportSequenceNumber,默认每个RTP包都带有此扩展。 还有记录音频能量大小的AudioLevel扩展,记录发送时间的AbsoluteSendTime扩展等等。 看下目前WebRTC支持的几种Header Extension: [crayon-69bcbaff2b379794348045/] SDP 如下是某个示例SDP内容: [crayon-69bcbaff2b37a777771268/] SDP中,a=extmap开头即为RTP Header Extension, 对于RFC中定义的RTP Header Extension,SDP格式如下: [crayon-69bcbaff2b37c327379753/] 对于WebRTC中自定义的RTP Header Extension,SDP格式如下: [crayon-69bcbaff2b37d274721538/] value值就是Header extension的本地标识符(ID值),ID值中0是预留位,所以我们可以看到从1开始递增,对于One-Byte Header来说,15也是预留位。 下面结合该SDP看下某个视频包的Wireshark解析: 可以看到该RTP包共有4个Header extension,这四个Header extension ID分别为:2,3,4,10。根据示例SDP,可知分别是:abs-send-time,transport-wide-cc-extensions,mid,rtp-stream-id扩展。 相关代码 RTP header extension的解析以及构造代码位于rtp_header_extensions.cc中。这里以TransportSequenceNumber扩展为例,看下代码: [crayon-69bcbaff2b37e411677976/] 前面SDP章节提到了,Header extensin ID跟Header extensin类型的对应。它们的对应关系处理在RtpHeaderExtensionMap类中,当进行SetLocalSdp操作时候,会调用: [crayon-69bcbaff2b37f259725193/] 绑定它们的关系。 总结 本文介绍了RTP包中的Header Extension,通过本文可以了解下Header Extension的结构,以及如果根据SDP以及Wireshark分析。 参考 [1] RTP: A Transport Protocol for Real-Time Applications.https://tools.ietf.org/html/rfc3550. [2] A General Mechanism for RTP Header Extensions.https://tools.ietf.org/html/rfc5285.