RTPS代理与转发服务
Proxy介绍
利用libevent实现网络连接和线程池。通过tcp连接的方式实现rtsp消息转发,再通过udp连接进行rtp与rtcp转发。报文解析使用到了Qt库。请尽量使用qmake进行编译。源码
通讯时序图
RTSP协议介绍
RTSP协议是一套用来进行音视频发送与接收的网络协议,与HTTP协议不同。它包含了一套tcp连接和两套udp连接。通过对协议的实测,大致的交互流程如下:
1. 服务端监听tcp连接:默认的连接端口是554,如果你希望实现自己的rtsp服务也可以自定义。
2. 客户端连接后需要根据固定的顺序完成握手:OPTIONS、DESCRIBE、SETUP、PLAY和TEARDOWN。除此以外的其它请求都为可选。
3. 服务端的返回值最常见的是200和403。如果返回200则表示请求通过,403表示需要验证验证权限。
4. 在客户端发送SETUP请求的报文中需要包含client_port=xxxx-xxxx的信息,通常是相邻的两个端口号,前一个是偶数端口用来接收rtp音视频报文,后一个端口是奇数端口用来发送rtcp同步报文。
5. 服务端收的应答中会包含server_port=xxxx-xxxx的信息,也是两个相邻端口号。偶数为rtp发送端口,奇数为rtcp接收端口。
6. 最后等待客户端发送PLAY请求,双方开始启用udp通信,tcp连接保持。海康的硬盘录像机除可以使用rtsp协议获取直播流以外还能获取录像流。当客户端与服务器建立完成连接后,客户端通过重新发送PLAY请求动态调整录像的播放速率。服务器调整播放速度其实只是调整了rtp端口的报文发送速度而已,具体解码播放还是要播放器来实现。
Proxy做了哪些工作
通过tcp连接,proxy接受客户端的连接后会向服务器发起连接,并将服务器的rtsp报文转发回客户端处理。因此握手与校验的工作依然需要由客户端来完成。
当proxy接收到来自客户端的SETUP请求后会将client_port=xxxx-xxxx的报文替换成自己的代理端口。服务器返回的server_port=xxxx-xxxx报文也会被替换。proxy内部会将这4个udp端口两两配对,两个偶数端口组成一个rtp管线负责向下转发,两个奇数端口组成rtcp管线负责向上转发。这两条管线(UdpPipe)我们称为StreamTask,会分配给一个线程(StreamThread)运行。线程来自一个用libevent实现的线程池(ThreadPool)。每当有一个StreamTask被创建的时候,proxy会从线程池中找一条负载最小的线程来分配任务。会在客户端连接断开后从线程池释放。