先给自己打个广告,本人的微信公众号正式上线了,搜索:张笑生的地盘,主要关注嵌入式软件开发,股票基金定投,足球等等,希望大家多多关注,有问题可以直接留言给我,一定尽心尽力回答大家的问题
一 what
一个rtp码流是由rtp header和stream组成的,如下:
- rtp固定header
rtp header的定义在ortp开源库中的定义如下:
typedef struct rtp_header
{
#ifdef ORTP_BIGENDIAN
uint16_t version:2; //定义RTP版本,此协议定义的版本是2(值1被RTP草案版本使用,值0用在最初"vat"语音工具使用的协议中)
uint16_t padbit:1; //=1: 则此包包含1~n个附加在末端的填充比特,填充比特不算作负载的一部分。填充的最后一个字节指明可以忽略多少个填充比特。填充可能用于某些具有固定长度的加密算法,或者用于在底层数据单元中传输多个RTP包
uint16_t extbit:1; //=1: 固定头(仅)后面跟随一个头扩展
uint16_t cc:4; //CSRC 计数包含了跟在固定头后面CSRC识别符的数目
uint16_t markbit:1; //=1:表示该帧结束,=0:表示仍然是音视频数据
uint16_t paytype:7; //此域定义了负载的格式,由具体应用决定其解释,协议可以规定负载类型码和负载格式之间一个默认的匹配。其他的负载类型码可以通过非 RTP 方法动态定义。RTP发送端在任意给定时间发出一个单独的 RTP 负载类型;此域不用来复用不同的媒体流
#else
uint16_t cc:4; //CSRC 计数包含了跟在固定头后面CSRC识别符的数目
uint16_t extbit:1; //=1: 固定头(仅)后面跟随一个头扩展
uint16_t padbit:1; //=1: 则此包包含1~n个附加在末端的填充比特,填充比特不算作负载的一部分。填充的最后一个字节指明可以忽略多少个填充比特。填充可能用于某些具有固定长度的加密算法,或者用于在底层数据单元中传输多个RTP包
uint16_t version:2; //定义RTP版本,此协议定义的版本是2(值1被RTP草案版本使用,值0用在最初"vat"语音工具使用的协议中)
uint16_t paytype:7; //此域定义了负载的格式,由具体应用决定其解释,协议可以规定负载类型码和负载格式之间一个默认的匹配。其他的负载类型码可以通过非 RTP 方法动态定义。RTP发送端在任意给定时间发出一个单独的 RTP 负载类型;此域不用来复用不同的媒体流
uint16_t markbit:1; //=1:表示该帧结束,=0:表示仍然是音视频数据
#endif
uint16_t seq_number; //RTP包顺序,比如一帧K帧,200K,顺序可能是0-199,最后一个包Marker位为1
uint32_t timestamp; //这个值并非每帧的时间戳,但是一个音频或视频包此项是相同的,因为MTU的限制,一帧数据的长度可能大于1400,一帧数据会被拆分为多个包发送
uint32_t ssrc; //为流标识,实际可以多个流往一个端口上发,通过此位标识
uint32_t csrc[16];
} rtp_header_t;
- rtp扩展header
根据rtp固定header中extbit定义可知,当此位域=1时,rtp流中存在一个rtp扩展header,我们肯定会想问:为何添加扩展头部header?
它允许实现实现个性化:某些新的与负载格式独立的功能要求的附加信息在RTP 数据包头中传输。设计此方法可以使其它没有扩展的交互忽略此头扩展。RTP扩展头格式如下所示。
RTP 固定头之后只允许有一个头扩展,为允许多个互操作实现,独立生成不同的头扩展,或某种特定实现有多种不同的头扩展,扩展项的前16比特用以识别标识符或参数。这 16 比特的格式由具体实现的上层协议定义。接下来16bit是指示长度域,指示扩展项中 32 比特字的个数,不包括 4 个字节扩展头(因此零是有效值)。
基本的 RTP 说明并不定义任何头扩展本身。
二 why
三 how