• 沒有找到結果。

RTSP PLAY

在文檔中 串流伺服器特性剖析 (頁 52-0)

二、 連線建立與 RTSP 信令溝通

2.4 Server 與 Client 互動之流程

2.4.2 Live555 RTSP 動作流程

2.4.2.4 RTSP PLAY

Client 接收 server 回傳的 SETUP 訊息後便會知道 server 端所使用的 RTP/RTCP 阜 號資訊,故 VLC player(Client)在完成用戶端接收模組的初始化動作後,便發出 PLAY 訊息告知伺服器可開始傳輸 RTP 封包。VLC player 發送的 PLAY 信令內容包括了多媒 體檔案的起始時間、終止時間等資訊,如下圖 2.21 所示,起始時間為 0.000 即是片頭一 開始,而終止時間未著名表示請 Live RTSPserver 播放到最後。

(VLC client 發送 PLAY 訊息給 Live RTSPServer,請求傳送 RTP 封包資料)

圖 2.21 client RTSP PLAY request

下圖2.22所示的是Live RTSPserver的PLAY回應封包內容,伺服器如果完成串流傳輸 的準備,則將下一個RTP封包的序號(sequence number)先傳給client做為確認之用。

(Live RTSPserver 的 PLAY 封包內容,傳回給 VLC client player)

圖 2.22 server RTSP PLAY response

2.4.2.5 client RTSP PAUSE request

Client 要求暫停 session 傳送但不釋放伺服器端資源,如下圖 2.23 所示。

圖 2.23 client RTSP PAUSE request

如果Server接受暫停指令,則回傳一個封包給client確認之,並暫停串流資料的傳 輸,server針對RTSP PAUSE回應內容如下圖2.24所示。

(Live RTSPServer告知VLC player已暫停封包的傳送)

圖 2.24 server RTSP PAUSE response

2.4.2.6 client RTSP TEARDOWN request

Client 要求將整個串流傳輸停止,如下圖 2.25 所示。

圖 2.25 client RTSP TEARDOWN request

當伺服器接收到此訊息後便關閉此串流傳輸,釋放連線的所有資源,並回應確認訊 息給使用者,Server針對RTSP TEARDOWN回應內容如下圖2.26所示,可以看到Live RTSPServer傳回確認訊息給VLC player後,便是TCP連線結束的handshaking。

連線結束 TCP handshaking

圖 2.26 server RTSP TEARDOWN response

要注意的是 client 端的程式設計在完成 SDP 格式的 coding 後,最後記得都要呼叫 sendRequest()將封包傳送之(也就是 BSD API 的 send())。

2.4.3 client getResponse()

在 client 端呼叫 BSD send()來發送 RTSP 命令後,server 端即回應相對應的 RTSP response 給 client,這時候 client 必須呼叫 getResponse()來接收 server 端所回應的 RTSP 訊息。

如下面的 getResponse()函數呼叫圖所示,當 client 接收到 server 的 RTSP response 後,需再呼叫五個函數,功能如下所述:

a.getLine()是一行一行地去讀取 SDP 的文字內容。

b.envir()函數主要是傳回一個 UsageEnvironment 的地址參照,如我們前面所介紹過的,

UsageEnvironment 這個類別的功用是負責接收串流程式內部所產生的訊息,並且把這 些訊息傳達給使用者知道。

c.getResponse1()

再去呼叫 BSD 的 recvfrom()來接收 server 所回應的 RTSP 訊息。

BSD soclet API recvfrom()如下所標示部分。

recvfrom():

經由 clientsocket (connected socket)讀取資 料,並儲存資料來源(對方) 的位址。

d.parseResponseCode()

這邊開始讀取 responseCode 的資料,解析 Server 傳回的狀態碼,比如說狀態碼 200 是 OK 的意思,RTSP status code 的意思如下表 2.3 所示。

表 2.3 RTSP status code table

在第二章最後,我們用以下 8 個步驟來說明 Live555 Client-Server 間傳送接收 RTSP 的『溝通協調』命令順序:

1.Client 發送 RTSP 命令給 Server。

2.Server 接受、解析、判斷、執行 RTSP,並產生適當的回應訊息。

3.Client 接收到 Server 回應訊息,並解析其回應碼(Response code)。

