1. 程式人生 > >流媒體技術筆記(DarwinStreamingServer相關)

流媒體技術筆記(DarwinStreamingServer相關)

attr 任務隊列 高性能 over session 前臺 網絡 param mutex

簡介

Darwin Streaming Server簡稱DSS。DSS是Apple公司提供的開源實時流媒體播放服務器程序。整個程序使用C++編寫,在設計上遵循高性能,簡單,模塊化等程序設計原則,務求做到程序高效,可擴充性好。並且DSS是一個開放源代碼的,基於標準的流媒體服務器,可以運行在Windows NT和Windows 2000,以及幾個UNIX實現上,包括Mac OS X,Linux,FreeBSD,和Solaris操作系統上的。

網址:http://dss.macosforge.org/

源碼:http://dss.macosforge.org/downloads/DarwinStreamingSrvr6.0.3-Source.tar

特性

支持MP4、3GPP等文件格式;

支持MPEG-4、H.264等視頻編解碼格式;

支持RTSP流控協議,支持HTTP協議,支持RTP流媒體傳輸協議;

支持基於Web的管理;

支持單播和組播;

具有完備的日誌功能。

此外,該服務器版本提供了一個基於模塊的擴展方法。利用DSS提供的API就可以很方便地編寫靜態或動態的模塊,對DSS進行擴展,使其支持其它文件格式、協議或者功能。

DSS服務器架構

設計模式相關

1、並發設計模式

阻塞的IO方式效率極低,這裏不予討論。非阻塞的IO分成兩種,分別是非阻塞同步IO和非阻塞異步IO,對應的,Reactor和Proactor是高性能並發服務器設計中常見的兩種模式,Reactor用於同步IO,Proactor用於異步IO。無論是Reator還是Proactor,都包含了時間分離器和時間處理器。

2、Darwin使用的設計模式

Darwin Streaming Server從設計模式上看,采用了Reactor的並發服務器設計模式。Reactor模式是典型的事件觸發模式,當有事件發生時則完成相應的Task,Task的完成是通過調用相應的handle來實現的,對於handle的調用是由有限個數的Thread來完成的。

在DSS的各類線程中,事件線程充當Reactor模式中的事件分離器,任務線程充當Reactor模式中的事件處理器。

主框架

DSS的核心服務器部分是由一個父進程所fork出的一個子進程構成,該父進程就構成了整合流媒體服務器。父進程會等待子進程的退出,如果在運行的時候子進程產生了錯誤從而退出,那麽父進程就會fork出一個新的子進程。

服務器的作用是充當網絡客戶和服務器模塊的接口,其中網絡客戶使用RTP和RTSP協議來發送請求和接收響應,而服務器模塊則負責處理請求和向客戶端發送數據包。核心流媒體服務通過創建四種類型的線程來完成自己的工作,具體如下:

服務器主線程(Main Thread) : 這個線程負責檢查服務器是否需要關閉,記錄狀態信息,或者打印統計信息。

空閑任務線程(Idle Task Thread):空閑任務線程管理一個周期性的任務隊列。該任務隊列有兩種類型:超時任務和Socket任務。

事件線程(Event Thread):負責監聽套接口相關事件,當有RTSP請求或者收到RTP數據包時,事件線程就會把這些實踐交給任務線程來處理。

任務線程(Task Thread):任務線程會把事件從事件線程中取出,並把處理請求傳遞到對應的服務器模塊進行處理,比如把數據包發送給客戶端的模塊,在默認情況下,核心服務器會為每個處理器核創建一個任務線程。

關系如圖所示:

技術分享圖片

DSS參數說明

-v :顯示使用方法,即參數列表

-d :在前臺運行程序

-D :在前臺運行程序,並顯示性能數據(服務器統計信息)

-Z xxx :設定debug級別

-p xxx :指定默認的RTSP服務器監聽端口

-S n :每隔n秒在控制臺中顯示一次服務器統計

-c myconfigpath.xml : 指定一個配置文件

-o myconfigpath.conf: 指定一個DSS 1.x/2.x的配置文件來生成xml

-x :強制建立一個新的xml配置文件並退出

-I :以空閑狀態啟動服務器

模塊

媒體服務器使用模塊來響應各種請求及完成任務。有三種類型的模塊:

  1. 內容管理模塊

