LIVE555 使用流程

來源:互聯網
上載者:User

1. RTSP串連的建立過程

      RTSPServer類用於構建一個RTSP伺服器,該類同時在其內部定義了一個RTSPClientSession類,用於處理單獨的客戶會話。

      首先建立RTSP伺服器(具體實作類別是DynamicRTSPServer),在建立過程中,先建立Socket(ourSocket)在TCP的554連接埠進行監聽,然後把串連處理函數控制代碼(RTSPServer::incomingConnectionHandler)和socket控制代碼傳給任務調度器(taskScheduler)。

      任務調度器把socket控制代碼放入後面select調用中用到的socket控制代碼集(fReadSet)中,同時將socket控制代碼和incomingConnectionHandler控制代碼關聯起來。 接著,主程式開始進入任務調度器的主迴圈(doEventLoop),在主迴圈中調用系統函數select阻塞,等待網路連接。

      當RTSP用戶端輸入(rtsp://192.168.0.1/1.mpg)串連伺服器時,select返回對應的scoket,進而根據前面儲存的對應關係,可找到對應處理函數控制代碼,這裡就是前面提到的incomingConnectionHandler了。在incomingConnectionHandler中建立了RTSPClientSession,開始對這個用戶端的會話進行處理。

2. DESCRIBE請求訊息處理過程

      RTSP伺服器收到用戶端的DESCRIBE請求後,根據請求URL(rtsp://192.168.0.1/1.mpg),找到對應的流媒體資源,返迴響應訊息。live555中的ServerMediaSession類用來處理會話中描述,它包含多個(音頻或視頻)的子會話描述(ServerMediaSubsession)。

      RTSP伺服器收到用戶端的串連請求,建立了RTSPClientSession類,處理單獨的客戶會話。在建立RTSPClientSession的過程中,將建立立的socket控制代碼(clientSocket)和RTSP請求處理函數控制代碼RTSPClientSession::incomingRequestHandler傳給任務調度器,由任務調度器對兩者進行一對一關聯。

      當用戶端發出RTSP請求後,伺服器主迴圈中的select調用返回,根據socket控制代碼找到對應的incomingRequestHandler,開始訊息處理。先進行訊息的解析,如果發現請求是DESCRIBE則進入handleCmd_DESCRIBE函數。根據用戶端請求URL的尾碼(如1.mpg),調用成員函數DynamicRTSPServer::lookupServerMediaSession尋找對應的流媒體資訊ServerMediaSession。如果ServerMediaSession不存在,但是本地存在1.mpg檔案,則建立一個新的ServerMediaSession。在建立ServerMediaSession過程中,根據檔案尾碼.mpg,建立媒體MPEG-1or2的解複用器(MPEG1or2FileServerDemux)。再由MPEG1or2FileServerDemux建立一個子會話描述MPEG1or2DemuxedServerMediaSubsession。最後由ServerMediaSession完成組裝響應訊息中的SDP資訊(SDP組裝過程見下面的描述),然後將響應訊息發給用戶端,完成一次訊息互動。SDP訊息組裝過程:

      ServerMediaSession負責產生會話公用描述資訊,子會話描述由MPEG1or2DemuxedServerMediaSubsession產生。 MPEG1or2DemuxedServerMediaSubsession在其父類成員函數OnDemandServerMediaSubsession::sdpLines()中產生會話描述資訊。在sdpLines()實現裡面,建立一個虛構(dummy)的FramedSource(具體實作類別為MPEG1or2AudioStreamFramer和MPEG1or2VideoStreamFramer)和RTPSink(具體實作類別為MPEG1or2AudioRTPSink和MPEG1or2VideoRTPSink),最後調用setSDPLinesFromRTPSink(...)成員函數產生子會話描述。

3. SETUP請求訊息處理過程

        RTSPClientSession類用於處理單獨的客戶會話。其類成員函數handleCmd_SETUP()處理用戶端的SETUP請求。調用parseTransportHeader()對SETUP請求的傳輸頭解析,調用子會話(這裡具體實作類別為OnDemandServerMediaSubsession)的getStreamParameters()函數擷取流媒體發送傳輸參數。將這些參數組裝成響應訊息,返回給用戶端。

        擷取發送傳輸參數的過程:調用子會話(具體實作類別MPEG1or2DemuxedServerMediaSubsession)的createNewStreamSource(...)建立MPEG1or2VideoStreamFramer,選擇發送傳輸參數,並調用子會話的createNewRTPSink(...)建立MPEG1or2VideoRTPSink。同時將這些資訊儲存在StreamState類對象中,用於記錄流的狀態。

        用戶端發送兩個SETUP請求,分別用於建立音頻和視頻的RTP接收。

4. PLAY請求訊息處理過程

      RTSPClientSession類成員函數handleCmd_PLAY()處理用戶端的播放請求。首先調用子會話的startStream(),內部調用MediaSink::startPlaying(...),然後是MultiFramedRTPSink::continuePlaying(),接著調用MultiFramedRTPSink::buildAndSendPacket(...)。buildAndSendPacke內部先設定RTP包頭,內部再調用MultiFramedRTPSink::packFrame()填充編碼幀資料。

      packFrame內部通過FramedSource::getNextFrame(), 接著MPEGVideoStreamFramer::doGetNextFrame(),再接著經過MPEGVideoStreamFramer::continueReadProcessing(), FramedSource::afterGetting(...), MultiFramedRTPSink::afterGettingFrame(...), MultiFramedRTPSink::afterGettingFrame1(...)等一系列繁瑣調用,最後到了MultiFramedRTPSink::sendPacketIfNecessary(),
這裡才真正發送RTP資料包。然後是計算下一個資料包發送時間,把MultiFramedRTPSink::sendNext(...)函數控制代碼傳給任務調度器,作為一個延時事件調度。在主迴圈中,當MultiFramedRTPSink::sendNext()被調度時,又開始調用MultiFramedRTPSink::buildAndSendPacket(...)開始新的發送資料過程,這樣用戶端可以源源不斷的收到伺服器傳來的RTP包了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.