4.Client 依回應碼決定相對應的處理函數。

5.Client 在處理函數中更進一步地去解析重要的串流資訊:

5.1 Transport Header(During RTSP『SETUP』)。

5.2 RTP 表頭資訊( During RTSP『PLAY』)。

5.3 Scale Header 播放範圍表頭( During RTSP『PLAY』)。

6.Client 把 RTP payload 的內容傳給上 decoder 應用程式去執行播放

(During PLAY)。

第三章 封包包裝及傳送

到目前為止我們已經把一個串流伺服器的『連線建立的標準程序』以及『溝通協調』

部分論述完畢,在第三章要更去探討的地方有下面幾點:

1.在client發送RTSP『PLAY』給server接收後,server將會採取什麼動作?

2.在server開始傳送RTP封包之前,這些媒體封包的來源訊框(frame)是如何由一個媒體檔 案的資料流中取得的?

3.在分離媒體檔案資料流中的表頭(header)以及訊框後,我們便把訊框打包進一個封包之 中,而當然一個封包不可能裝進所有的訊框資料,因此衍生出來的切割封裝的演算法 與所處網路環境的對應關係也是值得去瞭解的問題,因為這些問題牽動著串流媒體的 效能表現。 (註.詳細的封裝演算法在第四章才會討論之,第三章主要以瞭解Live555 的程式流程為主)。

而在第二章中我們提到了Live555 server在收到RTSP『PLAY』後便會去執行

handleCmd_PLAY(),所以我們接下來便由該行程式出發,以求瞭解在這個階段串流伺 服器彙整了哪些功能來完成影音的串流傳輸。

3.1 RTSP PLAY信令的執行-handleCmd_PLAY()

如上紅框內所示,handleCmd_PLAY()呼叫了九個函數,以下先對這九個函數做 一個簡單介紹:

1.dateHeader():

傳回系統儲存時間的相關資訊。

2.parseRangeHeader():

RangeHeader 是 client 用來告知 server 它所需的 data 範圍,也就是 Range header 會將 streaming media 的起始及結束的範圍告知 Server,所以 server 端需用這個函數來解析 client 所傳過來的 RTSP『PLAY』中的表頭資訊。

3.parseScaleHeader():

ScaleHeader 是 client 用來告知 server 它所需的影片播放速率,所以 server 端需用這個 函數來解析 client 所傳過來的 RTSP『PLAY』中的表頭資訊。

9.strDup():主要用途在 Buffer 中 string 的複製(scaleHeader = strDup(buf))。

上述函數中我們針對 RTSPServer.rtspURL()函數做特別說明,該函數會先呼叫

ourSourceAddressForMulticast(envir()),最後會再去呼叫下圖紅框內的十個函數,而我們 在此只論述到比較重要的三個函數,說明如下:

1.setupDatagramSocket():建立一個 UDP Socket,如下圖 3.1 所示。

2.readSocket():server 讀取 client 端所傳輸的資料,比如說 RTCP/UDP。

3.writeSocket():server 傳送資料給 client 接收,比如說 RTP/UDP。

1.setupDatagramSocket()會

完成建立 UDP Socket()以及

Bind()的動作。

2.readSocket()會呼叫

recvfrom()經由 client

socket 讀取資料,並儲存資料

來源的位址。

3.writeSocket()會呼叫

sendto()把 server 的資料傳

至 client 端的 socket。

圖 3.1 Create RTP/RTCP socket after RTSP PLAY

而 UDP socket 和 TCP socket 的使用差別就是因為 UDP socket 是非連接導向

(Connectionless),故不需要 connect()函數,其餘的函數使用方法大致上同於我們第二 章的介紹。 (註.UDP socket API 函數流程圖可以參考圖 2.4)

3.1.1 伺服器媒體連線會談(ServerMediaSession)

而建立好 UDP socket 之後,串流伺服器便具有能力把 RTP 封包傳送到網路上,但 是 RTP 封包資料從哪裡來呢?所以我們接下來繼續看 Live555 的下一行程式碼。

#4 ServerMediaSession* sms = ServerMediaSession::createNew(

*env, streamName, streamName,descriptionString);

在前面 2.2.4 章節中(SDP)中我們約略介紹到 Live555 所提供『ServerMediaSession』