內容管理模塊負責管理與媒體源相關的RTSP請求和響應,比如一個文件或者一個廣播。每個模塊負責解釋客戶的請求,讀取和解析它們的支持文件或者網絡源,並且以RTSP和RTP的方式進行響應。在某些情況下,比如流化mp3的模塊,使用的則是HTTP。

內容管理模塊包括:

QTSSFileModule

QTSSReflectorModule

QTSSRelayModule

QTSSMP3StreamingModule

  1. 服務器支持模塊

服務器支持模塊執行服務器數據的收集和記錄功能。

服務器模塊包括:

QTSSErrorLogModule

QTSSAccessLogModule

QTSSWebStatsModule

QTSSWebDebugModule

QTSSAdminModule

QTSSPOSIXFileSystemModule

  1. 訪問控制模塊

訪問控制模塊提供鑒權和授權功能,以及操作URL路徑提供支持。

訪問控制模塊包括:

QTSSAccessModule

QTSSHomeDirectoryModule

QTSSHttpFileModule

QTSSSpamDefenseModule

協議

DSS支持以下協議:

RTSP over TCP

RTP over UDP

RTP over Apple’s Reliable UDP

RTSP/RTP in HTTP (tunneled)

RTP over RTSP (RTP over TCP)

以下模塊用http實現:

QTSSAdminModule

QTSSMP3StreamingModule

QTSSWebStatsModule

QTSSHTTPStreamingModule

QTSSRefMovieModule

QTSSWebStats

數據訪問接口

當一個模塊需要訪問客戶請求的RTSP報頭時,可以通過QTSS.h這個API頭文件中定義的請求對象來訪問相應的請求信息。舉例來說,RTSPRequestInterface類實現了API字典元素,這些元素可以通過API來進行訪問。名稱是以“Interface”結尾的對象,比如RTSPRequestInterface,RTSPSessionInterface,和QTSServerInterface,則用於實現模塊的API。

下面是重要的接口類:

  • QTSServerInterface — 這是內部數據的存儲對象,在API中標識為QTSS_ServerObject。在API中的每一個QTSS_ServerAttributes都在基類中聲明和實現。

  • RTSPSessionInterace — 這是內部數據的存儲對象,在API中標識為qtssRTSPSessionObjectType。在API中的每一個QTSS_RTSPSessionAttributes都在基類中聲明和實現。

  • RTPSessionInterface — 這是內部數據的存儲對象,在API中標識為QTSS_ClientSessionObject。在API中的每一個QTSS_ClientSessionAttributes都在基類中聲明和實現。

  • RTSPRequestInterface — 這是內部數據的存儲對象,在API中標識為QTSS_RTSPRequestObject。在API中的每一個QTSS_RTSPRequestAttributes都在基類中聲明和實現。

主體類

DSS源代碼完全采用標準C++語言寫成,編程風格非常優秀,每一個C++類都對應著一對和類同名的.h/.cpp文件。整個服務器包括多個子系統,分別存放在獨立的工程內,其中,最為重要的是基礎功能類庫(Common Utilities Lib)和流化服務器(Streaming Server)兩個工程。

1、基礎功能類庫(Common Utilities Lib)

OS類

執行與系統平臺相關的數據結構。

Socket 類

執行與平臺相關的Socket函數。

Tasks類

主要包含使服務器異步運行模式的類。

RTCP Utilities Lib

主要包含對RTCP封包作解碼或編碼及產生封包的類。

2、核心功能庫(Server Core)

RTSP 子系統

負責解析和處理RTSP請求。

RTP子系統

負責媒體數據包的發送,根據RTCP 的反饋進行服務質量控制。

公共服務子系統

負責服務器的啟動/關閉、初始化參數設置以及為module機制、跨平臺的多線程和事件機制等提供支持。

源代碼組織

Server.tproj

這個目錄包含核心服務器(core server)的代碼,可以分成三個子系統:

  • 服務器內核。這個子系統中的類都有一個QTSS前綴。QTSServer負責處理服務器的啟動和關閉。QTSServerInterface負責保存服務器全局變量,以及收集服務器的各種統計信息。QTSSPrefs是存儲服務器偏好設定的地方。QTSSModule,QTSSModuleInterface,和QTSSCallbacks類的唯一目的就是支持QTSS的模塊API。

  • RTSP子系統。這些類負責解析和處理RTSP請求,以及實現QTSS模塊API的RTSP部分。其中的幾個類直接對應QTSS API的一些元素(比如,RTSPRequestInterface類就是對應於QTSS_RTSPRequestObject對象)。每個RTSP TCP連接都有一個RTSP會話對象與之相對應。RTSPSession對象是一個Task對象,負責處理與RTSP相關的事件。

  • RTP子系統。這些類處理媒體數據的發送。RTPSession對象包含與所有RTSP會話ID相關聯的數據。每個RTPSession都是一個Task對象,可以接受核心服務器的調度來進行RTP數據包的發送。RTPStream對象代表一個單獨的RTP流,一個RTPSession對象可以和任何數目的RTPStream對象相關聯。這兩個對象實現了QTSS模塊API中的針對RTP的部分。

