RTP Over RTSP Over TCP
2017-02-28 10:40
1476 查看
说明:从各帖子收集了一些资料,结合自己抓包,整理而来
socket接收到RTSP包结构:
[Magic][Channel][0x00][0x00]
Magic:0x24
Channel取值由RTSP协议中Setup阶段设置的interleaved来决定,默认0-1,0代表后面的是RTP包,1代表RTCP包
例如,设置TCP隧道传输RTP:
SETUP rtsp://user:pwd@192.168.1.45:554/trackID=1 RTSP/1.0
CSeq:2
Transport:RTP/AVP/TCP;unicast;interleaved=0-1
后面两个[0x00][0x00]字节是RTP或RTCP包的长度
----------------------------------------------------------------------------------
RTP包由RTP报头和RTP Payload(有效载荷)构成,结构:
[0x00][0x00][0x00][0x00] V(2bit)P(1bit)X(1bit)CC(4bit)M(1bit)PT(7bit)sequence number(16bit)
版本号、填充标记、扩展标记、CSRC计数器、有关有效载荷的标记、有效载荷类型(Payload Type)、序列号
[0x00][0x00][0x00][0x00] time stamp 时间戳
[0x00][0x00][0x00][0x00] synchronization source (SSRC) identifier 同步信源
[0x00][0x00][0x00][0x00] contributing source (CSRC) identifiers 特约信源
………………………………
[Payload........................][Padding]
V:2bit,版本号
P:1bit,Padding标记,取值0-1,0表示Payload后面没有填充,1代表Payload后跟有1个或最多8个字节的填充,如果有填充,
RTP包最后一个字节是填充计数器,表示包含自身在内的填充的字节数
X:1bit,扩展标记
CSRC:4bit,Contributing Source identifiers Count,CSRC计数器 ,特约信源计数器
M:标记,取值0-1,0代表不是一帧的结束,1代表一帧数据的结束,该值是由h264定义的NAL单元传输三个结构中
的FU(Fragmentation unit 分片单元) 结构的Header中E结束位决定的
PT:7bit,有效载荷类型,Payload Type
Seq:16bit,sequence number序列号,在前包的seq上自增1
如果没有扩展,RTP包除去前面12个字节的报头后,就是Payload,如果有Padding,还要减去后面的填充
-------------------------------------------------------------------------------------
RTP Payload的结构,是由h264协议定义的,可能会有三种情况:
1.当NAL单元小于MTU时,可以传输一个完整的NAL单元,即Payload就是原始的h264 NAL单元
2.当NAL单元特别小时,可以同时传送两个或多个NAL单元,即组合封包模式
3.当NAL单元大于MTU是,就分两个或多个RTP包发送,即分片封包 (Fragmentation Units)
H.264的功能分为两层,视频编码层(VCL)和网络提取层(NAL),VCL数据即被压缩编码后的视频数据序列。在VCL数据要封装到NAL单元中之后,才可以用来传输或存储。
对于一个原始的 H.264 NALU 单元常由 [Start Code] [NALU Header] [NALU Payload] 三部分组成, 其中 Start Code 用于标示这是一个NALU 单元的开始, 必须是 "00 00 00 01" 或 "00 00 01", NALU 头仅一个字节, 其后都是 NALU 单元内容。打包时去除 "00 00 01" 或 "00 00 00 01" 的开始码, 把其他数据封包的 RTP 包即可。
如有一个 H.264 的 NALU 是这样的:
[00 00 00 01 67 42 A0 1E 23 56 0E 2F ... ]
这是一个序列参数集 NAL 单元. [00 00 00 01] 是四个字节的开始码, 67 是 NALU 头, 42 开始的数据是 NALU 内容.
封装成 RTP 包将如下:
[ RTP Header ] [ 67 42 A0 1E 23 56 0E 2F ]
即只要去掉 4 个字节的开始码就可以了.
NALU 头的格式:
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|F|NRI| Type |
+---------------+
F:禁止位
编码中默认值为0,当网络识别此单元中存在比特错误时,可将其设为1,以便接收方丢掉该单元,主要 用于适应不同种
类的网络环境(比如有线无线相结合的环境)。
NRI:重要性指示位
用于在重构过程中标记一个NAL单元的重要性,值越大,越重要。值为0表示这个NAL单元没有用于预测,因此可被解码
器抛弃而不会有错误扩散;值高于0表示此NAL单元要用于无漂移重构,且值越高,对此NAL单元丢失的影响越大。
Type:NAL 单元的类型
这个字段和 H.264 中类型字段的区别是, 当 type的值为 24 ~ 31 表示这是一个特别格式的 NAL 单元,
而 H.264 中, 只取 1~23 是有效的值.
0:undefine
1:不分区、非IDR图像的片 ---主要是P帧
2:分片区A
3:分片区B
4:分片区C
5:IDR图像中的片 ---I帧
6:补充增强信息单元(SEI)
7:序列参数集
8:图像参数集
9:分界符
10:序列结束
11:码流结束
12:填充
24:STAP-A 单一时间的组合包
25:STAP-B 单一时间的组合包
26:MTAP16 多个时间的组合包
27:MTAP24 多个时间的组合包
28:FU-A 分片的单元
29:FU-B 分片的单元
30-31 undefine
------------------------------------------------------------------------------------
从RTP包中得到H264数据
单个NAL包单元
12字节的RTP头后面的就是音视频数据,比较简单。一个封装单个NAL单元包到RTP的NAL单元流的RTP序号必须
符合NAL单元的解码顺序
FU-A的分片格式
数据比较大的H264视频包,被RTP分片发送。12字节的RTP头后面跟随的就是FU-A分片:
FU indicator有以下格式:
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|F|NRI| Type |
+---------------+
FU指示字节的类型域 Type=28表示FU-A。。NRI域的值必须根据分片NAL单元的NRI域的值设置。
FU header的格式如下:
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|S|E|R| Type |
+---------------+
S: 1 bit
当设置成1,开始位指示分片NAL单元的开始。当跟随的FU荷载不是分片NAL单元荷载的开始,开始位设为0。
E: 1 bit
当设置成1, 结束位指示分片NAL单元的结束,即, 荷载的最后字节也是分片NAL单元的最后一个字节。当跟随的FU荷载
不是分片NAL单元的最后分片,结束位设置为0。
R: 1 bit
保留位必须设置为0,接收者必须忽略该位。
Type: 5 bits
拆包和解包
拆包:当编码器在编码时需要将原有一个NAL按照FU-A进行分片,原有的NAL的单元头与分片后的FU-A的单元头有如下关系:
原始的NAL头的前三位为FU indicator的前三位,原始的NAL头的后五位为FU header的后五位,FU indicator与FU header的
剩余位数根据实际情况决定。
解包:当接收端收到FU-A的分片数据,需要将所有的分片包组合还原成原始的NAl包时,FU-A的单元头与还原后的NAL的关系如下:
还原后的NAL头的八位是由FU indicator的前三位加FU header的后五位组成,即:
nal_unit_type = (fu_indicator & 0xe0) | (fu_header & 0x1f)
socket接收到RTSP包结构:
[Magic][Channel][0x00][0x00]
Magic:0x24
Channel取值由RTSP协议中Setup阶段设置的interleaved来决定,默认0-1,0代表后面的是RTP包,1代表RTCP包
例如,设置TCP隧道传输RTP:
SETUP rtsp://user:pwd@192.168.1.45:554/trackID=1 RTSP/1.0
CSeq:2
Transport:RTP/AVP/TCP;unicast;interleaved=0-1
后面两个[0x00][0x00]字节是RTP或RTCP包的长度
----------------------------------------------------------------------------------
RTP包由RTP报头和RTP Payload(有效载荷)构成,结构:
[0x00][0x00][0x00][0x00] V(2bit)P(1bit)X(1bit)CC(4bit)M(1bit)PT(7bit)sequence number(16bit)
版本号、填充标记、扩展标记、CSRC计数器、有关有效载荷的标记、有效载荷类型(Payload Type)、序列号
[0x00][0x00][0x00][0x00] time stamp 时间戳
[0x00][0x00][0x00][0x00] synchronization source (SSRC) identifier 同步信源
[0x00][0x00][0x00][0x00] contributing source (CSRC) identifiers 特约信源
………………………………
[Payload........................][Padding]
V:2bit,版本号
P:1bit,Padding标记,取值0-1,0表示Payload后面没有填充,1代表Payload后跟有1个或最多8个字节的填充,如果有填充,
RTP包最后一个字节是填充计数器,表示包含自身在内的填充的字节数
X:1bit,扩展标记
CSRC:4bit,Contributing Source identifiers Count,CSRC计数器 ,特约信源计数器
M:标记,取值0-1,0代表不是一帧的结束,1代表一帧数据的结束,该值是由h264定义的NAL单元传输三个结构中
的FU(Fragmentation unit 分片单元) 结构的Header中E结束位决定的
PT:7bit,有效载荷类型,Payload Type
Seq:16bit,sequence number序列号,在前包的seq上自增1
如果没有扩展,RTP包除去前面12个字节的报头后,就是Payload,如果有Padding,还要减去后面的填充
-------------------------------------------------------------------------------------
RTP Payload的结构,是由h264协议定义的,可能会有三种情况:
1.当NAL单元小于MTU时,可以传输一个完整的NAL单元,即Payload就是原始的h264 NAL单元
2.当NAL单元特别小时,可以同时传送两个或多个NAL单元,即组合封包模式
3.当NAL单元大于MTU是,就分两个或多个RTP包发送,即分片封包 (Fragmentation Units)
H.264的功能分为两层,视频编码层(VCL)和网络提取层(NAL),VCL数据即被压缩编码后的视频数据序列。在VCL数据要封装到NAL单元中之后,才可以用来传输或存储。
对于一个原始的 H.264 NALU 单元常由 [Start Code] [NALU Header] [NALU Payload] 三部分组成, 其中 Start Code 用于标示这是一个NALU 单元的开始, 必须是 "00 00 00 01" 或 "00 00 01", NALU 头仅一个字节, 其后都是 NALU 单元内容。打包时去除 "00 00 01" 或 "00 00 00 01" 的开始码, 把其他数据封包的 RTP 包即可。
如有一个 H.264 的 NALU 是这样的:
[00 00 00 01 67 42 A0 1E 23 56 0E 2F ... ]
这是一个序列参数集 NAL 单元. [00 00 00 01] 是四个字节的开始码, 67 是 NALU 头, 42 开始的数据是 NALU 内容.
封装成 RTP 包将如下:
[ RTP Header ] [ 67 42 A0 1E 23 56 0E 2F ]
即只要去掉 4 个字节的开始码就可以了.
NALU 头的格式:
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|F|NRI| Type |
+---------------+
F:禁止位
编码中默认值为0,当网络识别此单元中存在比特错误时,可将其设为1,以便接收方丢掉该单元,主要 用于适应不同种
类的网络环境(比如有线无线相结合的环境)。
NRI:重要性指示位
用于在重构过程中标记一个NAL单元的重要性,值越大,越重要。值为0表示这个NAL单元没有用于预测,因此可被解码
器抛弃而不会有错误扩散;值高于0表示此NAL单元要用于无漂移重构,且值越高,对此NAL单元丢失的影响越大。
Type:NAL 单元的类型
这个字段和 H.264 中类型字段的区别是, 当 type的值为 24 ~ 31 表示这是一个特别格式的 NAL 单元,
而 H.264 中, 只取 1~23 是有效的值.
0:undefine
1:不分区、非IDR图像的片 ---主要是P帧
2:分片区A
3:分片区B
4:分片区C
5:IDR图像中的片 ---I帧
6:补充增强信息单元(SEI)
7:序列参数集
8:图像参数集
9:分界符
10:序列结束
11:码流结束
12:填充
24:STAP-A 单一时间的组合包
25:STAP-B 单一时间的组合包
26:MTAP16 多个时间的组合包
27:MTAP24 多个时间的组合包
28:FU-A 分片的单元
29:FU-B 分片的单元
30-31 undefine
------------------------------------------------------------------------------------
从RTP包中得到H264数据
单个NAL包单元
12字节的RTP头后面的就是音视频数据,比较简单。一个封装单个NAL单元包到RTP的NAL单元流的RTP序号必须
符合NAL单元的解码顺序
FU-A的分片格式
数据比较大的H264视频包,被RTP分片发送。12字节的RTP头后面跟随的就是FU-A分片:
FU indicator有以下格式:
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|F|NRI| Type |
+---------------+
FU指示字节的类型域 Type=28表示FU-A。。NRI域的值必须根据分片NAL单元的NRI域的值设置。
FU header的格式如下:
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|S|E|R| Type |
+---------------+
S: 1 bit
当设置成1,开始位指示分片NAL单元的开始。当跟随的FU荷载不是分片NAL单元荷载的开始,开始位设为0。
E: 1 bit
当设置成1, 结束位指示分片NAL单元的结束,即, 荷载的最后字节也是分片NAL单元的最后一个字节。当跟随的FU荷载
不是分片NAL单元的最后分片,结束位设置为0。
R: 1 bit
保留位必须设置为0,接收者必须忽略该位。
Type: 5 bits
拆包和解包
拆包:当编码器在编码时需要将原有一个NAL按照FU-A进行分片,原有的NAL的单元头与分片后的FU-A的单元头有如下关系:
原始的NAL头的前三位为FU indicator的前三位,原始的NAL头的后五位为FU header的后五位,FU indicator与FU header的
剩余位数根据实际情况决定。
解包:当接收端收到FU-A的分片数据,需要将所有的分片包组合还原成原始的NAl包时,FU-A的单元头与还原后的NAL的关系如下:
还原后的NAL头的八位是由FU indicator的前三位加FU header的后五位组成,即:
nal_unit_type = (fu_indicator & 0xe0) | (fu_header & 0x1f)
相关文章推荐
- RTP over RTSP(TCP)
- RTSP - RTP over TCP
- RTSP/RTP over TCP
- RTP over RTSP(TCP)
- RTSP - RTP over TCP
- RTSP - RTP over TCP
- RTSP - RTP over TCP
- RTSP - RTP over TCP
- RTSP - RTP over TCP
- RTSP - RTP over TCP
- RTSP - RTP over TCP
- live555 RTSP Server RTP over TCP BUG
- RTSP - RTP over TCP
- (转)live555 RTSP Server RTP over TCP BUG
- RTP over RTSP(TCP)(一)
- RTSP - RTP over TCP
- RTSP - RTP over TCP
- RTSP - RTP over TCP
- EasyPlayerPro Windows流媒体播放器(RTSP/RTMP/HTTP/HLS/File/TCP/RTP/UDP都能播)发布啦
- rtsp/rtp over http