類別的用途,它是 Live555 用來表示一個『伺服器連線會談的資料結構』,而 createNew() 會產生一個 ServerMediaSession 的建構子,該建構子用來建立以及初始化一個多媒體『連 線會談』的相關資訊,比如說有:

1.streamName(串流名稱)~此即為 client 端輸入 URL suffix 的連線代號,需特別注意此變 數的處理,因為 Live555 是以連線名稱來決定所要播放的檔案。

2.info (Live 版本的資訊)。

3.description= "LIVE.COM Streaming Media v"(軟體開發公司的 title)。

4.gettimeofday(取得系統的時間資訊)

而這也就是我們下面所看到的 User-Agent 欄位資訊。

3.1.2 伺服器的媒體底層連線會談(ServerMediaSubSession)

ServerMediaSession(伺服器媒體連線會談)類別的功用是幫助伺服器建立一些基本 的訊息;而接下來的程式如#5 所示:

#5 sms->addSubsession(MPEG4VideoFileServerMediaSubsession::createNew

(*env, inputFileName, reuseFirstSource));

上述#5 程式開始便進入媒體資料切割打包的部分,而

『MPEG4VideoFileServerMediaSubsession』這部分是我們所要串流的影音格式是什麼,

即套用該影音格式的對應建構子,舉例來說:

由 ServerMediaSession 建構子所完成的 User-Agent 資訊,包含串流名稱以 及軟體版本資訊

『MPEG4VideoFile』+『ServerMediaSubsession』=『MPEG4VideoFileServerMediaSubsession』,或是

『MP3AudioFile』+『ServerMediaSubsession』=『MP3AudioFileServerMediaSubsession』

,也就是套用特定影音格式的 createNew 部分,這是因為每一種影音格式都有特定的 RTP 包裝方式,並且規定於不同的 RFC 文件中。因此,Live555 目前支援影音格式共有九種,

每一種建構子都會對應到特定影音格式的解析以及封包演算法,以下列舉的是該九種建 構子的程式碼。

1.A MPEG-4 video elementary stream::

sms->addSubsession(MPEG4VideoFileServerMediaSubsession

::createNew(*env, inputFileName, reuseFirstSource));

2. MPEG-1 or 2 audio+video program stream (elementary stream):

MPEG1or2FileServerDemux* demux = MPEG1or2FileServerDemux::createNew(*env, inputFileName, reuseFirstSource);

sms->addSubsession(demux->newVideoServerMediaSubsession(iFramesOnly));

sms->addSubsession(demux->newAudioServerMediaSubsession());

3.mp3:

sms->addSubsession(MP3AudioFileServerMediaSubsession::createNew

(*env,inputFileName,reuseFirstSource,useADUs,interleaving));

4.wav:

sms->addSubsession(WAVAudioFileServerMediaSubsession::createNew

(*env, inputFileName, reuseFirstSource, convertToULaw));

5.amr:

sms->addSubsession(AMRAudioFileServerMediaSubsession::createNew

(*env, inputFileName, reuseFirstSource));

6.vob:

sms->addSubsession(demux->newVideoServerMediaSubsession(iFramesOnly));

sms->addSubsession(demux->newAC3AudioServerMediaSubsession());

7.ts:

sms->addSubsession(MPEG2TransportFileServerMediaSubsession::createNew

(*env, inputFileName, reuseFirstSource));

8.m4v:

sms->addSubsession(MPEG4VideoFileServerMediaSubsession::createNew

(*env, inputFileName, reuseFirstSource));

9.aac

sms->addSubsession(ADTSAudioFileServerMediaSubsession

::createNew(*env, inputFileName, reuseFirstSource));

所以在 Live555 的『testOnDemandRTSPServer』這個程式所實作的串流伺服器具 有在『同一時間』串流『九種媒體格式』的能力,也就是說在最大 connected socket 限 制數目範圍內,串流伺服器可以隨意傳送這九種媒體格式的媒體檔案給用戶端接收。

*在此特別注意inputFileName是一個指向媒體檔案名稱的指標,預設會播放同一目錄 下所設定的檔案(如 test.mpg)。如果想建置一個 Live Capture 即時影像傳送的串流伺服 器,只要把即時抓取所儲存的檔案名稱設置成 test.mpg 即可,但注意即時抓取影像所儲 存的影音格式要和支援的格式相符。

