rtsp的讲解
一、RTSP请求的常用方法
方法 | 描述 |
---|---|
OPTIONS | 获取服务端提供的可用方法 |
DESCRIBE | 向服务端获取对应会话的媒体描述信息 |
SETUP | 向服务端发起建立请求,建立连接会话 |
PLAY | 向服务端发起播放请求 |
TEARDOWN | 向服务端发起关闭连接会话请求 |
二、 sdp格式
sdp格式由多行的type=value组成
sdp会话描述由一个会话级描述和多个媒体级描述组成。会话级描述的作用域是整个会话,媒体级描述描述的是一个视频流或者音频流
会话级描述由v=开始到第一个媒体级描述结束
媒体级描述由m=开始到下一个媒体级描述结束
下面是上面示例的sdp文件,我们就来好好分析一下这个sdp文件
v=0\r\n
o=- 91565340853 1 in IP4 192.168.31.115\r\n
t=0 0\r\n
a=contol:*\r\n
m=video 0 RTP/AVP 96\r\n
a=rtpmap:96 H264/90000\r\n
a=framerate:25\r\n
a=control:track0\r\n
这个示例的sdp文件包含一个会话级描述和一个媒体级描述,分别如下
会话级描述
v=0\r\n
o=- 91565340853 1 IN IP4 192.168.31.115\r\n
t=0 0\r\n
a=contol:*\r\n
v=0 表示sdp的版本
o=- 91565340853 1 IN IP4 192.168.31.115
格式为 o=<用户名> <会话id> <会话版本> <网络类型><地址类型> <地址>
用户名:-
会话id:91565340853,表示rtsp://192.168.31.115:8554/live请求中的live这个会话
会话版本:1
网络类型:IN,表示internet
地址类型:IP4,表示ipv4
地址:192.168.31.115,表示服务器的地址
媒体级描述
m=video 0 RTP/AVP 96\r\n
a=rtpmap:96 H264/90000\r\n
a=framerate:25\r\n
a=control:track0\r\n
m=video 0 RTP/AVP 96\r\n
格式为 m=<媒体类型> <端口号> <传输协议> <媒体格式 >
媒体类型:video
端口号:0,为什么是0?因为上面在SETUP过程会告知端口号,所以这里就不需要了
传输协议:RTP/AVP,表示RTP OVER UDP,如果是RTP/AVP/TCP,表示RTP OVER TCP
媒体格式:表示负载类型(payload type),一般使用96表示H.264
a=rtpmap:96 H264/90000
格式为a=rtpmap:<媒体格式><编码格式>/<时钟频率>
a=framerate:25
表示帧率
a=control:track0
表示这路视频流在这个会话中的编号
三、RTSP协议
rtp包由rtp头部和rtp荷载构成
1.rtp头部
RTP头部
版本号(V):2Bit,用来标志使用RTP版本
填充位§:1Bit,如果该位置位,则该RTP包的尾部就包含填充的附加字节
扩展位(X):1Bit,如果该位置位,则该RTP包的固定头部后面就跟着一个扩展头部
CSRC技术器(CC):4Bit,含有固定头部后面跟着的CSRC的数据
标记位(M):1Bit,该位的解释由配置文档来承担
载荷类型(PT):7Bit,标识了RTP载荷的类型
序列号(SN):16Bit,发送方在每发送完一个RTP包后就将该域的值增加1,可以由该域检测包的丢失及恢复
包的序列。序列号的初始值是随机的
时间戳:32比特,记录了该包中数据的第一个字节的采样时刻
同步源标识符(SSRC):32比特,同步源就是RTP包源的来源。在同一个RTP会话中不能有两个相同的SSRC值
贡献源列表(CSRC List):0-15项,每项32比特,这个不常用
2.rtp载荷
rtp载荷为音频或者视频数据
3.RTP OVER TCP
RTP默认是采用UDP发送的,格式为RTP头+RTP载荷,如果是使用TCP,那么需要在RTP头之前再加上四个字节
第一个字节:$,辨识符
第二个字节:通道,在SETUP的过程中获取
第三第四个字节: RTP包的大小,最多只能12位,第三个字节保存高4位,第四个字节保存低8位
四、H.264的RTP打包
1 H.264格式
H.264由一个一个的NALU组成,每个NALU之间使用00 00 00 01
或00 00 01
分隔开
每个NALU的第一次字节都有特殊的含义,其内容如下
位 | 描述 |
---|---|
bit[7] | 必须为0 |
bit[5-6] | 标记该NALU的重要性 |
bit[0-4] |
2 H.264的RTP打包方式
H.264可以由三种RTP打包方式
-
单NALU打包
一个RTP包包含一个完整的NALU
-
聚合打包
对于较小的NALU,一个RTP包可包含多个完整的NALU
-
分片打包
对于较大的NALU,一个NALU可以分为多个RTP包发送
注意:这里要区分好概念,每一个RTP包都包含一个RTP头部和RTP荷载,这是固定的。而H.264发送数据可支持三种RTP打包方式
比较常用的是单NALU打包和分片打包,本文也只介绍这两种
单NALU打包
所谓单NALU打包就是将一整个NALU的数据放入RTP包的载荷中
这是最简单的一种方式,无需过多的讲解
分片打包
每个RTP包都有大小限制的,因为RTP一般都是使用UDP发送,UDP没有流量控制,所以要限制每一次发送的大小,所以如果一个NALU的太大,就需要分成多个RTP包发送,如何分成多个RTP包,下面来好好讲一讲
首先要明确,RTP包的格式是绝不会变的,永远多是RTP头+RTP载荷
RTP头部是固定的,那么只能在RTP载荷中去添加额外信息来说明这个RTP包是表示同一个NALU
如果是分片打包的话,那么在RTP载荷开始有两个字节的信息,然后再是NALU的内容
第一个字节位FU Indicator
,其格式如下
高三位:与NALU第一个字节的高三位相同
Type:28,表示该RTP包一个分片,为什么是28?因为H.264的规范中定义的,此外还有许多其他Type,这里不详讲
第二个字节位FU Header
,其格式如下
S:标记该分片打包的第一个RTP包
E:比较该分片打包的最后一个RTP包
Type:NALU的Type
3 H.264 RTP包的时间戳计算
RTP包的时间戳起始值是随机的
RTP包的时间戳增量怎么计算?
假设时钟频率为90000,帧率为25
频率为90000表示一秒用90000点来表示
帧率为25,那么一帧就是1/25秒
所以一帧有90000*(1/25)=3600个点来表示
因此每一帧数据的时间增量为3600
4.H.264 RTP打包的sdp描述
dp描述着媒体信息,当使用vlc打开这个sdp文件后,会根据这些信息做相应的操作(创建套接字…),然后等待接收RTP包
这里给出RTP打包H.264的sdp文件,并描述每一行是什么意思
m=video 9832 RTP/AVP 96
a=rtpmap:96 H264/90000
a=framerate:25
c=IN IP4 127.0.0.1
这个一个媒体级的sdp描述,关于sdp文件描述详情可看从零开始写一个RTSP服务器(一)不一样的RTSP协议讲解
m=video 9832 RTP/AVP 96
格式为 m=<媒体类型> <端口号> <传输协议> <媒体格式 >
媒体类型:video,表示这是一个视频流
端口号:9832,表示UDP发送的目的端口为9832
传输协议:RTP/AVP,表示RTP OVER UDP,通过UDP发送RTP包
媒体格式:表示负载类型(payload type),一般使用96表示H.264
a=rtpmap:96 H264/90000
格式为a=rtpmap:<媒体格式><编码格式>/<时钟频率>
a=framerate:25
表示帧率
c=IN IP4 127.0.0.1
IN:表示internet
IP4:表示IPV4
127.0.0.1:表示UDP发送的目的地址为127.0.0.1
五、AAC的RTP打包
1 AAC格式
AAC音频文件有一帧一帧的ADTS帧组成,每个ADTS帧包含ADTS头部和AAC数据,如下所示
ADTS头部的大小通常为7个字节
,包含着这一帧数据的信息,内容如下
各字段的意思如下
syncword
总是0xFFF, 代表一个ADTS帧的开始, 用于同步.
ID
MPEG Version: 0 for MPEG-4,1 for MPEG-2
Layer
always: ‘00’
protection_absent
Warning, set to 1 if there is no CRC and 0 if there is CRC
profile
表示使用哪个级别的AAC,如01 Low Complexity(LC) – AAC LC
sampling_frequency_index
采样率的下标
aac_frame_length
一个ADTS帧的长度包括ADTS头和AAC原始流
adts_buffer_fullness
0x7FF 说明是码率可变的码流
number_of_raw_data_blocks_in_frame
表示ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧
这里主要记住ADTS头部通常为7个字节,并且头部包含aac_frame_length
,表示ADTS帧的大小
AAC的RTP打包方式
AAC的RTP打包方式并没有向H.264那样丰富,我知道的只有一种方式,原因主要是AAC一帧数据大小都是几百个字节,不会向H.264那么少则几个字节,多则几千
AAC的RTP打包方式就是将ADTS帧取出ADTS头部,取出AAC数据,每帧数据封装成一个RTP包
需要注意的是,并不是将AAC数据直接拷贝到RTP的载荷中。AAC封装成RTP包,在RTP载荷中的前四个字节是有特殊含义的,然后再是AAC数据,如下图所示
其中RTP载荷的一个字节为0x00,第二个字节为0x10
第三个字节和第四个字节保存AAC Data的大小,最多只能保存13bit,第三个字节保存数据大小的高八位,第四个字节的高5位保存数据大小的低5位
3 AAC RTP包的时间戳计算
假设音频的采样率位44100,即每秒钟采样44100次
AAC一般将1024次采样编码成一帧,所以一秒就有44100/1024=43帧
RTP包发送的每一帧数据的时间增量为44100/43=1025
每一帧数据的时间间隔为1000/43=23ms