實時傳輸協議(RTP)和實時控制協議(RTCP)
RTP是一種提供端對端傳輸服務的實時傳輸協議,用來支持在單目標廣播和多目標廣播網絡服務中傳輸實時數據,而實時數據的傳輸則由RTCP協議來監視和控制。
RTP定義在RFC
使用RTP協議的應用程序運行在RTP之上,而執行RTP的程序運行在UDP的上層,目的是為了使用UDP的端口號和檢查和。如圖16-12所示,RTP可以看成是傳輸層的子層。由多媒體應用程序生成的聲音和電視數據塊被封裝在RTP信息包中,每個RTP信息包被封裝在UDP消息段中,然后再封裝在IP數據包中。
1889中。信息包的結構包含廣泛用于多媒體的若干個域,包括聲音點播(audio-on-demand)、影視點播(video ondemand)、因特網電話(Internettelephony)和電視會議(videoconferencing)。RTP的規格沒有對聲音和電視的壓縮格式制定標準,它可以被用來傳輸普通格式的文件。例如,WAV或者GSM(Global System forMobilecommunications)格式的聲音、MPEG-1和MPEG-2的電視,也可以用來傳輸專有格式存儲的聲音和電視文件。 TCP/IP模型 | |
應用層(application) | |
傳輸層 | RTP |
UDP | |
IP | |
數據鏈路層(data link) | |
物理層(physical) |
圖16-12 RTP是傳輸層上的協議
從應用開發人員的角度來看,可把RTP執行程序看成是應用程序的一部分,因為開發人員必需把RTP集成到應用程序中。在發送端,開發人員必需把執行RTP協議的程序寫入到創建RTP信息包的應用程序中,然后應用程序把RTP信息包發送到UDP的套接接口(socketinterface),如圖16-13所示;同樣,在接收端,RTP信息包通過UDP套接接口輸入到應用程序,因此開發人員必需把執行RTP協議的程序寫入到從RTP信息包中抽出媒體數據的應用程序。
TCP/IP模型 | |
應用層(application) | |
RTP | |
| 套接接口 |
UDP | |
IP | |
數據鏈路層(data link) | |
物理層(physical) |
圖16-13 RTP和UDP之間的接口
現以用RTP傳輸聲音為例來說明它的工作過程。假設音源的聲音是64kb/s的PCM編碼聲音,并假設應用程序取20毫秒的編碼數據為一個數據塊(chunk),即在一個數據塊中有160個字節的聲音數據。應用程序需要為這塊聲音數據添加RTP標題生成RTP信息包,這個標題包括聲音數據的類型、順序號和時間戳。然后RTP信息包被送到UDP套接接口,在那里再被封裝在UDP信息包中。在接收端,應用程序從套接接口處接收RTP信息包,并從RTP信息包中抽出聲音數據塊,然后使用RTP信息包的標題域中的信息正確地譯碼和播放聲音。
如果應用程序不使用專有的方案來提供有效載荷類型(payloadtype)、順序號或者時間戳,而是使用標準的RTP協議,應用程序就更容易與其他的網絡應用程序配合運行,這是大家都希望的事情。例如,如果有兩個不同的公司都在開發因特網電話軟件,他們都把RTP合并到他們的產品中,這樣就有希望:使用不同公司電話軟件的用戶之間能夠進行通信。
這里需要強調的是,RTP本身不提供任何機制來確保把數據及時遞送到接收端或者確保其他的服務質量,它也不擔保在遞送過程中不丟失信息包或者防止信息包的次序不被打亂。的確,RTP的封裝只是在系統端才能看到,中間的路由器并不區分那個IP數據報是運載RTP信息包的。
RTP允許給每個媒體源分配一個單獨的RTP信息包流,例如,攝像機或者麥克風。例如,有兩個團體參與的電視會議,這就可能打開4個信息包流:兩臺攝像機傳送電視流和兩個麥克風傳送聲音流。然而,許多流行的編碼技術,包括MPEG-1和MPEG-2在編碼過程中都把聲音和電視圖像捆綁在一起以形成單一的數據流,一個方向就生成一個RTP信息包流。
RTP信息包沒有被限制只可應用于單目標廣播,它們也可以在一對多(one-to-many)的多目標廣播樹或者在多對多(many-to-many)的多目標廣播樹上傳送。例如,多對多的多目標廣播,在這種應用場合下,所有發送端通常都把他們的RTP信息包流發送到具有相同多目標廣播地址的多目標廣播樹上。
16.6.2 RTP信息包標題域
RTP標題由4個信息包標題域和其他域組成:有效載荷類型(payload type)域,順序號(sequencenumber)域,時間戳(timestamp)域和同步源標識符(Synchronization SourceIdentifier)域等。RTP信息包的標題域的結構如下圖所示:
Payload Type | Sequence Number | Timestamp | Synchronization Source Identifier | Miscellaneous Fields |
1. 有效載荷類型
RTP信息包中的有效載荷域(Payload TypeField)的長度為7位,因此RTP可支持128種不同的有效載荷類型。對于聲音流,這個域用來指示聲音使用的編碼類型,例如PCM、自適應增量調制或線性預測編碼等等。如果發送端在會話或者廣播的中途決定改變編碼方法,發送端可通過這個域來通知接收端。表16-01列出了目前RTP所能支持的聲音有效載荷類型。
表16-01目前RTP所能支持的聲音有效載荷類型
有效載荷號 | 聲音類型 | 采樣率(kHz) | 數據率(kb/s) |
0 | PCM mu-law | 8 | 64 |
1 | 1016 | 8 | 4.8 |
2 | G.721 | 8 | 32 |
3 | GSM | 8 | 32 |
6 | DVI | 16 | 64 |
7 | LPC | 8 | 2.4 |
9 | G.722 | 8 | 48~64 |
14 | MPEG Audio | 90 | - |
15 | G.728 | 8 | 16 |
對電視流,有效載荷類型可以用來指示電視編碼的類型,例如motion JPEG,MPEG-1,MPEG-2或者H.231等等。發送端也可以在會話或者期間隨時改變電視的編碼方法。表16-02列出了目前RTP所能支持的某些電視有效載荷類型。
表16-02目前RTP所能支持的聲音有效載荷類型
有效載荷號 | 電視格式 |
26 | Motion JPEG |
28 | - |
31 | H.261 |
32 | MPEG-1 video |
33 | MPEG-2 video |
2. 順序號
順序號(Sequence NumberField)域的長度為16位。每發送一個RTP信息包順序號就加1,接收端可以用它來檢查信息包是否有丟失以及按順序號處理信息包。例如,接收端的應用程序接收到一個RTP信息包流,這個RTP信息包在順序號86和89之間有一個間隔,接收端就知道信息包87和88已經丟失,并且采取措施來處理丟失的數據。
3. 時間戳
時間戳(Timestamp)域的長度為32字節。它反映RTP數據信息包中第一個字節的采樣時刻(時間)。接收端可以利用這個時間戳來去除由網絡引起的信息包的抖動,并且在接收端為播放提供同步功能。
4. 同步源標識符
同步源標識符(SynchronizationSourceIdentifier,SSRC)域的長度為32位。它用來標識RTP信息包流的起源,在RTP會話或者期間的每個信息包流都有一個清楚的SSRC。SSRC不是發送端的IP地址,而是在新的信息包流開始時源端隨機分配的一個號碼。
16.6.3 實時傳輸控制協議
實時傳輸控制協議(Real-timeControl Protocol,RTCP)也定義在1996年提出的RFC1889中。多媒體網絡應用把RTCP和RTP一起使用,尤其是在多目標廣播中更具吸引力。當從一個或者多個發送端向多個接收端廣播聲音或者電視時,也就是在RTP會話期間,每個參與者周期性地向所有其他參與者發送RTCP控制信息包,如圖16-14所示。RTCP用來監視服務質量和傳送有關與會者的信息。對于RTP會話或者廣播,通常使用單個多目標廣播地址,屬于這個會話的所有RTP和RTCP信息包都使用這個多目標廣播地址,通過使用不同的端口號可把RTP信息包和RTCP信息包區分開來。
RTCP的主要功能是為應用程序提供會話質量或者廣播性能質量的信息。每個RTCP信息包不封裝聲音數據或者電視數據,而是封裝發送端和/或者接收端的統計報表。這些信息包括發送的信息包數目、丟失的信息包數目和信息包的抖動等情況,這些反饋信息對發送端、接收端或者網絡管理員都是很有用的。RTCP規格沒有指定應用程序應該使用這個反饋信息做什么,這完全取決于應用程序開發人員。例如,發送端可以根據反饋信息來修改傳輸速率,接收端可以根據反饋信息判斷問題是本地的、區域性的還是全球性的,網絡管理員也可以使用RTCP信息包中的信息來評估網絡用于多目標廣播的性能。
16.6.4 實時流放協議
實時流放協議(Real-Time StreamingProtocol,RTSP)是一個剛開始開發的協議,它的設想描述在RFC
播放的數據流被分成許多信息包,信息包的大小很適用于客戶機和服務器之間的帶寬。當客戶機已經接收到足夠多的信息包之后,用戶軟件就可開始播放一個信息包,同時對另一個信息包解壓縮和接收第三個信息包。這樣用戶就不需要把整個媒體文件從服務器上下載之后就可立即播放。廣播源可以是現場的數據流也可以是存儲的數據流。
RTSP協議想要提供控制多種應用數據傳送的功能,提供一種選擇傳送通道的方法,例如UDP, TCP,IP多目標廣播通道,以及提供一種基于RTP協議的遞送方法。正在設計的RTSP將工作在RTP的上層,用來控制和傳送實時的內容。
RTSP能夠與資源保留協議一起使用,用來設置和管理保留帶寬的流式會話或者廣播。
2326文件中。RTSP是應用級的實時流放協議,它主要目標是為單目標廣播和多目標廣播上的流式多媒體應用提供牢靠的播放性能,以及支持不同廠家提供的客戶機和服務機之間的協同工作能力。
在windows使用vs2008編譯live555
在windows使用vs2008編譯live5551.live555 源代碼簡介
liveMedia項目的源代碼包括四個基本的庫,各種測試代碼以及IVE555 Media Server。
四個基本的庫分別是UsageEnvironment&TaskScheduler,groupsock,liveMedia,BasicUsageEnvironment。
UsageEnvironment和TaskScheduler類用于事件的調度,實現異步讀取事件的句柄的設置以及錯誤信息的輸出。另外,還有一個HashTable類定義了一個通用的hash表,其它代碼要用到這個表。這些都是抽象類,在應用程序中基于這些類實現自己的子類。
groupsock類是對網絡接口的封裝,用于收發數據包。正如名字本身,Groupsock主要是面向多播數據的收發的,它也同時支持單播數據的收發。Groupsock定義了兩個構造函數
?
?
?
?
?
前者是用于SIM(source-independent multicast)組,后者用于SSM(source-specificmulticast)組。groupsock庫中的Helper例程提供了讀寫socket等函數,并且屏蔽了不同的操作系統之間的區別,這是在GroupsockHelper.cpp文件中實現的。
liveMedia庫中有一系列類,基類是Medium,這些類針對不同的流媒體類型和編碼。
各種測試代碼在testProgram目錄下,比如openRTSP等,這些代碼有助于理解liveMedia的應用。
LIVE555 Media Server是一個純粹的RTSP服務器。支持多種格式的媒體文件:
?
?
?
?
?
?
?
2.在windows下編譯live555
(1).下載 live555,http://www.live555.com/
?
?
?
?
?
?
call "C:\Program Files\Microsoft Visual Studio9\VC\vcvarsall.bat"
cd liveMedia
nmake /B -f liveMedia.mak
cd ../groupsock
nmake /B -f groupsock.mak
cd ../UsageEnvironment
nmake /B -f UsageEnvironment.mak
cd ../BasicUsageEnvironment
nmake /B -f BasicUsageEnvironment.mak
cd ../testProgs
nmake /B -f testProgs.mak
cd ../mediaServer
nmake /B -f mediaServer.mak
有關這一點來說,建議把vs2008的編譯環境加入到環境變量中,那么以后需用命令行編譯程序都可行了,可以參考 http://blog.chinaunix.net/u3/94873/showart_1907792.html的前部分設置VS2008的環境設置。
?
以上的編譯并不是 DEBUG模式,要調試時,應先在win32config加入一行"NODEBUG=1"
進行編譯后,可以在要調試的程序路徑下輸入如:C:\works\VCCode\video\live555-latest\live\testProgs>devenvopenRTSP.exe,這樣就會把相關的調試環境搭建起來進行調試了。
文 字體大小:大 中 小
?
它們主要的區別是HTTP協議是沒有狀態的, http協議在發送一個命令后,連接會斷開,而且命令之間沒有依賴性。不同的是RTSP的命令需要知道現在正處于一個什么狀態,也就是說rtsp的命令總是按照順序來發送,某個命令總在另外一個命令之前要發送。Rtsp不管處于什么狀態都不會去斷掉連接。
HTTP 協議默 認使用80端口,而RTSP默認使用554端口。如果一些服務器因為某些安全的原因而封掉了這個端口,那代理和防火墻可能不讓RTSP消息通過,需要管理員去放開554端口,而使得rtsp協議能通過。
基本類
在Mplayer中如果使用live選項進行編譯,則需要安裝live555庫。live555實現RTP/RTSP功能。
使用環境(usageEnvironment):UsageEnvironment和TaskScheduler類用在調度不同事件。還有HashTable類定義,這些都是抽象基類。在使用過程中可以利用環境的特定功能。
groupsock:封裝網絡接口和socket。特別是還封裝了multicast應用,這個multicast并不是Mbone意義的multicast,而是將多個寫而不讀socket組合處理,用來模擬multicast。
liveMedia:定義一個類棧,根類是Medium類-不同的流類型和編解碼器。
BasicUsageEnvironment:定義一個usageEnvironment的實現,這個里面除了有一個TaskScheduler以外,都是一些說明性的東西。TaskSheduler里面是一些調度相關的函數,其中doEventLoop是主控函數,定義為純虛函數。
testProgs:目錄下是一個簡單的實現,使用了BasicUsageEnvironment來展示如何使用這些庫。
BasicTaskScheduler0:主要成員變量有fdelayQueue, fReadHandlers,fLastHandledSocketNum;這里主要的處理函數是scheduleDelayedTask,通過定時器觸發一個時間,比如RTCP包的發送等。
BasicTaskScheduler:中又添加了fMaxNumSockets和fReadSet。其中freadHandlers類中定義一個鏈表,將所有的句柄,對應的處理函數 和處理函數參數作鏈接成一個鏈表,通過成員函數assignHandler管理。這里面主要的函數是turnOnBackgroundReadHand
MediaSession類中定義了一個mediaSubSession鏈表;MediaSubSession中又SessionId,服務端口號,rtp/rtcp ChannelId和MediaSink指針,等等一些參數信息。
H.264
1. 基類
Medium:定義媒體名字和環境信息,處理任務名,靜態函數close和lookupByName和一些虛函數來指明該medium類型,是媒體幀的基類。
MediaSource類:實現基類中medium類型的虛函數,
FramedSoruce:定義了getNextFrame和doGetNextFrame純虛函數是使用到的一些變量。
2. 相關類
H264VideoStreamFramer;H264VideoFileSink:H264VideoRTPSource:H264VideoRTPSinik
H.264利用NAL封裝數據,通過RTP傳輸數據包。相關的處理在RTPSource/Sink中。
Mplayer
從RTSP或者SIP中渠道SDP描述,然后調用Live555中的mediaSession類創建Session。通過成員函數initializeWithSDP分析SDP描述。
OpenRTSP
1. Client
1. 創建TaskScheduler和UsageEnvironment實例;
2. 調用createClient創建media實例;
在openRTSP.c中,main完成配置以后,開始如下循環:
startPlayingStreams();
env->taskScheduler().doEventLoop(); // does notreturn
在BasicTaskScheduler0類中,定義為while(1) SingleStep();
SingleStep的處理是通過select監聽一組句柄,這組句柄通過iter組成的鏈表串接起來,對每個句柄有處理函數,如果有句柄上有數據,那么調用對應的處理函數。
2. liev555mediaserver
創建過程:
1. 創建TaskScheduler:這里僅僅初始化一個fdset并且socket數目初始化為0。
2. 以TaskScheduler為參數創建UsageEnvironment對象。
3. 以前述environment和服務端口號(554/8554)以及用戶認證對象為參數創建 RTSPServer對象,這里是用子類DynamicRTSPServer的創建函數創建。在createNew成員函數中建立socket,分配發送緩沖區,和創建RTSPServer對象。這里通過turnOnBackgroundReadHand
4. 執行env->taskScheduler().doEventLoop();
從RFC2326中可以看出通常的交互流程是發送describe,然后發送setup,再play。所以以請求MPG多媒體URI為例分析如下:
C->M: DESCRIBE rtsp://foo/twister RTSP/1.0
CSeq: 1
M->C: RTSP/1.0 200 OK
CSeq: 1
Content-Type: application/sdp
Content-Length: 164
v=0
o=- 2890844256 2890842807 IN IP4 172.16.2.93
s=RTSP Session
i=An Example of RTSP Session Usage
a=control:rtsp://foo/twister
t=0 0
m=audio 0 RTP/AVP 0
a=control:rtsp://foo/twister/audio
m=video 0 RTP/AVP 26
a=control:rtsp://foo/twister/video
C->M: SETUP rtsp://foo/twister/audio RTSP/1.0
CSeq: 2
Transport: RTP/AVP;unicast;client_port=8000-8001
M->C: RTSP/1.0 200 OK
CSeq: 2
Transport: RTP/AVP;unicast;client_port=8000-8001;
server_port=9000-9001
Session: 12345678
C->M: SETUP rtsp://foo/twister/video RTSP/1.0
CSeq: 3
Transport: RTP/AVP;unicast;client_port=8002-8003
Session: 12345678
M->C: RTSP/1.0 200 OK
CSeq: 3
Transport: RTP/AVP;unicast;client_port=8002-8003;
server_port=9004-9005
Session: 12345678
C->M: PLAY rtsp://foo/twister RTSP/1.0
CSeq: 4
Range: npt=0-
Session: 12345678
M->C: RTSP/1.0 200 OK
CSeq: 4
Session: 12345678
RTP-Info: url=rtsp://foo/twister/video;
seq=9810092;rtptime=3450012
C->M: PAUSE rtsp://foo/twister/video RTSP/1.0
CSeq: 5
Session: 12345678
M->C: RTSP/1.0 460 Only aggregate operationallowed
CSeq: 5
C->M: PAUSE rtsp://foo/twister RTSP/1.0
CSeq: 6
Session: 12345678
M->C: RTSP/1.0 200 OK
CSeq: 6
Session: 12345678
C->M: SETUP rtsp://foo/twister RTSP/1.0
CSeq: 7
Transport: RTP/AVP;unicast;client_port=10000
M->C: RTSP/1.0 459 Aggregate operation notallowed
CSeq: 7
函數 handleCmd_DESCRIBE處理describe請求,生成含SDP信息響應消息,lookupServerMediaSession
音頻:MPEG1or2AudioRTPSink::AudioRTPSink::MultiFramedRTPSink::RTPSink::MediaSink::Media
視頻:MPEG1or2VideoRTPSink::VideoRTPSink::MultiFramedRTPSink::RTPSink::MediaSink::Media
而SDP信息的獲取在函數 setSDPLinesFromRTPSink中處理。(AudioRTPSink指定媒體類型,時間標簽頻率和載荷格式名“MPA”,視頻名字是“MPV")
這里類結構 MPEG1or2DemuxedServerMed
函數 handleCmd_SETUP處理setup請求,
MPEG1or2Demux類是mpeg相關的一個主要類,創建該類時會分析媒體文件。該類定義中有個數組,OutputDescriptorfOutput[256];MPEG1or2Demux的構造函數中初始化。
在windows使用vs2008編譯live555
1.live555 源代碼簡介
liveMedia項目的源代碼包括四個基本的庫,各種測試代碼以及IVE555 Media Server。
四 個基本的庫分別是UsageEnvironment&TaskScheduler,groupsock,liveMedia,BasicUsageEnvironment。
UsageEnvironment和TaskScheduler類用于事件的調度,實現異步讀取事件的句柄的設置以及錯誤信息的輸出。另外,還有一個HashTable類定義了一個通用的hash表,其它代碼要用到這個表。這些都是抽象類,在應用程序中基于這些類實現自己的子類。
groupsock類是對網絡接口的封裝,用于收發數據包。正如名字本身,Groupsock主要是面向多播數據的收發的,它也同時支持單播數據的收發。Groupsock定義了兩個構造函數
Groupsock(UsageEnvironment& env, struct in_addrconst& groupAddr,
Port port, u_int8_t ttl);
Groupsock(UsageEnvironment& env, struct in_addrconst& groupAddr,
struct in_addr const& sourceFilterAddr,
Port port);
前 者是用于SIM(source-independent multicast)組,后者用于SSM(source-specificmulticast)組。groupsock庫中的Helper例程提供了讀寫socket等函數,并且屏蔽了不同的操作系統之間的區別,這是在GroupsockHelper.cpp文件中實現的。
liveMedia庫中有一系列類,基類是Medium,這些類針對不同的流媒體 類型和編碼。
各種測試代碼在testProgram目錄下,比如openRTSP等,這些代碼有助于理解liveMedia的應用。
LIVE555 Media Server是一個純粹的RTSP服務器。支持多種格式的媒體文件:
* TS流文件,擴展名ts。
* PS流文件,擴展名mpg。
* MPEG-4視頻基本流文件,擴展名m4e。
* MP3文件,擴展名mp3。
* WAV文件(PCM),擴展名wav。
* AMR音頻文件,擴展名.amr。
* AAC文件,ADTS格式,擴展名aac。
2.在windows下編譯live555
(1).下載 live555,http://www.live555.com/
(2). 編輯 win32config,TOOLS32=C:\Program Files\Microsoft VisualStudio 9.0\VC
即保證這個路徑是你的Vs2008 路徑。
(3). 編輯"LINK_OPTS_0 = $(linkdebug) msvcirt.lib" in win32config to"LINK_OPTS_0 = $(linkdebug) msvcrt.lib",由于編譯器所要LINK的運行庫不一樣了
(4). 修改groupsock/makefile.head,替換"INCLUDES = -Iinclude-I../UsageEnvironment/include" 為"INCLUDES = -Iinclude-I../UsageEnvironment/include -DNO_STRSTREAM".
(5). 運行genWindowsMakefiles.cmd 生成VS能夠編譯的*.mak文件
(6). 將以下內容保存為live/compile.bat
call "C:\Program Files\Microsoft Visual Studio9\VC\vcvarsall.bat"
cd liveMedia
nmake /B -f liveMedia.mak
cd ../groupsock
nmake /B -f groupsock.mak
cd ../UsageEnvironment
nmake /B -f UsageEnvironment.mak
cd ../BasicUsageEnvironment
nmake /B -f BasicUsageEnvironment.mak
cd ../testProgs
nmake /B -f testProgs.mak
cd ../mediaServer
nmake /B -f mediaServer.mak
有 關這一點來說,建議把vs2008的編譯環境加入到環境變量中,那么以后需用命令行編譯程序都可行了,可以參考 http://blog.chinaunix.net/u3/94873/showart_1907792.html的前部分設置VS2008的環境設置。
(7). 在命令行下運行compile.bat,就會看到很多編譯過程出現在CMD中了。
以上的編譯并不是 DEBUG模式,要調試時,應先在win32config加入一行"NODEBUG=1"
進行編譯后,可以在要調試的程序路徑下輸入如:C:\works\VCCode\video\live555-latest\live\testProgs>devenvopenRTSP.exe,這樣就會把相關的調試環境搭建起來進行調試了。
liveMedia項目的源代碼包括四個基本的庫,各種測試代碼以及IVE555 Media Server。
四個基本的庫分別是UsageEnvironment&TaskScheduler,groupsock,liveMedia,BasicUsageEnvironment。
UsageEnvironment和TaskScheduler類用于事件的調度,實現異步讀取事件的句柄的設置以及錯誤信息的輸出。另外,還有一個HashTable類定義了一個通用的hash表,其它代碼要用到這個表。這些都是抽象類,在應用程序中基于這些類實現自己的子類。
groupsock類是對網絡接口的封裝,用于收發數據包。正如名字本身,Groupsock主要是面向多播數據的收發的,它也同時支持單播數據的收發。Groupsock定義了兩個構造函數
Groupsock(UsageEnvironment& env, struct in_addrconst& groupAddr,
Port port, u_int8_t ttl);
Groupsock(UsageEnvironment& env, struct in_addrconst& groupAddr,
struct in_addr const& sourceFilterAddr,
Port port);
前者是用于SIM(source-independent multicast)組,后者用于SSM(source-specificmulticast)組。groupsock庫中的Helper例程提供了讀寫socket等函數,并且屏蔽了不同的操作系統之間的區別,這是在GroupsockHelper.cpp文件中實現的。
liveMedia庫中有一系列類,基類是Medium,這些類針對不同的流媒體 類型和編碼。
各種測試代碼在testProgram目錄下,比如openRTSP等,這些代碼有助于理解liveMedia的應用。
LIVE555 Media Server是一個純粹的RTSP服務器。支持多種格式的媒體文件:
* TS流文件,擴展名ts。
* PS流文件,擴展名mpg。
* MPEG-4視頻基本流文件,擴展名m4e。
* MP3文件,擴展名mp3。
* WAV文件(PCM),擴展名wav。
* AMR音頻文件,擴展名.amr。
* AAC文件,ADTS格式,擴展名aac。
用live555開發應用程序
基于liveMedia的程序,需要通過繼承UsageEnvironment抽象類和TaskScheduler抽象類,定義相應的類來處理事件調度,數據讀寫以及錯誤處理。live項目的源代碼里有這些類的一個實現,這就是“BasicUsageEnvironment”庫。BasicUsageEnvironment主要是針對簡單的控制臺應用程序,利用select實現事件獲取和處理。這個庫利用Unix或者Windows的控制臺作為輸入輸出,處于應用程序原形或者調試的目的,可以用這個庫用戶可以開發傳統的運行與控制臺的應用。
通過使用自定義的“UsageEnvironment”和“TaskScheduler”抽象類的子類,這些應用程序就可以在特定的環境中運行,不需要做過多的修改。需要指出的是在圖形環境(GUI toolkit)下,抽象類 TaskScheduler 的子類在實現doEventLoop()的時候應該與圖形環境自己的事件處理框架集成。
先來熟悉在liveMedia庫中Source,Sink以及Filter等概念。Sink就是消費數據的對象,比如把接收到的數據存儲到文件,這個文件就是一個Sink。Source就是生產數據的對象,比如通過RTP讀取數據。數據流經過多個'source'和'sink's,下面是一個示例:
'source1' -> 'source2' (a filter) ->'source3' (a filter) -> 'sink'
從其它 Source接收數據的source也叫做"filters"。Module是一個sink或者一個filter。
數據接收的終點是 Sink類,MediaSink是所有Sink類的基類。MediaSink的定義如下:
class MediaSink: public Medium {
public:
static Boolean lookupByName(UsageEnvironment& env,char const* sinkName,
MediaSink*& resultSink);
typedef void (afterPlayingFunc)(void* clientData);
Boolean startPlaying(MediaSource& source,
afterPlayingFunc* afterFunc,
void* afterClientData);
virtual void stopPlaying();
// Test for specific types of sink:
virtual Boolean isRTPSink() const;
FramedSource* source() const {return fSource;}
protected:
MediaSink(UsageEnvironment& env); // abstract baseclass
virtual ~MediaSink();
virtual BooleansourceIsCompatibleWithUs
// called by startPlaying()
virtual Boolean continuePlaying() = 0;
// called by startPlaying()
static void onSourceClosure(void* clientData);
// should be called (on ourselves) by continuePlaying() whenit
// discovers that the source we're playing from has closed.
FramedSource* fSource;
private:
// redefined virtual functions:
virtual Boolean isSink() const;
private:
// The following fields are used when we're being played:
afterPlayingFunc* fAfterFunc;
void* fAfterClientData;
};
Sink 類實現對數據的處理是通過實現純虛函數continuePlaying(),通常情況下continuePlaying調用fSource->getNextFrame來為Source設置數據緩沖區,處理數據的回調函數等,fSource是MediaSink的類型為FramedSource*的類成員;
基于liveMedia的應用程序的控制流程如下:
應用程序是事件驅動的,使用如 下方式的循環
while (1) {
通過查找讀網絡句柄的列表和延遲隊列(delay queue)來發現需要完成的任務
完成這個任務
}
對于每個sink,在進入這個循環之 前,應用程序通常調用下面的方法來啟動需要做的生成任務:
someSinkObject->startPlaying();
任何時候,一個Module需要獲取數據都通過調用剛好在它之前的那個Module的FramedSource::getNextFrame()方法。這是通過純虛函數FramedSource:oGetNextFrame() 實現的,每一個Source module都有相應的實現。
Each 'source' module's implementation of "doGetNextFrame()" worksby arranging for an 'after getting' function to be called (from anevent handler) when new data becomes available for thecaller.
注意,任何應用程序都要處理從'sources'到'sinks'的數據流,但是并非每個這樣的數據流都與從網絡接口收發數據相對應。
比如,一個服務器應用程序發送RTP數據包的時候用到一個或多 個"RTPSink" modules。這些"RTPSink"modules以別的方式接收數據,通常是文件 "*Source" modules (e.g., to read data from afile), and, as a side effect, transmit RTP packets.
一個簡單的RTSP客戶端程序
在另一個文章里,給出了這個簡單的客戶端的程序的代碼,可以通過修改Makefile來裁剪liveMedia,使得這個客戶端最小化。此客戶端已經正常運行。
首先是OPTION
然 后是DESCRIBE
建立Media Session,調用的函數是MediaSession::createNew,在文件liveMedia/MediaSession.cpp中實現。
為這個Media Session建立RTPSource,這是通過調用MediaSubsession::initiate來實現的的,這個方法在liveMedia/MediaSession.cpp中實現。
在然 后是SETUP
最后是PLAY
rtp數據的句 柄:MultiFramedRTPSource::networkReadHandler在liveMedia/MultiFramedRTPSource.cpp中
rtcp數據處理的句 柄:RTCPInstance::incomingReportHandler在liveMedia/RTCP.cpp中
rtp數據處 理的句柄的設置:MultiFramedRTPSource: oGetNextFrame在liveMedia/MultiFramedRTPSource.cpp中,被FileSink::continuePlaying調用在FileSink.cpp中.
rtcp數據處理的句柄設置 fRTCPInstance = RTCPInstance::createNew在/liveMedia/MediaSession.cpp中調用,
createNew 調用了構造函數RTCPInstance::RTCPInstance,這個構造函數有如下調用
TaskScheduler::BackgroundHandlerProc* handler =(TaskScheduler::BackgroundHandlerProc*)&incomingReportHandler;
*********************************************************************************************************************
通過分析live庫提供的例子程序OpenRTSP,可以清晰地了解客戶端接收來自網絡上媒體數據的過程。注意,RTP協議和RTCP協議接收的數據分別是視音頻數據和發送/接收狀況的相關信息,其中,RTP協議只負責接收數據,而RTCP協議除了接收服務器的消息之外,還要向服務器反饋。
A.?
main(int argc,char *argv[])
{
1.?
2.?
3.?
4.?
5.?
6.?
7.?
8.?
9.?
10.?
11.?
12.?
13.?
}
淺談vlc模塊管理方式-插件
vlc中所有的模塊均以動態庫(插件)方式來管理,就連main模塊也不例外。可以在windows下查看vlc安裝目錄下plugin目錄,里面包含了所有的動態庫。當vlc啟動的時候,主模塊采用動態加入的方式.
具體實現如下:
?
?
?
?
?
?
?
?
?
TS流、ES流、PES流介紹分析
IP數據報有首部和數據兩部分組成的,首部的前一部分是固定長度20字節,是所有IP數據報必須具有的。首部包括:總長度、標識、MF、DF、片偏移。
數字信號實際傳送的是數據流,一般數據流包括以下三種:
ES流:也叫基本碼流,包含視頻、音頻或數據的連續碼流。
PES流:也叫打包的基本碼流,是將基本的碼流ES流根據需要分成長度不等的數據包,并加上包頭就形成了打包的基本碼流PES流。
TS流:也叫傳輸流,是由固定長度為188字節的包組成,含有獨立時基的一個或多個節目,適用于誤碼較多的環境。liveMedia項目(http://www.live555.com/)的源代碼包括四個基本的庫,各種測試代碼以及MediaServer。四個基本的庫分別是: UsageEnvironment&TaskScheduler,groupsock, liveMedia和BasicUsageEnvironment。
UsageEnvironment和TaskScheduler類用于事件的調度,實現異步讀取事件的句柄的設置以及錯誤信息的輸出。另外,還有一個HashTable類定義了一個通用的hash表,其它代碼要用到這個表。這些都是抽象類,在應用程序中基于這些類來實現自己的子類。
groupsock類是對網絡接口的封裝,用于收發數據包。正如名字本身,groupsock主要是面向多播數據的收發的,它也同時支持單播數據的收發。
liveMedia庫中有一系列類,基類是Medium,這些類針對不同的流媒體類型和編碼。
各種測試代碼在testProgram目錄下,比如openRTSP等,這些代碼有助于理解liveMedia的應用。
Media Server是一個純粹的RTSP服務器。支持多種格式的媒體文件:
* TS流文件,擴展名ts。
* PS流文件,擴展名mpg。
* MPEG-4視頻基本流文件,擴展名m4e。
* MP3文件,擴展名mp3。
* WAV文件(PCM),擴展名wav。
* AMR音頻文件,擴展名.amr。
* AAC文件,ADTS格式,擴展名aac。
用live555開發應用程序
基于liveMedia的程序,需要通過繼承UsageEnvironment抽象類和TaskScheduler抽象類,定義相應的類來處理事件調度,數據讀寫以及錯誤處理。live項目的源代碼里有這些類的一個基本實現,這就是“BasicUsageEnvironment”庫。BasicUsageEnvironment主要是針對簡單的控制臺應用程序,利用select實現事件獲取和處理。這個庫利用Unix或者Windows的控制臺作為輸入輸出,處于應用程序原形或者調試的目的,可以用這個庫用戶可以開發傳統的運行與控制臺的應用。
通過使用自定義的“UsageEnvironment”和“TaskScheduler”抽象類的子類,這些應用程序就可以在特定的環境中運行,不需要做過多的修改。需要指出的是在圖形環境(GUI toolkit)下,抽象類 TaskScheduler 的子類在實現doEventLoop()的時候應該與圖形環境自己的事件處理框架集成。
基本概念
先來熟悉在liveMedia庫中Source,Sink以及Filter等概念。Sink就是消費數據的對象,比如把接收到的數據存儲到文件,這個文件就是一個Sink。Source就是生產數據的對象,比如通過RTP讀取數據。數據流經過多個'source'和'sink's,下面是一個示例:
'source1' -> 'source2' (a filter) ->'source3' (a filter) -> 'sink'
從其它Source接收數據的source也叫做"filters"。Module是一個sink或者一個filter。數據接收的終點是Sink類,MediaSink是所有Sink類的基類。Sink類實現對數據的處理是通過實現純虛函數continuePlaying(),通常情況下continuePlaying調用fSource->getNextFrame來為Source設置數據緩沖區,處理數據的回調函數等,fSource是MediaSink的類型為FramedSource*的類成員。
基本控制流程
基于liveMedia的應用程序的控制流程如下:
應用程序是事件驅動的,使用如下方式的循環
while (1) {
通過查找讀網絡句柄的列表和延遲隊列(delay queue)來發現需要完成的任務
完成這個任務
}
對于每個sink,在進入這個循環之前,應用程序通常調用下面的方法來啟動需要做的生成任務:?
Each 'source' module's implementation of "doGetNextFrame()" worksby arranging for an 'after getting' function to be called (from anevent handler) when new data becomes available for thecaller.
Note that the flow of data from 'sources' to 'sinks' happens withineach application, and doesn't necessarily correspond to the sendingor receiving of network packets. For example, a server application(such as "testMP3Streamer") that sends RTP packets will do so usingone or more "RTPSink" modules. These "RTPSink" modules receive datafrom other, "*Source" modules (e.g., to read data from a file),and, as a side effect, transmit RTP packets.
live555代碼解讀之一:RTSP連接的建立過程
RTSPServer類用于構建一個RTSP服務器,該類同時在其內部定義了一個RTSPClientSession類,用于處理單獨的客戶會話。
首先創建RTSP服務器(具體實現類是DynamicRTSPServer),在創建過程中,先建立Socket(ourSocket)在TCP的554端口進行監聽,然后把連接處理函數句柄(RTSPServer::incomingConnectionHandle
任務調度器把socket句柄放入后面select調用中用到的socket句柄集(fReadSet)中,同時將socket句柄和incomingConnectionHandle
當RTSP客戶端輸入(rtsp://192.168.1.109/1.mpg)連接服務器時,select返回對應的scoket,進而根據前面保存的對應關系,可找到對應處理函數句柄,這里就是前面提到的incomingConnectionHandle
live555代碼解讀之二:DESCRIBE請求消息處理過程
RTSP服務器收到客戶端的DESCRIBE請求后,根據請求URL(rtsp://192.168.1.109/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
SDP消息組裝過程:
ServerMediaSession負責產生會話公共描述信息,子會話描述由MPEG1or2DemuxedServerMed
以上涉及到的類以及繼承關系:
Medium <- ServerMediaSession
Medium <- ServerMediaSubsession <-OnDemandServerMediaSubse
Medium <- MediaSource <- FramedSouse<- FramedFileSource <-ByteStreamFileSource
Medium <- MediaSource <- FramedSouse<- MPEG1or2DemuxedElementar
Medium <- MPEG1or2FileServerDemux
Medium <- MPEG1or2Demux
Medium <- MediaSource <- FramedSouse<- MPEG1or2DemuxedElementar
Medium <- MediaSource <- FramedSouse<- FramedFilter <-MPEGVideoStreamFramer <-MPEG1or2VideoStreamFrame
Medium <- MediaSink <- RTPSink<- MultiFramedRTPSink <- VideoRTPSink<- MPEG1or2VideoRTPSink
live555代碼解讀之三:SETUP 和PLAY請求消息處理過程
前面已經提到RTSPClientSession類,用于處理單獨的客戶會話。其類成員函數handleCmd_SETUP()處理客戶端的SETUP請求。調用parseTransportHeader()對SETUP請求的傳輸頭解析,調用子會話(這里具體實現類為OnDemandServerMediaSubse
獲取發送傳輸參數的過程:調用子會話(具體實現類MPEG1or2DemuxedServerMed
客戶端發送兩個SETUP請求,分別用于建立音頻和視頻的RTP接收。
PLAY請求消息處理過程
RTSPClientSession類成員函數handleCmd_PLAY()處理客戶端的播放請求。首先調用子會話的startStream(),內部調用MediaSink::startPlaying(...),然后是MultiFramedRTPSink::continuePlaying(),接著調用MultiFramedRTPSink::buildAndSendPacket(...)。buildAndSendPacke內部先設置RTP包頭,內部再調用MultiFramedRTPSink::packFrame()填充編碼幀數據。
packFrame內部通過 FramedSource::getNextFrame(),接著MPEGVideoStreamFramer::doGetNextFrame(),再接著經過MPEGVideoStreamFramer::continueReadProcessing(),FramedSource::afterGetting(...),?
發送RTP數據包的間隔計算方法:
Update the time at which the next packet should be sent, based onthe duration of the frame that we just packed into it.
涉及到一些類有:
MPEGVideoStreamFramer: A filter that breaks up an MPEG videoelementary stream into headers and frames
MPEG1or2VideoStreamFrame
MPEG1or2DemuxedElementar
MPEG1or2Demux: Demultiplexer for a MPEG 1 or 2 Program Stream
ByteStreamFileSource: A file source that is a plain byte stream(rather than frames)
MPEGProgramStreamParser: Class for parsing MPEG programstream
StreamParser: Abstract class for parsing a byte stream
StreamState:A class that represents the state of an ongoing stream
RTSP點播消息流程
Real Time Streaming Protocol或者RTSP(實時流媒體協議),是由Real network 和Netscape共同提出的如何有效地在IP網絡上傳輸流媒體數據的應用層協議。RTSP提供一種可擴展的框架,使能夠提供可控制的,按需傳輸實時數據,比如音頻和視頻文件。源數據可以包括現場數據的反饋和存貯的文件。rtsp對流媒體提供了諸如暫停,快進等控制,而它本身并不傳輸數據,rtsp作用相當于流媒體服務器的遠程控制。傳輸數據可以?
通過傳輸層的tcp,udp協議,rtsp也提供了基于rtp傳輸機制的一些有效的方法。
RTSP消息格式:?
RTSP的消息有兩大類,一是請求消息(request),一是回應消息(response),兩種消息的格式不同.?
請求消息:?
方法 URI RTSP版本 CR LF?
消息頭 CR LF CR LF?
消息體 CR LF?
其中方法包括OPTION回應中所有的命令,URI是接受方的地址,例如?
:rtsp://192.168.20.136?
RTSP版本一般都是 RTSP/1.0.每行后面的CRLF表示回車換行,需要接受端有相應的解?
析,最后一個消息頭需要有兩個CR LF?
回應消息:?
RTSP版本 狀態碼 解釋 CR LF?
消息頭 CR LF CR LF?
消息體 CR LF?
其中RTSP版本一般都是RTSP/1.0,狀態碼是一個數值,200表示成功,解釋是與狀態碼對應?
的文本解釋.?
簡單的rtsp交互過程:?
C表示rtsp客戶端,S表示rtsp服務端?
1.C->S:OPTION request//詢問S有哪些方法可用?
1.S->C:OPTION response//S回應信息中包括提供的所有可用方法?
?
2.C->S:DESCRIBE request//要求得到S提供的媒體初始化描述信息?
2.S->C:DESCRIBE response//S回應媒體初始化描述信息,主要是sdp?
?
3.C->S:SETUP request//設置會話的屬性,以及傳輸模式,提醒S建立會?
話?
3.S->C:SETUP response//S建立會話,返回會話標識符,以及會話相關信息?
?
?
4.C->S:PLAY request //C請求播放?
4.S->C:PLAY response//S回應該請求的信息?
?
S->C:發送流媒體數據?
5.C->S:TEARDOWN request//C請求關閉會話?
5.S->C:TEARDOWN response//S回應該請求?
?
上述的過程是標準的、友好的rtsp流程,但實際的需求中并不一定按部就班來。?
其中第3和4步是必需的!第一步,只要服務器客戶端約定好,有哪些方法可用,則option請求可以不要。第二步,如果我們有其他途徑得到媒體初始化描述信息(比如http請求等等),則我們也不需要通過rtsp中的describe請求來完成。第五步,可以根據系統需求的設計來決定是否需要。?
?
rtsp中常用方法:?
?
1.OPTION?
目的是得到服務器提供的可用方法:?
OPTIONS rtsp://192.168.20.136:5000/xxx666RTSP/1.0?
CSeq: 1 //每個消息都有序號來標記,第一個包通常是option請求消息?
User-Agent: VLC media player (LIVE555 Streaming Mediav2005.11.10)?
?
服務器的回應信息包括提供的一些方法,例如:?
RTSP/1.0 200 OK?
Server: UServer 0.9.7_rc1?
Cseq: 1 //每個回應消息的cseq數值和請求消息的cseq相對應?
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE,SCALE,?
GET_PARAMETER //服務器提供的可用的方法?
2.DESCRIBE?
C向S發起DESCRIBE請求,為了得到會話描述信息(SDP):?
DESCRIBE rtsp://192.168.20.136:5000/xxx666RTSP/1.0?
?
CSeq: 2?
token:?
Accept: application/sdp?
User-Agent: VLC media player (LIVE555 Streaming Mediav2005.11.10)?
?
服務器回應一些對此會話的描述信息(sdp):?
RTSP/1.0 200 OK?
Server: UServer 0.9.7_rc1?
Cseq: 2?
x-prev-url: rtsp://192.168.20.136:5000?
x-next-url: rtsp://192.168.20.136:5000?
x-Accept-Retransmit: our-retransmit?
x-Accept-Dynamic-Rate: 1?
Cache-Control: must-revalidate?
Last-Modified: Fri, 10 Nov 2006 12:34:38GMT?
Date: Fri, 10 Nov 2006 12:34:38 GMT?
Expires: Fri, 10 Nov 2006 12:34:38 GMT?
Content-Base:rtsp://192.168.20.136:5000/xxx666/?
Content-Length: 344?
Content-Type: application/sdp?
?
v=0 //以下都是sdp信息?
o=OnewaveUServerNG 1451516402 1025358037 IN IP4192.168.20.136?
s=/xxx666?
u=http:///?
e=admin@?
c=IN IP4 0.0.0.0?
t=0 0?
a=isma-compliance:1,1.0,1?
?
a=range:npt=0-?
m=video 0 RTP/AVP 96//m表示媒體描述,下面是對會話中視頻通道的媒體描述?
a=rtpmap:96 MP4V-ES/90000?
a=fmtp:96?
profile-level-id=245;config=000001B0F5000001B5090000
?
a=control:trackID=0//trackID=0表示視頻流用的是通道0?
?
3.SETUP?
客戶端提醒服務器建立會話,并確定傳輸模式:?
SETUP rtsp://192.168.20.136:5000/xxx666/trackID=0RTSP/1.0?
CSeq: 3?
Transport:RTP/AVP/TCP;unicast;interleaved=0-1?
User-Agent: VLC media player (LIVE555 Streaming Mediav2005.11.10)?
//uri中帶有trackID=0,表示對該通道進行設置。Transport參數設置了傳輸模式,包?
的結構。接下來的數據包頭部第二個字節位置就是interleaved,它的值是每個通道都?
不同的,trackID=0的interleaved值有兩個0或1,0表示rtp包,1表示rtcp包,接受端?
根據interleaved的值來區別是哪種數據包。?
?
服務器回應信息:?
RTSP/1.0 200 OK?
Server: UServer 0.9.7_rc1?
Cseq: 3?
Session: 6310936469860791894 //服務器回應的會話標識符?
Cache-Control: no-cache?
Transport:RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=6B8B4567?
4.PLAY?
客戶端發送播放請求:?
PLAY rtsp://192.168.20.136:5000/xxx666RTSP/1.0?
CSeq: 4?
Session: 6310936469860791894?
Range: npt=0.000- //設置播放時間的范圍?
User-Agent: VLC media player (LIVE555 Streaming Mediav2005.11.10)?
服務器回應信息:?
RTSP/1.0 200 OK?
Server: UServer 0.9.7_rc1?
Cseq: 4?
Session: 6310936469860791894?
Range: npt=0.000000-?
RTP-Info:url=trackID=0;seq=17040;rtptime=1467265309?
//seq和rtptime都是rtp包中的信息?
5.TEARDOWN?
客戶端發起關閉請求:?
TEARDOWN rtsp://192.168.20.136:5000/xxx666RTSP/1.0?
CSeq: 5?
Session: 6310936469860791894?
User-Agent: VLC media player (LIVE555 Streaming Mediav2005.11.10)?
服務器回應:?
RTSP/1.0 200 OK?
Server: UServer 0.9.7_rc1?
Cseq: 5?
Session: 6310936469860791894?
Connection: Close?
?
以上方法都是交互過程中最為常用的,其它還有一些重要的方法如?
get/set_parameter,pause,redirect等等?
ps:?
sdp的格式?
v=<version>?
o=<username><session id><version> <networktype> <address type><address>?
s=<sessionname>?
i=<sessiondescription>?
u=<URI>?
e=<emailaddress>?
p=<phonenumber>?
c=<network type><address type><connectionaddress>?
b=<modifier>:<bandwidth-value>?
t=<start time><stop time>?
r=<repeat interval><active duration><list of offsets fromstart-time>?
z=<adjustment time><offset> <adjustmenttime> <offset>....?
k=<method>?
k=<method>:<encryptionkey>?
a=<attribute>?
a=<attribute>:<value>?
m=<media><port><transport> <fmtlist>?
v = (協議版本)?
o = (所有者/創建者和會話標識符)?
s = (會話名稱)?
i = * (會話信息)?
u = * (URI 描述)?
e = * (Email 地址)?
p = * (電話號碼)?
c = * (連接信息)?
b = * (帶寬信息)?
z = * (時間區域調整)?
k = * (加密密鑰)?
a = * (0 個或多個會話屬性行)?
時間描述:?
t = (會話活動時間)?
r = * (0或多次重復次數)?
媒體描述:?
m = (媒體名稱和傳輸地址)?
i = * (媒體標題)?
c = * (連接信息 — 如果包含在會話層則該字段可選)?
b = * (帶寬信息)?
k = * (加密密鑰)?
a = * (0 個或多個媒體屬性行)?
參考文章:rfc2326(rtsp);rfc2327(sdp)?
RTSP點播消息流程實例(客戶端:VLC, RTSP服務器:LIVE555 MediaServer)?
?
1)C(Client)-> M(MediaServer)?
OPTIONS rtsp://192.168.1.109/1.mpgRTSP/1.0?
CSeq: 1?
user-Agent: VLC media player(LIVE555 Streaming Mediav2007.02.20)?
?
1)M -> C?
RTSP/1.0 200 OK?
CSeq: 1?
Date: wed, Feb 20 2008 07:13:24 GMT?
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY,PAUSE?
?
2)C -> M?
DESCRIBE rtsp://192.168.1.109/1.mpgRTSP/1.0?
CSeq: 2?
Accept: application/sdp?
User-Agent: VLC media player(LIVE555 Streaming Mediav2007.02.20)?
?
2)M -> C?
RTSP/1.0 200 OK?
CSeq: 2?
Date: wed, Feb 20 2008 07:13:25 GMT?
Content-Base: rtsp://192.168.1.109/1.mpg/?
Content-type: application/sdp?
Content-length: 447?
v=0?
o =- 2284269756 1 IN IP4 192.168.1.109?
s=MPEG-1 or 2 program Stream, streamed by the LIVE555 MediaServer?
i=1.mpg?
t=0 0?
a=tool:LIVE555 Streaming Media v2008.02.08?
a=type:broadcast?
a=control:*?
a=range:npt=0-66.181?
a=x-qt-text-nam:MPEG-1 or Program Stream, streamed by theLIVE555 Media Server?
a=x-qt-text-inf:1.mpg?
m=video 0 RTP/AVP 32?
c=IN IP4 0.0.0.0?
a=control:track1?
m=audio 0 RTP/AVP 14?
c=IN IP4 0.0.0.0?
a=control:track2?
?
3)C -> M?
SETUP rtsp://192.168.1.109/1.mpg/track1RTSP/1.0?
CSeq: 3?
Transport: RTP/AVP;unicast;client_port=1112-1113?
User-Agent: VLC media player(LIVE555 Streaming Mediav2007.02.20)?
?
3)M -> C?
RTSP/1.0 200 OK?
CSeq: 3?
Date: wed, Feb 20 2008 07:13:25 GMT?
Transport:RTP/AVP;unicast;destination=192.168.1.222;source=192.168.1.109;client_port=1112-1113;server_port=6970-6971?
Session: 3?
?
4)C -> M?
SETUP rtsp://192.168.1.109/1.mpg/track2RTSP/1.0?
CSeq: 4?
Transport: RTP/AVP;unicast;client_port=1114-1115?
Session: 3?
User-Agent: VLC media player(LIVE555 Streaming Mediav2007.02.20)?
?
4)M -> C?
RTSP/1.0 200 OK?
CSeq: 4?
Date: wed, Feb 20 2008 07:13:25 GMT?
Transport:RTP/AVP;unicast;destination=192.168.1.222;source=192.168.1.109;client_port=1114-1115;server_port=6972-6973?
Session: 3?
?
5)C -> M?
PLAY rtsp://192.168.1.109/1.mpg/ RTSP/1.0?
CSeq: 5?
Session: 3?
Range: npt=0.000-?
User-Agent: VLC media player(LIVE555 Streaming Mediav2007.02.20)?
?
5)M -> C?
RTSP/1.0 200 OK?
CSeq: 5?
Range: npt=0.000-?
Session: 3?
TS流與PS流的區別在于TS流的包結構是固定長度的,而PS流的包結構是可變長度。PS包與TS包在結構上的這種差異,導致了它們對傳輸誤碼具有不同的抵抗能力,因而應用的環境也有所不同。TS碼流由于采用了固定長度的包結構,當傳輸誤碼破壞了某一TS包的同步信息時,接收機可在固定的位置檢測它后面包中的同步信息,從而恢復同步,避免了信息丟失。而PS包由于長度是變化的,一旦某一PS包的同步信息丟失,接收機無法確定下一包的同步位置,就會造成失步,導致嚴重的信息丟失。因此,在信道環境較為惡劣,傳輸誤碼較高時,一般采用TS碼流;而在信道環境較好,傳輸誤碼較低時,一般采用PS碼流由于TS碼流具有較強的抵抗傳輸誤碼的能力,因此目前在傳輸媒體中進行傳輸的MPEG-2碼流基本上都采用了TS碼流的包
格。
用live555開發流媒體播放器應用程序的方法