流媒體服務(wù)器是由一個父進(jìn)程構(gòu)成的,這個父進(jìn)程分叉出一個子進(jìn)程,該子進(jìn)程就是核心服務(wù)器。父進(jìn)程會等待子進(jìn)程的退出。如果子進(jìn)程錯誤退出,則父進(jìn)程就會分叉出一個新的子進(jìn)程。
核心服務(wù)器的作用是充當(dāng)網(wǎng)絡(luò)客戶和服務(wù)器模塊的接口,其中網(wǎng)絡(luò)客戶使用RTP和RTSP協(xié)議來發(fā)送請求和接收響應(yīng),而服務(wù)器模塊則負(fù)責(zé)處理請求和向客戶端發(fā)送數(shù)據(jù)包。核心服務(wù)器通過創(chuàng)建四種類型的線程來完成自己的工作,具體如下:
服務(wù)器自己擁有的主線程(Main Thread)。這個線程負(fù)責(zé)檢查服務(wù)器是否需要關(guān)閉,記錄狀態(tài)信息,或者打印統(tǒng)計信息。空閑任務(wù)線程(Idle Task Thread)。空閑任務(wù)線程管理一個周期性的任務(wù)隊列。該任務(wù)隊列有兩種類型:套接口任務(wù)。事件線程(Event Thread)。事件線程負(fù)責(zé)偵聽套接口事件,比如收到RTSP請求和RTP數(shù)據(jù)包,然后把事件傳遞給任務(wù)線程。一個或者多個任務(wù)(Task)線程。任務(wù)線程從事件線程中接收RTSP和RTP請求,然后把請求傳遞到恰當(dāng)?shù)姆?wù)器模塊進(jìn)行處理,把數(shù)據(jù)包發(fā)送給客戶端。缺省情況下,核心服務(wù)器為每一個處理器創(chuàng)建一個任務(wù)線程。圖 1-1 總結(jié)了客戶端,核心服務(wù)器的線程,和服務(wù)器模塊之間的關(guān)系。

