伍開勝 羅 宇 劉 斌
(西華師范大學計算機學院,四川 南充637000)
隨著信息技術的發展,多媒體播放器迎來新的挑戰。在多媒體應用技術中,對多媒體大量的數據傳輸、高效的數據處理、音視頻流的同步、媒體流的格式轉換,一直是需要解決的主要問題,怎樣使流媒體的處理變得簡單而富有成效逐漸成為了焦點問題。而選擇一種合適的應用方案,將事半功倍。
本文以微軟的Visual C++作為開發工具,以Directshow為框架設計一個能播放RMVB,MP4,AVI等常見格式的播放器。
在DirectShow中,一個應用程序必須實例化一個或者多個過濾器,并將它們連接起來.所有這些過濾器和它們之間的連接被稱為過濾器圖表(FilterGraph)。應用程序通過過濾器圖表管理器(Filter Graph Manager)來創建相應的Filter Graph.其中,Filter Graph Manager也是個COM組件,它為應用程序提供了建立Filter Graph的各種方法,控制著FilterGraph的運行。
DirectShow是基于模塊化,每個功能模塊都采取COM組件方式,稱為過濾器(Filter)。Directshow提供了一部分標準的過濾器可直接使用,開發者也可開發自己的功能Filter來擴展Directshow的應用。下面用一個簡單的小例子來說明如何使用Filter來播放一個格式為AVI的視頻文件。
(1)先從文件中讀取AVI數據,形成字節流(由源Filter完成這一步驟)。
(2)檢查AVI數據流的頭格式,然后通過AVI分割Filter將視頻流和音頻流分離。
(3)根據數據壓縮格式的不同,選取不同的decoder Filter對視頻進行解碼。
(4)使用Renderer Filter重畫視頻圖像。
(5)音頻流送到聲卡進行播放,一般采用缺省的DirectSound DeviceFilter。
圖1中的箭頭表示Filter鏈表中的數據流的方向。在DirectShow中,像上面的這樣一個Filter鏈表我們稱為Filter Graph。Filter一般分為下面幾種類型。
(1)源過濾器(Source Filter):源過濾器引入數據到過濾器圖中,數據來源可以是文件、網絡、照相機等。不同的源過濾器處理不同類型的數據源。
(2)變換過濾器(Transform Filter):變換過濾器的工作是獲取輸入流,處理數據,并生成輸出流。變換過濾器對數據的處理包括編解碼、格式轉換、壓縮解壓縮等。
(3)提交過濾器(Renderer Filter):提交過濾器在過濾器圖里處于最后一級,它們接收數據并把數據提交給外設。
Filter有三種狀態:運行、暫停、停止,Filter Graph中所有的Filter的狀態的改變都是統一的,所以Filter Graph也有運行,停止,暫停三種狀態。
(1)播放器基本功能:播放、暫停、停止;
(2)實現解碼回放有關的功能:如拖動進度條,調節播放進度;
(3)截圖功能:抓取圖片并保存為一個本地的位圖;
(4)聲音、聲道控制:調節音量、調整音道功能。
按照播放器的功能,將播放器模塊進行劃分,得到系統的功能結構圖如下:
媒體播放器的定位接口的獲取、全屏實現、音量控制和靜音設置關鍵代碼實例。
首先獲取Filter Graph的各個控制接口,查詢接口函數的代碼如下:
//得到播放器控制接口、定位接口等
bool CDXGraph::QueryInterfaces(void)
{
if(mGraph)
{
HRESULT hr=NOERROR;
//得到播放控制接口
hr|=mGraph ->QueryInterface (IID_IMediaControl,(void**)&mMediaControl);
//得到媒體事件接口
hr|= mGraph->QueryInterface (IID_IMediaEventEx,(void**)&mEvent);
//得到視頻窗口接口
hr|=mGraph ->QueryInterface (IID_IVideoWindow,(void**)&mVideoWindow);
//得到音頻相關接口
hr|= mGraph->QueryInterface (IID_IBasicVideo, (void **)&mBasicVideo);
//得到音頻相關接口
hr|= mGraph->QueryInterface (IID_IBasicAudio, (void **)&mBasicAudio);
{
mSeeking->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);
}
return SUCCEEDED(hr);

圖1 播放AVI文件的過濾器圖管理器

圖2
}
return false;
}
//設置視頻窗口并設置消息通知窗口
mFilterGraph->SetDisplayWindow(mVideoWindow.GetSafeHwnd());
mFilterGraph->SetNotifyWindow(this->Get SafeHwnd());
獲取聲音控制接口指針mBasicAudio,聲音大小控制函數:
bool CDXGraph::SetAudioVolume(long inVolume)
{
if(mBasicAudio)
{
HRESULT hr=mBasicAudio->put_Volume(inVolume);
return SUCCEEDED(hr);
}
return false;
}
進行靜音設置:
void CSimplePlayerDlg::OnMute()
{
m_bMute=!m_bMute;
//當播放鏈路存在時,設置是否靜音
if(mFilterGraph){
if(m_bMute)
mFilterGraph->SetAudioVolume(VOLUME_MUTE);
else
mFilterGraph->SetAudioVolume(VOLUME_NORMAL);
}
//播放鏈路尚未建立時,設置是否靜音(isInitedSilence在播放按鈕響應函數中使用,指示初次播放是否靜音)
else
{
if(m_bMute)
{
isInitedSilence=0;
}
else
{
isInitedSilence=1;
}
}
通過QueryInterfaces函數獲取IVideoWindow視頻窗口控制接口,根據傳入的布爾值,設置為全屏播放文件(在全屏模式下,按ESC將恢復到正常模式)。
bool CDXGraph::SetFullScreen(BOOL inEnabled)
{
if(mVideoWindow)
{
HRESULT hr= mVideoWindow->put_FullScreenMode
(inEnabled?OATRUE:OAFALSE);
return SUCCEEDED(hr);
}
return false;
}
選取了兩款開源視頻播放器Mplayer,VLC Media Player還有Windows系統自帶的Media Player進行測試,測試視頻為BBC記錄片《美麗中國》的發行版,分辨率為1024*576,該紀錄片是第一部表現中國野生動植物和自然人文景觀的大型電視紀錄片,從一個前所未有的角度,向電視觀眾展示中國的魅力。
測試平臺主要配置:
操作系統 Windows XP專業版32位SP3(DirectX 9.0c)
處理器英特爾第二代酷睿i7-2670QM@2.20GHz
內存 4 GB(Team DDR3 1333MHz)
顯卡 Nvidia GeForce GT 540M
本播放器基于2002年Microsoft發布的Directshow SDK 9.0進行開發,而測試中使用的2015年編譯的Mplayer和VLC Media Player發布版本雖然對Intel酷睿2架構有更好的支持,更好的利用了最新的SSE4等指令集,OpenGL的功能也很強大,但因為Directshow在windows平臺上的優勢,在性能上依然與本設計存在一定差距。而本播放器因為功能較為精簡的原因,在性能上對同出自于Directshow的Windows Media Player仍有一定優勢。
DirectShow提供的良好開發環境,使得媒體播放器開發實現比較方便。本系統采用的是智能連接,只要是曾在系統注冊過的Filter均可以使用,避免了重復編寫Filter的麻煩,造成代碼的冗余。雖然在性能上相對于同類軟件有一定優勢,然而并沒有網絡功能,這也是今后要探索的方向。
[1]龐然.基于DirectX的音視頻播放器軟件設計[D].浙江:浙江大學,2006.
[2]趙炯.利用VC_實現基于DirectShow的視頻播放器開發[J].成都大學學報,2011.
[3]路錦正,周冬梅.VisualC++音頻/視頻處理技術及工程實踐[M].北京:電子工業出版社,2009.
[4]陸其明.DirectShow開發指南[M].北京:清華大學出版社:2003.
[5]張玲玲.VisualC++音頻/視頻技術開發與實戰[M].北京:清華大學出版社,2012.
[6]蒿淑勤.音視頻播放器的開發大連[D].大連理工大,2010.