CommonUtilitiesLib

這個目錄含有一個工具箱,包括線程管理,數據結構,網絡,和文本解析工具。Darwin流媒體服務器及其相關工具通過這些類對類似或者相同的任務進行抽象,以減少重復代碼;這些類的封裝簡化了較高層次的代碼;借助這些類還分離了專用於不同平臺的代碼。下面是對目錄下的各個類的簡短描述:

  • OS類。這些類在時間,條件變量,互斥鎖,和線程方面提供了專用於不同平臺的代碼抽象。這些類包括OS,OSCond,OSMutex,OSThread,和OSFileSource;數據結構則包括OSQueue,OSHashTable,OSHeap,和OSRef。

  • 套接口類(Sockets)。這些類為TCP和UDP網絡通訊方面提供了專用於不同平臺的代碼抽象。通常情況下,套接口類是異步的(或者說是非阻塞的),可以發送事件給Task對象。這些類有:EventContext,Socket,UDPSocket,UDPDemuxer,UDPSocketPool,TCPSocket,和TCPListenerSocket。

  • 解析工具。這些類負責解析和格式化文本。包括StringParser,StringFormatter,StrPtrLen,和StringTranslator。

  • Task(任務):這些類實現了服務器的異步事件機制。

QTFileLib

流媒體服務器的一個主要特性就是它能夠將索引完成(hinted)的QuickTime電影文件通過RTSP和RTP協議提供給客戶。這個目錄包含QTFile庫的源代碼,包括負責解析索引完成的QuickTime文件的代碼。服務器的RTPFileModule通過調用QTFile庫來從索引過的QuickTime文件中取得數據包和元數據。QTFile庫可以解析下面幾種文件類型:.mov,.mp4(.mov的一種修改版本),和.3gpp(.mov的一種修改版本)。

APICommonCode

這個目錄包含與API相關的類的源代碼,比如moduletils,或者諸如記錄文件的管理這樣的公共模塊函數。

APIModules

這個目錄包含流媒體服務器模塊目錄,每個模塊都有一個目錄。

RTSPClientLib

這個目錄包含實現RTSP客戶端的源代碼,這些代碼可以用於連接服務器,只要該連接協議被支持。

RTCPUtilitiesLib

這個目錄包含解析RTCP請求的源代碼。

APIStubLib

這個目錄包含API的定義和支持文件。

HTTPUtilitiesLib

這個目錄包含解析HTTP請求的源代碼。

二次開發模塊添加的要求

  每個DSS模塊必須實現兩個函數:一個是Main函數,服務器在啟動時將調用這個函數進行必要的初始化。另一個是Dispatch函數,通過實現此函數,服務器可調用DSS模塊並完成特定處理。對於編譯到服務器裏面的模塊,其主函數的地址必須傳遞到服務器的模塊Main函數中。

具體實現時,Main函數必須命名為MyModule_Main,其中MyModule是模塊的文件名。此函數的實現通常如下所示:

QTSS_Error MyModule_Main(void* inPrivateArgs)

{

return _stublibrary_main(inPrivateArgs, MyModuleDispatch);
}

  每個DSS模塊都必須提供一個Dispatch函數。服務器為了特定的目的需要使用某個模塊時,是通過調用該模塊的Dispatch函數來實現的,調用時必須將任務的名稱及相應的參數傳遞給該函數。在DSS中,使用角色(Role)這個術語來描述特定的任務。Dispatch函數的格式如下所示:

  void MyModuleDispatch(QTSS_Role inRole,QTSS_RoleParamPtr inParams);

  其中MyModuleDispatch是Dispatch函數的名稱;MyModule是模塊的文件名;inRole是角色的名稱,只有註冊了該角色的模塊才會被調用;inParams則是一個結構體,可用於傳遞相應的參數。

流媒體技術筆記(DarwinStreamingServer相關)