由于服務(wù)器很大程度上是異步的,所以需要為不同的事件提供一個通訊機(jī)制。舉例來說,當(dāng)某個用于RTSP連接的套接口得到數(shù)據(jù)時,需要通知某些組件,數(shù)據(jù)才能被處理。Task(任務(wù))對象就是執(zhí)行這種通訊的一般性的機(jī)制。
每一個Task對象都有兩個主要的方法:即Signal和Run。服務(wù)器調(diào)用Signal方法來把一個事件發(fā)送給Task對象,而Run方法則用來為Task對象指定處理事件的時機(jī)。
每個Task對象的目標(biāo)都是用小的非阻塞的時間片來實(shí)現(xiàn)服務(wù)器的功能。Run是一個純虛函數(shù),當(dāng)Task對象有事件需要處理時被調(diào)用。在Run函數(shù)的內(nèi)部,Task對象可以調(diào)用GetEvents函數(shù)來接收當(dāng)前的和先前已經(jīng)用信號通知過的事件,并自動使該事件退出隊列。Run函數(shù)是永遠(yuǎn)不可重入的:如果一個Task對象在其Run函數(shù)中調(diào)用GetEvents函數(shù),然后在Run函數(shù)完成之前又發(fā)出信號,則該Run函數(shù)只有在當(dāng)前的函數(shù)實(shí)例退出之后,才能(因?yàn)槟莻€新的事件)再次被調(diào)用。事實(shí)上,Task對象的Run函數(shù)會被反復(fù)調(diào)用,直到該對象的所有事件全部被GetEvents函數(shù)清除掉為止。
這個事件觸發(fā)任務(wù)的核心概念被集成到幾乎每一個流媒體服務(wù)器的子系統(tǒng)中。舉例來說,一個Task對象可能和一個套接口(Socket)對象相關(guān)聯(lián)。如果Socket對象得到一個事件(通過select()通知,或者通過Mac OS X的時間隊列),則相應(yīng)的Task對象就會得到信號通知。在這種情況下,Run函數(shù)的函數(shù)體中就會包含相應(yīng)的代碼,來處理在該Socket對象上接收到的任何事件。
Task對象使得流媒體服務(wù)器用單獨(dú)一個線程來運(yùn)行所有連接的做法成為可能,這正是流媒體服務(wù)器在單處理器系統(tǒng)上的缺省設(shè)置。
這個部分包含以下內(nèi)容:
模塊
協(xié)議
數(shù)據(jù)
類
應(yīng)用程序和工具
源代碼的組織
流媒體服務(wù)器使用模塊來響應(yīng)各種請求及完成任務(wù)。有三種類型的模塊:
內(nèi)容管理模塊負(fù)責(zé)管理與媒體源相關(guān)的RTSP請求和響應(yīng),比如一個文件或者一個廣播。每個模塊負(fù)責(zé)解釋客戶的請求,讀取和解析它們的支持文件或者網(wǎng)絡(luò)源,并且以RTSP和RTP的方式進(jìn)行響應(yīng)。在某些情況下,比如流化mp3的模塊,使用的則是HTTP。QTSSFileModule,QTSSReflectorModule,QTSSRelayModule,和QTSSMP3StreamingModule都是內(nèi)容管理模塊。
服務(wù)器支持模塊執(zhí)行服務(wù)器數(shù)據(jù)的收集和記錄功能。服務(wù)器模塊包括QTSSErrorLogModule, QTSSaccessLogModule,QTSSWebStatsModule,QTSSWebDebugModule, QTSSAdminModule,和QTSSPOSIXFileSystemModule。
訪問控制模塊提供鑒權(quán)和授權(quán)功能,以及操作URL路徑提供支持。訪問控制模塊包括QTSSAccessModule,QTSSHomeDirectoryModule,QTSSHttpFileModule,和QTSSSpamDefenseModule。
流媒體服務(wù)器支持下面的協(xié)議:
基于TCP之上的RTSP。實(shí)時流媒體協(xié)議(Real Time Streaming PRotocol,即RTSP)是一個客戶-服務(wù)器多媒體表示控制協(xié)議,其設(shè)計目的是為了實(shí)現(xiàn)ip網(wǎng)絡(luò)流媒體的有效分發(fā)。RTSP為諸如RTP這樣的單點(diǎn)傳輸和多點(diǎn)傳輸協(xié)議的握手,以及與文件格式無關(guān)的編解碼器的選擇提供了基本條件。它既可以應(yīng)用于具有大量觀眾的場合,也可以應(yīng)用于只有一個觀眾的媒體點(diǎn)播場合。RFC 2326定義了RTSP的IETF標(biāo)準(zhǔn)。基于UDP的RTP。實(shí)時傳輸協(xié)議(Realtime Transport Protocol,即RTP)為多媒體數(shù)據(jù)流定義數(shù)據(jù)包的格式。很多標(biāo)準(zhǔn)協(xié)議都用到RTP協(xié)議,比如用于流媒體的RTSP協(xié)議,和用于多點(diǎn)傳輸?shù)腟DP協(xié)議。它為RTSP和SDP提供數(shù)據(jù)的分發(fā)格式。RFC 1889定義了RTP的IETF建議標(biāo)準(zhǔn)。基于蘋果電腦的可靠UDP(Reliable UDP)協(xié)議的RTP。如果一個RTP客戶發(fā)出相應(yīng)的請求,則服務(wù)器可以使用可靠UDP的格式來發(fā)送RTP包。可靠UDP定義了一系列對服務(wù)品質(zhì)的增強(qiáng),比如提高擁擠控制調(diào)整方法,重新傳輸,和服務(wù)器瘦化算法(thinning server algorithm),這些增強(qiáng)使服務(wù)器在數(shù)據(jù)包丟失和網(wǎng)絡(luò)擁擠的情況下,向RTP客戶提供優(yōu)質(zhì)RTP流的能力得到提升。HTTP中的RTSP/RTP(通道式)。防火墻通常不允許私有IP網(wǎng)絡(luò)的用戶接收QuickTime內(nèi)容。在私有網(wǎng)絡(luò)中,通常會對HTTP代理服務(wù)器進(jìn)行配置,使用戶只能間接訪問英特網(wǎng)。為了能夠把內(nèi)容分發(fā)到這一類客戶,QuickTime 4.1支持用HTTP的請求和響應(yīng)的方式來代替RTSP和RTP進(jìn)行數(shù)據(jù)傳送,這使得防火墻后面的接收者可以通過HTTP代理服務(wù)器訪問到QuickTime分發(fā)的內(nèi)容。RTSP之上的RTP(TCP之上的RTP)。某些防火墻的設(shè)計,和其它環(huán)境可能會要求服務(wù)器使用不同的方式把數(shù)據(jù)發(fā)送給客戶。RFC 2326允許把目的地為同一控制端點(diǎn)的RTSP數(shù)據(jù)包打包為一個更底層的協(xié)議數(shù)據(jù)單元(protocol data unint,即PDU),然后封裝在TCP流中,或者和RTP和RTCP數(shù)據(jù)包交織在一起。采用交織的方式會使客戶和服務(wù)器的操作變得更為復(fù)雜,增加額外的負(fù)擔(dān),因此只有當(dāng)TCP中攜帶RTSP的情況下,才使用這種方法。RTP數(shù)據(jù)包的封裝方式如下:首先是一個ASCII的美元符號($);接著是一個字節(jié)的通道標(biāo)識符(在傳輸頭中定義,使用的是交織過的參數(shù));然后是被包裝的二進(jìn)制數(shù)據(jù)的長度,這是一個二進(jìn)制的按網(wǎng)絡(luò)字節(jié)順序排列的雙字節(jié)整數(shù);緊接下來是流數(shù)據(jù),沒有CRLF,但是包含一個上層協(xié)議頭。每一個$塊包含一個且只有一個RTP包。在使用RTP進(jìn)行傳輸時,服務(wù)器也會在TCP連接之上把RTCP消息進(jìn)行編織。缺省情況下,RTCP數(shù)據(jù)包會在高于RTP通道的第一個可用通道進(jìn)行發(fā)送。客戶可以顯式地在其它通道上請求RTCP數(shù)據(jù)包,通過在傳輸頭中的編織參數(shù)中指定兩個通道就可以實(shí)現(xiàn)。當(dāng)有兩個或者兩個以上的流被編織時,RTCP用來進(jìn)行各個流的同步。當(dāng)網(wǎng)絡(luò)配置需要時,這也提供了一種基于TCP控制連接建立RTP/RTCP數(shù)據(jù)包通道,并在可能的情況下將它們傳送到UDP上的便利方法。此外,下面的模塊實(shí)現(xiàn)了HTTP的支持:
QTSSAdminModuleQTSSMP3StreamingModuleQTSSWebStatsModuleQTSSHTTPStreamingModuleQTSSRefMovieModuleQTSSWebStatsQTSSWebDebugModule當(dāng)一個模塊需要訪問客戶請求的RTSP報頭時,可以通過QTSS.h這個API頭文件中定義的請求對象來訪問相應(yīng)的請求信息。舉例來說,RTSPRequestInterface類實(shí)現(xiàn)了API字典元素,這些元素可以通過API來進(jìn)行訪問。名稱是以“Interface”結(jié)尾的對象,比如RTSPRequestInterface,RTSPsessionInterface,和QTSServerInterface,則用于實(shí)現(xiàn)模塊的API。 下面是重要的接口類:
QTSServerInterface — 這是內(nèi)部數(shù)據(jù)的存儲對象,在API中標(biāo)識為QTSS_ServerObject。在API中的每一個QTSS_ServerAttributes都在基類中聲明和實(shí)現(xiàn)。RTSPSessionInterace — 這是內(nèi)部數(shù)據(jù)的存儲對象,在API中標(biāo)識為qtssRTSPSessionObjectType。在API中的每一個QTSS_RTSPSessionAttributes都在基類中聲明和實(shí)現(xiàn)。RTPSessionInterface — 這是內(nèi)部數(shù)據(jù)的存儲對象,在API中標(biāo)識為QTSS_ClientSessionObject。在API中的每一個QTSS_ClientSessionAttributes都在基類中聲明和實(shí)現(xiàn)。RTSPRequestInterface — 這是內(nèi)部數(shù)據(jù)的存儲對象,在API中標(biāo)識為QTSS_RTSPRequestObject。在API中的每一個QTSS_RTSPRequestAttributes都在基類中聲明和實(shí)現(xiàn)。圖 1-2 顯示在服務(wù)器中的對象是如何互相引用的。

