RTP协议文档RFC3550,RTP两个子协议RTP、RTCP都在这个文档里边。
RTSP是流媒体控制协议,用于媒体传输的交互,具体媒体负载用RTP协议传输,RTP协议,用于实时传输数据,协议信息包括:时间戳、序列号、负载格式。
RTP协议头:
- V - version(2 bits)
字段值默认为0x02 - P - padding(1 bit)
此位被填充的话,在报文尾填充一个或多个额外的八位组,非有效载荷 - X - extension(1 bit)
扩展标志,若=1,在RTP header报文后跟一个扩展报头 - CC - CSRC count(4 bits)
CSRC计数器,即共享媒体源个数,一般用于混音、混屏 - M - marker(1 bit)
根据载荷不同,表示不同含义;表示视频一帧的结尾,或音频会话的开始 - PT - payload type(7 bits)
标志载荷类型
音频类型:
视频载荷:
- sequence number(16 bits)
序列号,标识发送者发送的RTP包的序列号,序列号递增;起始序列号是随机的;序列号可以用来检查UDP传输下的丢包及客户端对数据的排序。 - timestamp(32 bits)
时间戳,反应RTP数据包的采样时间,一帧数据可能被分成多个RTP包发送,同一个帧的时间戳是一样的;初始值随机 - SSRC(32 bits)
同步信源标识 - CSRC list(0-15 items, 32 bits each)
特约信源,可以有0-15个,每个占32位
RTP包封装代码实例:
#include "type.h"
typedef struct RTP_header
{
u8 csrcCount:4; //共享媒体源个数
u8 extension:1; //拓展字段,=1填充拓展报文头
u8 padding:1; //填充标志,=1需要在报文位填充空数据,4字节对齐
u8 version:2; //版本,默认2
u8 payloadType:7; //载荷类型,h.264填充动态类型96即可
u8 mark:1; //视频帧起始或者音频会话的结束
u16 sequenceNumber; //序列号,起始序列号随机
u32 timeStamp; //时间戳
u32 ssrc; //同步信源的标识
u32 csrc[0]; //特约信源标识,仅占位,由前边的csrcCount决定
}RTP_header;
typedef struct RTP_packet
{
RTP_header rtpHeader;
u8 payload[0];
}RTP_packet;
拓展协议头(了解)
填充拓展标志后,需要在RTP header后跟一个拓展协议头:
- defined by profile(16 bits)
两种类型:one-byte header和two-byte header,当profile=0xBEDE时是one-byte header,0x1000时是two-byte header - length(16 bits)
表示后边的header extension共有几个字节,长度以4字节为单位,如length=3表示header extension共有12字节 - header extension(32 bits)
具体的拓展头,由ID-L-data组成,组织形式是one-byte header或two-byte header,这里暂时只做拓展了解,摄像头实时流不一定用这个,用上的时候再说~
RTP载荷为H.264
标准文档RFC6184
H264需要在NALU前边添加NALU Header:
- F(1 bit)
forbidden_zero_bit,必须为0 - NRI(2 bits)
nal_ref_idc,00-11,给解码器的NALU重要性的权值,不是太关心 - Type(5 bits)
nal_unit_type,有如下表的type
总结下来,就是对传输过程中NALU的处理分了三种情况,用来适应网络传输中(主要是MTU最大传输单元)的情况:
单个NALU
H264的NALU载荷适应MTU的情况下,一次传输一个完整的NALU
协议非常简单,就是加F-NRI-TYPE的头,后边按照四字节对齐补padding;
type字段对于single NALU packet来说,就是H264规定的类型(0-23),常见的如下:
Type | 含义 |
---|---|
0 | 未指定 |
1 | 非IDR图像的片 |
5 | IDR图像的片 |
6 | SEI(辅助增强信息) |
7 | SPS(序列参数集) |
8 | PPS(图像参数集) |
组合NALU
NALU大小远不够MTU,可以多个NALU一起传输
组合包有四种:
其
-
STAP-A
上图为STAP-A格式 2 NALU组合发送的格式,HDR(header)中NRI为所有NALU最大值,Type=24 -
STAP-B
上图为STAP-B格式 2 NALU组合发送的格式,HDR(header)中Type=25,STAP-B HDR后紧跟DON(decoding order number,16 bits),这个DON是决定解码顺序的标号,包到达时间可能和解码顺序不同,用这个标记解码器识别按顺序解码,这里暂时不多研究,聚合包的形式暂时只了解不深究,可能代码可以暂时不用。也希望有大佬可以指导两句~~ -
MTAP16
-
MTAP24
分片NALU
一个NALU已经超了MTU,需要一个NALU分开多次传输
-
FU-A
FU indicator格式如下:
这个就不解释了,前边一样
FU header格式如下:
S - start(1 bit):为1时,标识这个是一帧数据的起始分片;
E - end(1 bit):为1时,标识这个是一帧数据分片的结尾;
R - forbiden bit(1 bit):必须填0;
Type - nal_unit_type(5 bits):H264码流帧类型,1-23. -
FU-B
这个和FU-A差不多,也是多了16 bits DON,解码顺序,这里也可暂时不多研究。
注意
:
1.上述都是网络协议,默认网络字节序即大端字节序
封装;
2.具体的H.264负载,已经有RTP包装,不需要带上start code
;当然实测发现带上了也不影响