摘要:我們基于DirectShow技術實現了一套網絡媒體點播系統,該系統使用私有的傳輸協議和播放器,包含媒體點播、用戶認證與計費等基本功能。該文簡單介紹了DirectShow技術,并主要就播放器架構和傳輸協議進行了敘述。
關鍵詞:DirectShow;視頻點播;過濾器;.Net框架;傳輸協議
中圖分類號:TP302文獻標識碼:A文章編號:1009-3044(2010)02-426-03
VOD System Base on DirectShow Technology
CHEN Zhi-xin1, JIA Bo2
(1.Information and Network Center, Hunan Normal University, Changsha 410006, China; 2.College of Mathematics and Computer Sciences, Hunan Normal University, Changsha 410006, China)
Abstracts: Based on DirectShow technology, we achieve a Video-on-demand system, the system uses proprietary protocol and player, including the media file playback, user authentication and billing and other basic functions. This paper briefly describes the DirectShow technology and focuses on the player architecture and delivery protocol.
Key words: directShow; VOD; filter; .Net framework; delivery protocol
DirectShow是微軟公司提供的一套軟件開發包,用于在Windows系統下開發多媒體應用程序。同DirectX軟件包中的其他組件一樣,DirectShow提供一套API,使得開發人員在編寫應用程序時無需考慮硬件平臺的差異,實現高效的音視頻采集、編碼、解碼和播放,極大的降低了應用程序的復雜度和開發人員的工作量。DirectShow是基于Com的。
DirectShow在工作時就像一個電路板。電路板在設計時將所需的芯片鑲嵌在載板上,并將芯片的針腳按照特定的方式予以連接,就能實現特定的功能;DirectShow應用程序中的Filter Graph就像載板,添加的Filter就像芯片,而Pin則是Filter的針腳,Filter通過Pin連接起來之后就能接受Filter Graph的控制,實現需要的功能。GraphEdit是微軟提供的測試DirectShow的工具,下圖清晰的展示了DirectShow如何播放一個視頻文件。
圖1
圖1中的方框都是Filter,突起的部分是Pin,箭頭表示了Pin直接的連接關系。1號Filter是一個Source Filter,用于讀取視頻文件,并將文件的數據提供給2號Filter;2號Filter是一個Splitter,用于分離音視頻數據;3、4分別是音頻解碼器和視頻解碼器;5、6分別是音頻渲染器和視頻渲染器,將信號發送到對應的硬件上,完成播放功能。由此看出,我們要實現網絡媒體的播放功能,可以通過編寫Source Filter來實現。
1 Source Filter的實現
我們參考DirectX SDK中提供的Async Filter示例,該示例實現一個File Source Filter,與系統默認提供的File Source Filter不同的是,該示例需要將媒體文件完全讀取到內存中再進行處理。它主要包含兩個類:
1) CMemStream,繼承自CAsyncStream,實現對內存中數據流的同步隨機訪問。
2) CAsyncFilter,繼承自CAsyncReader并實現IFileSourceFilter接口,其中CAsyncReader是同步讀取數據的Source Filter,而IFileSourceFilter接口使得應用程序可以通過調用Load函數來指定要載入的媒體文件。在Load被調用時,該Filter使用ReadFile函數讀取媒體文件的完整內容,并創建了CMemStream對象,之后對媒體文件的讀取則完全變成了自CMemStream對象的讀取。
對Async Filter進行全面了解后,我們編寫了一個新的Filter以實現播放通用的數據流。具體步驟如下:
1) 定義IStream通用接口,替換了CAsyncStream。該接口包含如下虛方法:① SetPointer,用于定位讀取指針;② Read,用于讀取數據;③ Size,用于獲取數據流的長度;④ Alignment,用于校準;⑤ Lock,以獨占的方式鎖定;⑥ Unlock,解除鎖定。
定義通用接口的目的是為了更好的可擴展性,如果需要讓播放器在將來能夠支持更多的協議,只需編寫實現了IStream接口的數據提供類。
2) 定義IStreamSourceFilter通用接口,用于替換IFileSourceFilter。與IFileSourceFilter一樣包含Load虛方法,不過方法的參數不再是路徑字符串,而是實現了IStream接口的對象指針。
3) 編寫MCFilter,繼承自CAsyncReader,并實現IStreamSourceFilter。
編寫完成之后,按照編譯DirectShow Filter的方法編譯,得到一個ActiveX DLL文件,使用Regsvr32命令注冊之后,就能在其他地方調用了。
2 播放器的實現
為了更方便的編寫應用程序,我們采用了Visual Studio 2008作為開發工具,.Net Framework 2.0作為支撐平臺。由于.Net Framework提供了豐富的類庫和友好的可視化界面設計工具,使得編寫Windows應用程序的工作得到了極大的簡化。但是.Net Framework是運行托管代碼的平臺,并不能直接調用Com類,因此我們還使用了DirectShow.Net軟件包。
DirectShow.Net軟件包是由一位瑞士的軟件工程師編寫,將絕大多數DirectShow中用到的Com類進行了封裝,可以方便的在托管代碼中調用,但是我們自己編寫的Filter顯然不在上述范圍。因此我們改動了DirectShow.Net軟件包的源代碼,增加了對MCFilter的封裝。
播放器開始工作時,創建一個Filter Grap對象,然后檢查播放的URL。如果是本地文件,則直接使用RenderFile方式進行播放。如果是我們定義的網絡協議,則創建一個MCFilter并加入Graph中,根據協議名稱創建對應的IStream對象,然后調用MCFilter的Load方法以形成能夠提供媒體內容的Source Filter并對MCFilter的Pin調用Render方法,從而生成完整的FilterGraph,實現媒體播放。過程如下圖:
圖2
FilterGraph實現了諸多接口,用于實現對多媒體應用程序的控制功能。對于播放器來說,控制媒體播放、音量和視頻展示是主要需要實現的。為此,我們需要使用FilterGraph的以下接口:
1) IMediaEventEx,用于截獲播放中的事件,比如播放開始、結束等。獲取事件的目的是為了更新播放器窗口樣式,比如播放開始后,啟動播放的“Play”按鈕應該變為“Pause”按鈕,以便用戶操作。
2) IMediaControl,該接口包含Run、Stop、Pause三個方法,對應于播放控制的開始、停止和暫停。
3) IMediaPosition,用于獲取或設置媒體播放進度,是實現媒體隨機播放的基礎。
4) IBasicVideo,用于獲取媒體中包含的視頻信息,比如原始視頻尺寸等。
5) IVideoWindow,視頻展示的接口,通過PutOwner方法將視頻畫面展示到特定的窗口中。
6) IBasicAudio,音頻控制接口,主要用于控制音量。
完整的實現一個播放器是很復雜的事情,很多細節功能需要考慮,這里不一一敘述。好用的播放器除了有完善的功能外還需要友好的用戶界面,圖3是我們編寫的播放器運行時的截圖。
3 協議設計
我們設計了一套私有的網絡協議,作為我們媒體點播系統的傳輸協議,協議包含以下部分。
1) 控制元:控制元是表示控制信息的結構體,客戶端與服務器交互的過程中,使用這些控制元來進行通信。不同的控制信息繼承自控制元基類,而包含不同的字段。控制元在網絡中傳輸時,使用XML格式存儲。
2) 數據元:數據元是包含媒體數據的傳輸單元,默認包含32KB的數據。數據元的頭部包含了該數據的偏移量和所屬管道,以便客戶端收到之后重新組成數據流。
3) 狀態元:由于協議要實現的是同步讀取遠程的媒體文件,因此需要使用一種信號來同步服務端與客戶端。狀態元就是起到了同步的作用,它只在客戶端收到數據元后發送給服務端,以標明該數據元已經收到。
4) 投遞包:將控制元、數據元和狀態元封裝在一起生成的數據包,是在底層連接上投遞的基本單位。我們采用TCP協議作為底層協議,因為TCP協議是基于流的,所以我們設計了一個緩沖池,用于從TCP流中解取投遞包。
5) 虛擬管道:為了支持在一個基礎連接上打開多個文件同時進行訪問,我們設計了虛擬管道。客戶端要求打開一個文件時,服務端返回一個管道標示號并與客戶端之間建立虛擬管道。針對每一個虛擬通道,客戶端使用獨立的緩存管理器進行緩存管理。
6) 緩存管理器:緩存管理器附加在虛擬管道,針對該管道進行客戶端方面的緩存管理。緩存器又分為低速緩存區、高速緩存區和永久緩存區三種。低速緩存區用于保存從服務端收到的數據元,它將數據元用鏈表的方式直接保存在內存中,這樣寫入的速度是最快的;高速緩存區使用一段連續的內存空間保存數據流,方便播放器進行讀取;永久緩存區使用的是磁盤空間,這樣可以避免重復的數據投遞。緩存管理器始終監視高速緩存區的狀態,在緩存區不足時掛起播放器的讀取操作,并從低速區或永久區檢索數據予以填充。
圖4和圖5分別表示了協議的層次和協議流程。
4 總結
我們基于DirectShow技術,構建了一套完整的視頻點播系統,已經在我校投入使用。與之前使用的Helix Server相比,我們這套系統有諸多的優勢。由于對媒體文件的解碼是放在客戶端進行的,只要是能在本地播放的文件就可以用于網絡點播,因此能支持幾乎所有的媒體格式;由于系統在進行數據傳輸時是基于緩存來進行帶寬控制的,不同于Helix基于碼率的控制,因此在開始播放和隨機播放時響應時間更短;在播放高碼率媒體文件時,我們的系統具有更高的流暢性。
由于本系統支持IStream通用接口,使得對本系統的擴展十分方便。我們只需要實現一個IStream接口即可使播放器支持新的網絡協議,使得實現在線點播分布式網絡中的媒體文件變得異常簡單。
參考文獻:
[1] 陸其明.DirectShow開發指南[M].北京:清華大學出版社,2004.
[2] Bargen.Inside DirectX[M].Microsoft Press,1998:22-87.
[3] Microsoft Corporation.MSDN Library[M].US: Microsoft Corporation,2001.
[4] 李陶深.DirectShow技術下局域網流媒體系統的設計[J].廣西科學院學報,2007,23(4):297-299.
[5] 黃振宇.基于COM的DirectShow Filter實現[J].微機發展,2004,5(14):114-116.
[6] 張明華.DirectShow中過濾器圖的定制方法及應用[J].計算機工程,2004,4(30):141-143.
[7] 文坤.DirectShow程序設計原理及應用[J].計算機系統應用,2006(3):25-28.
[8] 鐘玉琢.多媒體技術(高級)[M].北京:清華大學出版社,1999.
[9] 李莉.視頻流點播代理緩存管理新策略[J].系統仿真學報,2009,1(21):251-255.
[10] 史翠竹.視頻點播系統中客戶端的緩存管理和碼率控制策略研究[J].計算機工程與應用,2004(7):126-129.
[11] 楊書慧.基于Internet的視頻代理緩存服務器設計的若干關鍵問題[J].計算機科學,2003(30):118-123.