服務(wù)器對象中有一個預(yù)置信息字典。服務(wù)器內(nèi)部有一個模塊列表,列表中的每一個模塊都有一個字典,用于存放自己的預(yù)置信息。服務(wù)器中還有一個RTP客戶會話的列表,每一個會話都可能有一個RTSP會話以及一個或多個RTP媒體流。通過API來遍歷服務(wù)器中所有活躍的會話和流是有可能的。
QTServer是一個核心服務(wù)器對象,這個對象的一部分可以通過API和QTSServerInterface基類來進(jìn)行訪問。Dictionary是一種把鍵值對實(shí)現(xiàn)為對象數(shù)據(jù)的數(shù)據(jù)存儲類。由API定義的所有服務(wù)器對象都是從這個基類繼承下來的。Module是管理模塊的類。每個模塊的實(shí)例負(fù)責(zé)裝載,初始化,以及執(zhí)行一個靜態(tài)或者動態(tài)的API模塊。RTSP和RTP會話。流的讀寫是由會話通過一個流對象來管理的。RTSP會話在RTSPSession::Run方法中會調(diào)用每個模塊中注冊過的RTSP角色(Role)。被調(diào)用的API模塊角色有QTSS_RTSPFilter_Role,QTSS_RTSPRoute_Role,QTSS_RTSPAuthenticate_Role, QTSS_RTSPAuthorize_Role,QTSS_RTSPPreProcessor_Role,QTSS_RTSPRequest_Role, QTSS_RTSPPostProcessor_Role,和QTSS_RTSPSessionClosingRole。RTSP會話還會調(diào)用注冊為QTSS_RTSPIncomingData_Role角色的模塊。RTP會話除了處理數(shù)據(jù)的讀寫之外,還調(diào)用下面的角色:QTSS_RTPSendPackets_Role,QTSS_RTCPProcess_Role,和QTSS_ClientSessionClosing_Role。如果需要更多關(guān)于角色的信息,請參見“Darwin模塊角色”部分。蘋果電腦在提供流媒體服務(wù)器的同時還提供下面的應(yīng)用程序和工具:
PlayListBroadcasterMP3BroadcasterStreamingProxy(僅在POSIX和Mac OS X平臺上提供)QTFileTools(僅在POSIX和Mac OS X平臺上提供,不做維護(hù))。WebAdminqtpasswdPlayListBroadcaster用來播放QuickTime Broadcaster錄制完成的電影。
MP3Broadcaster用來廣播MP3文件,和現(xiàn)場直播一樣。
僅在POSIX和Mac OS X平臺上提供。
QTFileTools是一些基于QTFile庫開發(fā)的電影查看工具。這些工具包括:
QTBroadcaster。這個工具要求給定一個目標(biāo)IP地址,一個擁有一個或者多個線索軌道(hint track)ID的電影源,以及一個初始化端口。通過這個工具,被線索軌道引用的每一個數(shù)據(jù)包都可以被廣播到指定的IP地址。QTFileInfo。使用這個工具需要給定一個電影源。通過這個工具可以顯示指定電影的名稱,創(chuàng)建日期,以及修改日期。如果電影中的軌道是線索軌道,則它也可以顯示RTP字節(jié)總數(shù)和數(shù)據(jù)包總數(shù),平均的位率和數(shù)據(jù)包尺寸,以及數(shù)據(jù)報頭在流中的百分比。QTFileTest。使用這個工具需要給定一個電影源。通過這個工具可以解析電影頭原子(Movie Header Atom),并跟蹤和顯示輸出信息。QTRTPGent。這個工具要求給定一個具有線索軌道的電影源。它可以顯示每一個線索軌道樣本中含有的多少數(shù)據(jù)包,并且將RTP數(shù)據(jù)包寫入到名為track.cache的文件中。QTRTPFileTest。這個工具要求給定一個具有線索軌道ID的電影源。它可以顯示每個數(shù)據(jù)包的RTP頭信息(包括TransmitTime,Cookie,SeqNum,和TimeStamp)。QTSampleLister。這個工具要求給定一個電影源和一個軌道ID。它可以顯示指定軌道的媒體數(shù)目,媒體時間,數(shù)據(jù)偏移量,以及軌道中每個樣本的尺寸。QTSDPGen。這個工具要求給定一個包含一個或者多個電影源的列表。它可以顯示列表中每個電影包含的所有線索軌道的SDP信息。通過 -f 選項(xiàng),可以把SDP信息保存在moviename.sdp文件中,該文件和電影源位于同一個目錄。QTTrackInfo。這個工具要求給定一個電影源,一個樣本表原子類型(stco,stsc,stsz,或者stts)以及一個軌道ID。它可以顯示指定軌道的樣本表原子的信息。作為例子,下面的命令顯示ID為3的軌道中的樣本表的大塊數(shù)據(jù)的偏移量:
./QTTrackInfo -T stco /movies/mystery/.mov 3WebAdmin
WebAdmin是一個基于Perl的web服務(wù)器。將瀏覽器連接到這個服務(wù)器上,就可以對流媒體服務(wù)器進(jìn)行管理。
qtpasswd
qtpasswd程序用于產(chǎn)生訪問控制用的密碼文件。
源代碼的組織
流媒體服務(wù)器的源代碼全部用C++編寫的,并且普遍使用到諸如繼承和多態(tài)這樣的面向?qū)ο蟮母拍睢C恳粚?h / .cpp文件對應(yīng)一個C++類,并且文件名和類名是相互匹配的,這個規(guī)則幾乎沒有例外。流媒體服務(wù)器的源代碼按下面的方式進(jìn)行組織:
“Server.tproj”“CommonUtilitiesLib”“QTFileLib”“APICommonCode”“APIModules”“RTSPClientLib”“RTCPUtilitiesLib”“APIStubLib”“HTTPUtilitiesLib”Server.tproj
這個目錄包含核心服務(wù)器(core server)的代碼,可以分成三個子系統(tǒng):
服務(wù)器內(nèi)核。這個子系統(tǒng)中的類都有一個QTSS前綴。QTSServer負(fù)責(zé)處理服務(wù)器的啟動和關(guān)閉。QTSServerInterface負(fù)責(zé)保存服務(wù)器全局變量,以及收集服務(wù)器的各種統(tǒng)計信息。QTSSPrefs是存儲服務(wù)器偏好設(shè)定的地方。QTSSModule,QTSSModuleInterface,和QTSSCallbacks類的唯一目的就是支持QTSS的模塊API。RTSP子系統(tǒng)。這些類負(fù)責(zé)解析和處理RTSP請求,以及實(shí)現(xiàn)QTSS模塊API的RTSP部分。其中的幾個類直接對應(yīng)QTSS API的一些元素(比如,RTSPRequestInterface類就是對應(yīng)于QTSS_RTSPRequestObject對象)。每個RTSP TCP連接都有一個RTSP會話對象與之相對應(yīng)。RTSPSession對象是一個Task對象,負(fù)責(zé)處理與RTSP相關(guān)的事件。RTP子系統(tǒng)。這些類處理媒體數(shù)據(jù)的發(fā)送。RTPSession對象包含與所有RTSP會話ID相關(guān)聯(lián)的數(shù)據(jù)。每個RTPSession都是一個Task對象,可以接受核心服務(wù)器的調(diào)度來進(jìn)行RTP數(shù)據(jù)包的發(fā)送。RTPStream對象代表一個單獨(dú)的RTP流,一個RTPSession對象可以和任何數(shù)目的RTPStream對象相關(guān)聯(lián)。這兩個對象實(shí)現(xiàn)了QTSS模塊API中的針對RTP的部分。CommonUtilitiesLib
這個目錄含有一個工具箱,包括線程管理,數(shù)據(jù)結(jié)構(gòu),網(wǎng)絡(luò),和文本解析工具。Darwin流媒體服務(wù)器及其相關(guān)工具通過這些類對類似或者相同的任務(wù)進(jìn)行抽象,以減少重復(fù)代碼;這些類的封裝簡化了較高層次的代碼;借助這些類還分離了專用于不同平臺的代碼。下面是對目錄下的各個類的簡短描述:
OS類。這些類在時間,條件變量,互斥鎖,和線程方面提供了專用于不同平臺的代碼抽象。這些類包括OS,OSCond,OSMutex,OSThread,和OSFileSource;數(shù)據(jù)結(jié)構(gòu)則包括OSQueue,OSHashTable,OSHeap,和OSRef。套接口類(Sockets)。這些類為TCP和UDP網(wǎng)絡(luò)通訊方面提供了專用于不同平臺的代碼抽象。通常情況下,套接口類是異步的(或者說是非阻塞的),可以發(fā)送事件給Task對象。這些類有:EventContext,Socket,UDPSocket,UDPDemuxer,UDPSocketPool,TCPSocket,和TCPListenerSocket。解析工具。這些類負(fù)責(zé)解析和格式化文本。包括StringParser,StringFormatter,StrPtrLen,和StringTranslator。Task(任務(wù)):這些類實(shí)現(xiàn)了服務(wù)器的異步事件機(jī)制。QTFileLib
流媒體服務(wù)器的一個主要特性就是它能夠?qū)⑺饕瓿桑╤inted)的QuickTime電影文件通過RTSP和RTP協(xié)議提供給客戶。這個目錄包含QTFile庫的源代碼,包括負(fù)責(zé)解析索引完成的QuickTime文件的代碼。服務(wù)器的RTPFileModule通過調(diào)用QTFile庫來從索引過的QuickTime文件中取得數(shù)據(jù)包和元數(shù)據(jù)。QTFile庫可以解析下面幾種文件類型:.mov,.mp4(.mov的一種修改版本),和.3gpp(.mov的一種修改版本)。
APICommonCode
這個目錄包含與API相關(guān)的類的源代碼,比如moduletils,或者諸如記錄文件的管理這樣的公共模塊函數(shù)。
APIModules
這個目錄包含流媒體服務(wù)器模塊目錄,每個模塊都有一個目錄。
RTSPClientLib
這個目錄包含實(shí)現(xiàn)RTSP客戶端的源代碼,這些代碼可以用于連接服務(wù)器,只要該連接協(xié)議被支持。
RTCPUtilitiesLib
這個目錄包含解析RTCP請求的源代碼。
APIStubLib
這個目錄包含API的定義和支持文件。
HTTPUtilitiesLib
這個目錄包含解析HTTP請求的源代碼。
新聞熱點(diǎn)
疑難解答