翻译自:https://www.kurento.org/blog/rtp-i-intro-rtp-and-sdp
FFmpeg and GStreamer 是两个工具可操作rtp,也提供可编程。
rtp已经成为事实的标准用于webRTC或者其他工具传输音视频。原理是一个rtp会话包含一堆参与者,即peer。发送peer吧媒体拆开成chunks,即rtp packets,用udp发送给接收者peer。反之,接收者重新组合。
rtp packet包括固定长的头,可为空的源列表,负载数据payload。
(Bitmap) 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |V=2|P|X| CC |M| PT | sequence number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | timestamp | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | synchronization source (SSRC) identifier | +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | contributing source (CSRC) identifiers | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | payload ... | | +-------------------------------+ | | RTP padding | RTP pad count | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
rtp几十年前制定,现在很多属性已经不用。挑重点:
PT
(Payload Type)除了以前标准定义的,现在一般用自己动态定义的,范围为 [96-127]。比如chrome 96是video VP8, pt 98是vp9,102是h264.
sequence number
随机数开头,然后递增,来确定包的顺序。
timestamp
也是随机数开头,按时钟类型(clock rate)增长,通过相对增量确定改播放的时刻。
SSRC
(Synchronization Source)随机串,每个视频音频在rtp会话中唯一。通过这个识别自己属于哪个媒体。
由于缺失了tcp的保障,rtp的udp传输需要rtcp去控制。发送方提供RTP和RTCP Sender Reports,接收方接收。rtcp发送比rtp少,基本1秒;而rtp更快。
另外还提供 RTCP Feedback (RTCP-FB)
这些RTP的功能有没有实现,需要看下面的描述协议sdp。
在会话前需要确定网络相关和媒体相关信息。sdp是文本型松散格式结构。偏向介绍WebRTC的SDP Offer/Answer 模型。
sdp对于发送方描述了想要什么类型接收者;接收者回应了想让发送者以什么格式发送。
a=行用了添加属性。
示例1:
v=0 o=- 0 0 IN IP4 127.0.0.1 s=- c=IN IP4 127.0.0.1 t=0 0 m=video 5004 RTP/AVP 96 a=rtpmap:96 VP8/90000
两部分,前5行"session-level description":
v=0 o=- 0 0 IN IP4 127.0.0.1 s=- c=IN IP4 127.0.0.1 t=0 0
It describes things such as the peer's host IP address, time bases, and summary description. 大部分可省略,0或 (-
).
下面是 "media-level description", m=
和 (a=
) :
m=video 5004 RTP/AVP 96 a=rtpmap:96 VP8/90000
5004
is the local port where other peers should send RTP packets.5005
本地udp端口 RTCP packets. 总是 RTP port + 1.RTP/AVP
媒体定义 RTP/AVP, as defined in RFC 3551.96
Payload Type在接下来的 RTP packets.VP8/90000
视频编码和时钟频率 RTP packets.示例二,带注释:
# Protocol version; always 0 v=0 # Originator and session identifier o=jdoe 2890844526 2890842807 IN IP4 224.2.17.12 # Session description s=SDP Example # Connection information (network type and host address, like in 'o=') c=IN IP4 224.2.17.12 # NTP timestamps for start and end of the session; can be 0 t=2873397496 2873404696 # First media: a video stream with these parameters: # * The RTP port is 5004 # * The RTCP port is 5005 (implicitly by using RTP+1) # * Adheres to the "RTP Profile for Audio and Video" (RTP/AVP) # * Payload Type can be 96 or 97 m=video 5004 RTP/AVP 96 97 # Payload Type 96 encoding corresponds to VP8 codec a=rtpmap:96 VP8/90000 # Payload Type 97 encoding corresponds to H.264 codec a=rtpmap:97 H264/90000
rtp map定义了Payload type和值:比如 97是H264,时钟频率是9000.
示例三,
定义多个媒体用 m= 分割
v=0 o=- 0 0 IN IP4 127.0.0.1 s=- c=IN IP4 127.0.0.1 t=0 0 m=audio 5006 RTP/AVP 111 a=rtpmap:111 opus/48000/2 a=fmtp:111 minptime=10;useinbandfec=1 m=video 5004 RTP/AVP 96 98 102 a=rtcp:54321 a=rtpmap:96 VP8/90000 a=rtpmap:98 VP9/90000 a=rtpmap:102 H264/90000 a=fmtp:102 profile-level-id=42001f
两个媒体。第一个是音频:
m=audio 5006 RTP/AVP 111 a=rtpmap:111 opus/48000/2 a=fmtp:111 minptime=10;useinbandfec=1
PT是111,Opus,48000Hz,2声道。fmtp
("format parameters")是附加的opus参数。
第二部分是视频:96
,98
, or102
; 优选96。 102是h264,带编解码参数是profile-level-id为42001f。
其他附加属性:
a=rtcp:53020 自指定了rtcp端口。而不是默认的+1
a=rtcp-mux 指rtp和rtcp用同一端口
a=rtcp-rsize 优化传输,在RTP/AVPF时才能用。
a=recvonly 接收方只接收,不发送rtp。当然rtcp还是会发送。
a=sendonly 发送方只发送。rtcp包括。
a=sendrecv 隐含值。
四、SDP Offer/Answer Model (RFC 3264)
初始化sdp会话时的协商。这个模型在SIP或者WebRTC使用。
rtp会话的发起者发起叫sdp offer。接收者根据发来信息,生成新的一个sdp返回,叫sdp answer。RFC 3264 建立规则。
o=
and c=
行.0
.a=rtcp
is in use.a=recvonly
对于对方是 a=sendonly 反之亦然
vice versa.示例:
sdp offer:
v=0 o=- 0 0 IN IP4 127.0.0.1 s=Sample SDP Offer c=IN IP4 127.0.0.1 t=0 0 m=audio 5006 RTP/AVP 111 a=rtpmap:111 opus/48000/2 a=sendonly m=video 5004 RTP/AVP 96 98 102 a=rtcp:5554 a=rtpmap:96 VP8/90000 a=rtpmap:98 VP9/90000 小小网站目录 a=rtpmap:102 H264/90000 a=sendonly m=video 9004 RTP/AVP 96 a=rtpmap:96 VP8/90000 a=sendonly
3路输入,比如可能是1路麦克风,1个摄像头,1个桌面捕获。
sdp answer:选中h264,a=rtcp:
v=0 o=- 3787580028 3787580028 IN IP4 172.17.0.1 s=Sample SDP Answer c=IN IP4 127.0.0.1 t=0 0 m=audio 28668 RTP/AVP 111 a=rtpmap:111 opus/48000/2 a=recvonly m=video 35585 RTP/AVP 102 a=rtpmap:102 H264/90000 a=recvonly m=video 0 RTP/AVP 96
o=
.102
, 对应 H.264 codec. 不支持的属性扔掉。a=rtcp
属性.offer方应该注意到,并发送到35586
(RTP + 1).0。
sdp的交换方式并没有规定。各种方法可用,如最简单的粘贴赋值过去;数据库共享,tcp的websocket,消息服务器MQTT,RabbitMQ,Redis等等都行。
六、附录:
rtsp协议类似HTTP协议。http协议有个http服务提供GET
, POST
, DELETE
, CONNECT
等,RTSP协议也有个rtsp服务提供DESCRIBE
, SETUP
, ANNOUNCE
, TEARDOWN
, PLAY
, PAUSE
, RECORD
, etc.
rtsp包括了signaling。如果简单的rtp和sdp,只是peer交换sdp。而rtsp的客户端可传输所有命令和sdp通过tcp。
rtp任何人可接入rtp会话。安全rtp提供以下保护:
RTP/RTCP协议简介
实时传输协议RTP(RealtimeTransport Protocol):是针对Internet上多媒体数据流的一个传输协议, 由IETF(Internet工程任务组)作为RFC1889发布。RTP被定义为在一对一或一对多的传输情况下工作,其目的是提供时间信息和实现流同步。RTP的典型应用建立在UDP上,但也可以在TCP或ATM等其他协议之上工作。RTP本身只保证实时数据的传输,并不能为按顺序传送数据包提供可靠的传送机制,也不提供流量控制或拥塞控制,它依靠RTCP提供这些服务。
实时传输控制协议RTCP(RealtimeTransportControl Protocol):负责管理传输质量在当前应用进程之间交换控制信息。在RTP会话期间,各参与者周期性地传送RTCP包,包中含有已发送的数据包的数量、丢失的数据包的数量等统计资料,因此,服务器可以利用这些信息动态地改变传输速率,甚至改变有效载荷类型。RTP和RTCP配合使用,能以有效的反馈和最小的开销使传输效率最佳化,故特别适合传送网上的实时数据。
RTCP主要有4个功能:
(1)用反馈信息的方法来提供分配数据的传送质量,这种反馈可以用来进行流量的拥塞控制,也可以用来监视网络和用来诊断网络中的问题;
(2)为RTP源提供一个永久性的CNAME(规范性名字)的传送层标志,因为在发现冲突或者程序更新重启时SSRC(同步源标识)会变,需要一个运作痕迹,在一组相关的会话中接收方也要用CNAME来从一个指定的与会者得到相联系的数据流(如音频和视频);
(3)根据与会者的数量来调整RTCP包的发送率;
(4)传送会话控制信息,如可在用户接口显示与会者的标识,这是可选功能。
RTP/RTCP工作过程
工作时,RTP协议从上层接收流媒体信息码流(如H.263),装配成RTP数据包发送给下层,下层协议提供RTP和RTCP的分流。如在UDP中,RTP使用一个偶数号端口,则相应的RTCP使用其后的奇数号端口。RTP数据包没有长度限制,它的最大包长只受下层协议的限制。
RTP会话和流的两级分用
一个RTP会话(Session)包括传给某个指定目的地对(Destination Pair)的所有通信量,发送方可能包括多个。而从同一个同步源发出的RTP分组序列称为流(Stream),一个RTP会话可能包含多个RTP流。一个RTP分组在服务器端发送出去的时候总是要指定属于哪个会话和流,在接收时也需要进行两级分用,即会话分用和流分用。只有当RTP使用同步源标识(SSRC)和分组类型(PTYPE)把同一个流中的分组组合起来,才能够使用序列号(SequenceNumber)和时间戳(Timestamp)对分组进行排序和正确回放。
由于实时数据的独有性,不同实时客户可以共用一个RTP实时服务线程和一个RTCP实时服务线程,这样可以大大减小服务器的负担,而每个文件客户由于请求的文件不同,相应地对速度和开始时间的要求都可能不同,所以需要有自己独有的RTP文件服务线程和RTCP文件服务线程。
RTP服务线程负责把实时数据流发送给客户,RTCP服务线程根据RTP线程的统计数据,产生发送方报告给客户。RTP线程和RTCP线程之间通过一段共享内存交互统计数据,对共享内存必须设置互斥体进行保护,防止出现错误读写。在这种方式下,服务器可以根据每个用户的不同请求和具体情况方便地提供不同的服务。
RTP 时间戳的处理
时间戳字段是RTP首部中说明数据包时间的同步信息,是数据能以正确的时间顺序恢复的关键。时间戳的值给出了分组中数据的第一个字节的采样时间(Sampling Instant),要求发送方时间戳的时钟是连续、单调增长的,即使在没有数据输入或发送数据时也是如此。在静默时,发送方不必发送数据,保持时间戳的增长,在接收端,由于接收到的数据分组的序号没有丢失,就知道没有发生数据丢失,而且只要比较前后分组的时间戳的差异,就可以确定输出的时间间隔。
RTP规定一次会话的初始时间戳必须随机选择,但协议没有规定时间戳的单位,也没有规定该值的精确解释,而是由负载类型来确定时钟的颗粒,这样各种应用类型可以根据需要选择合适的输出计时精度。
在RTP传输音频数据时,一般选定逻辑时间戳速率与采样速率相同,但是在传输视频数据时,必须使时间戳速率大于每帧的一个滴答。如果数据是在同一时刻采样的,协议标准还允许多个分组具有相同的时间戳值。
RTP协议没有规定RTP分组的长度和发送数据的速度,因而需要根据具体情况调整服务器端发送媒体数据的速度。对来自设备的实时数据可以采取等时间间隔访问设备缓冲区,在有新数据输入时发送数据的方式,时间戳的设置相对容易。对已经录制好的本地硬盘上的媒体文件,以H.263格式的文件为例,由于文件本身不包含帧率信息,所以需要知道录制时的帧率或者设置一个初始值,在发送数据的时候找出发送数据中的帧数目,根据帧率和预置值来计算时延,以适当的速度发送数据并设置时间戳信息。
RTCP的一个关键作用就是能让接收方同步多个RTP流,例如:当音频与视频一起传输的时候,由于编码的不同,RTP使用两个流分别进行传输,这样两个流的时间戳以不同的速率运行,接收方必须同步两个流,以保证声音与影像的一致。为能进行流同步,RTCP要求发送方给每个传送一个唯一的标识数据源的规范名(Canonical Name),尽管由一个数据源发出的不同的流具有不同的同步源标识(SSRC),但具有相同的规范名,这样接收方就知道哪些流是有关联的。而发送方报告报文所包含的信息可被接收方用于协调两个流中的时间戳值。发送方报告中含有一个以网络时间协议NTP(Network Time Protocol)格式表示的绝对时间值,接着RTCP报告中给出一个RTP时间戳值,产生该值的时钟就是产生RTP分组中的TimeStamp字段的那个时钟。由于发送方发出的所有流和发送方报告都使用同一个绝对时钟,接收方就可以比较来自同一数据源的两个流的绝对时间,从而确定如何将一个流中的时间戳值映射为另一个流中的时间戳值。
参考: