1、
RTSP的建立過程大概有這麼幾個
OPTIONS請求:詢問有哪些方法可用,這個請求似乎不太會用到
DESCRIBE請求:查詢服務器發送的媒體流的信息
SETUP請求:告知服務器建立連接,並告知端口號
PLAY請求:告知服務器開始以RTP包的形式發送數據
TEARDOWN請求:關閉連接
源代碼中請求的處理函數有很多,上面的幾個是比較有代表性的
2、
來看下服務器是如何處理一個DESCRIBE請求的的
在這之前,要有一個認識,在服務器端我們會建立一個RTSPSever,建立ServerMediaSession來表示服務器下的媒體文件,建立ServerMediaSubsession表示一個媒體文件中的視頻或音頻,一個ServerMediaSession可以包含多個ServerMediaSubsession。
(1)、
對應DESCRIBE的處理函數在RTSPServer::RTSPClientConnection::handled_DESCRIBE
(這裏提一下,在最新的live555源代碼中,請求的處理函數被分成了兩個類,一個是RTSPClientConnection,一個是RTSPClientSession。看一些之前的博客,以前的版本似乎是沒有RTSPClientConnection這個類的)
在處理函數handled_DESCRIBE中,又調用ServerMediaSession::generateSDPDescription函數,這個函數是爲了獲取SDP信息
(這裏提一下,ServerMediaSession的SDP信息是有其包含的所有ServerMediaSubsession的SDP信息組合在一起形成的)
該函數將產生的SDP消息發送給客戶端,客戶端以此得到媒體流信息
(2)、
爲了獲取每個ServerMediaSubsession的SDP信息,程序調用sdplines函數(我的源代碼在OnDemandServerMediaSubsession類中)
(這裏提一下,live555獲取SDP信息的方法是讓媒體文件播放一下,建個“零時”的FramedSource和RTPSink來模擬下發送接收,而且FramedSource和RTPSink的建立不同編碼格式調用不同的函數(同名,虛函數重寫))
FramedSource:獲取數據
RTPSink:用來保存RTP數據包
獲取sdp的函數
setSDPLinesFromRTPSink(dummyRTPSink, inputSource, estBitrate);
dummyRTPSink:RTPSink類對象
inputSource:FramedSource類對象
estBitrate: int(sdp信息應該就在這裏面)
(3)、
在函數setSDPLinesFromRTPSink中,調用分工明確的子函數獲取SDP的不同字段的信息
(再類RTPSink中定義了很多用於獲取sdp信息的成員函數)
(4)、
可以單獨拿出來寫一下的事獲取SDP中的auxSDPLine,調用函數getAuxSDPLine(rtpSink, inputSource)。不過不同的編碼格式重寫了這個函數
(5)、
到這裏,服務器成功獲得了媒體文件的SDP消息,接着,客戶端就可以向服務器發送SETUP請求,建立連接,連接建立好後就可以發送PLAY開始接收媒體流數據了