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會從線程池中找一條負載最小的線程來分配任務。會在客戶端連接斷開后從線程池釋放。