接下來我們便以 MPEG4VideoFileServerMediaSubsession::createNew()來做說明。

如下紅框內所示,執行 createNew 之後便會傳回一個 MPEG4VideoFileServerMediaSubsession 的建構子。

而該 MPEG4VideoFileServerMediaSubsession 的建構子主要會去做 FileServerMediaSubsession 的預設值設定。

而在 FileServerMediaSubsession 的建構子中會去做 OnDemandServerMediaSubsession 的 預設值設定。

OnDemandServerMediaSubsession.cpp 這一個程式主要功能便是由 sdpLines()函數

去呼叫『createNewStreamSource()』以及『createNewRTPSink()』,如下所示:

createNewStreamSource()函數功用主要負責開啟串流檔案,並從該檔案取得訊框

(frame),這部分我們會在接下來的 3.2 章節(開啟串流檔案來源 , MPEG4VideoFileServerMediaSubsession.cpp)中論述。

而 createNewRTPSink()主要負責對這些訊框做打包(pack)的動作,並且在這些封包 之中加入 RTP header 的資訊,這部分我們會在接下來的 3.4.3 章節(影像訊框的切割與 包裝,MultiFramedRTPSink.cpp)中論述。

(MPEG4VideoFileServerMediaSubsession 類別的繼承關係圖與函數呼叫圖)

3.2 訊框的切割、包裝以及傳送

在論述 Live555 訊框(frame)的切割

包裝以及傳送的方式之前,我們在此先對 3.4 章節的六個小節做個預覽說明,以便接下來能夠更有條理地分析 Live555 的

MPEG4VideoFileServerMediaSubsession.cpp 程式的功能模組。

小節 標題(主要函數) 簡要說明

3.2.5 RTP Payload format for MPEG4 (createNewRTPSink())

主要是對於 RTP 協定以及 RFC3016 的說明。

3.2.6 取得各種影音格式的訊框:

(doGetNextFrame())

特定媒體格式訊框的解析。

3.2.1 IP(Internet Protocol)、Fragment and RTCP

IP 通訊協定定義於 RFC 791,位於下圖 3.2(a)OSI model 的第三層,是網際網路所 使用的網路層通訊協定。IP 負責傳送資料到指定位址,但並不確認資料是否正確傳達,

是一種無連結(Connectionless)的通訊協定,而 IP 主要負責以下三點:

1.Packet 路徑選擇(Routing) 2.Packet 分割(Fragmentation) 3.Packet 重組 (Re-assembly)

- by Packet’s Fragment ID。

圖 3.2(a) OSI 7-layer model

通常網路上傳輸的封包大小都有限制(如下表 3.1 所示),比如說在 Ethernet 上 MTU 的限制為 1500 Bytes,而 1500 Bytes 便是 MTU(Maximum Transfer Unit,最大傳輸單 位);MTU 也就是 Data-link layer 中對資料(payload)傳輸的最大限制,而 Network layer 會因 Data-link layer 的 MTU 而對 frame 做切割的動作。

表 3.1 MTU limited table 以下為兩個 IP fragmentation 的例子:

範例一:假設原始 IP 封包大小為 4520Bytes,IP 表頭為 20Bytes,故 IP Payload 為 4500 Bytes;

若必須經由乙太網路傳送,在切割後每個 IPfragment 最大長度為 1500 Bytes,其中 IP 表

頭的長度為 20 Bytes,每一個 IP Payload 最大為 1480 Bytes,因此,會產生如下圖 3.2(b) 的 4 個新 IP fragment:

圖 3.2(b) IP fragmentation

下圖 3.3 為串流伺服器傳送 RTP 以及 RTSP 封包的內容資訊,因此以 MTU 為

1500Bytes 來說,最大的 RTP 封包 payload 便只能是 1460Bytes,如果串流伺服器故意設 定 payload 長度為 1470Bytes 將會造成系統額外的負擔,因為 Network layer 會把一個

1470Bytes 的訊框切割成二個封包,除了造成傳送端的麻煩,亦會造成接收端在封包重

1470Bytes 的訊框切割成二個封包,除了造成傳送端的麻煩,亦會造成接收端在封包重

在文檔中 串流伺服器特性剖析 (頁 52-0)

相關文件