伍開勝 羅 宇 劉 斌
(西華師范大學(xué)計算機(jī)學(xué)院,四川 南充637000)
隨著信息技術(shù)的發(fā)展,多媒體播放器迎來新的挑戰(zhàn)。在多媒體應(yīng)用技術(shù)中,對多媒體大量的數(shù)據(jù)傳輸、高效的數(shù)據(jù)處理、音視頻流的同步、媒體流的格式轉(zhuǎn)換,一直是需要解決的主要問題,怎樣使流媒體的處理變得簡單而富有成效逐漸成為了焦點(diǎn)問題。而選擇一種合適的應(yīng)用方案,將事半功倍。
本文以微軟的Visual C++作為開發(fā)工具,以Directshow為框架設(shè)計一個能播放RMVB,MP4,AVI等常見格式的播放器。
在DirectShow中,一個應(yīng)用程序必須實例化一個或者多個過濾器,并將它們連接起來.所有這些過濾器和它們之間的連接被稱為過濾器圖表(FilterGraph)。應(yīng)用程序通過過濾器圖表管理器(Filter Graph Manager)來創(chuàng)建相應(yīng)的Filter Graph.其中,Filter Graph Manager也是個COM組件,它為應(yīng)用程序提供了建立Filter Graph的各種方法,控制著FilterGraph的運(yùn)行。
DirectShow是基于模塊化,每個功能模塊都采取COM組件方式,稱為過濾器(Filter)。Directshow提供了一部分標(biāo)準(zhǔn)的過濾器可直接使用,開發(fā)者也可開發(fā)自己的功能Filter來擴(kuò)展Directshow的應(yīng)用。下面用一個簡單的小例子來說明如何使用Filter來播放一個格式為AVI的視頻文件。
(1)先從文件中讀取AVI數(shù)據(jù),形成字節(jié)流(由源Filter完成這一步驟)。
(2)檢查AVI數(shù)據(jù)流的頭格式,然后通過AVI分割Filter將視頻流和音頻流分離。
(3)根據(jù)數(shù)據(jù)壓縮格式的不同,選取不同的decoder Filter對視頻進(jìn)行解碼。
(4)使用Renderer Filter重畫視頻圖像。
(5)音頻流送到聲卡進(jìn)行播放,一般采用缺省的DirectSound DeviceFilter。
圖1中的箭頭表示Filter鏈表中的數(shù)據(jù)流的方向。在DirectShow中,像上面的這樣一個Filter鏈表我們稱為Filter Graph。Filter一般分為下面幾種類型。
(1)源過濾器(Source Filter):源過濾器引入數(shù)據(jù)到過濾器圖中,數(shù)據(jù)來源可以是文件、網(wǎng)絡(luò)、照相機(jī)等。不同的源過濾器處理不同類型的數(shù)據(jù)源。
(2)變換過濾器(Transform Filter):變換過濾器的工作是獲取輸入流,處理數(shù)據(jù),并生成輸出流。變換過濾器對數(shù)據(jù)的處理包括編解碼、格式轉(zhuǎn)換、壓縮解壓縮等。
(3)提交過濾器(Renderer Filter):提交過濾器在過濾器圖里處于最后一級,它們接收數(shù)據(jù)并把數(shù)據(jù)提交給外設(shè)。
Filter有三種狀態(tài):運(yùn)行、暫停、停止,F(xiàn)ilter Graph中所有的Filter的狀態(tài)的改變都是統(tǒng)一的,所以Filter Graph也有運(yùn)行,停止,暫停三種狀態(tài)。
(1)播放器基本功能:播放、暫停、停止;
(2)實現(xiàn)解碼回放有關(guān)的功能:如拖動進(jìn)度條,調(diào)節(jié)播放進(jìn)度;
(3)截圖功能:抓取圖片并保存為一個本地的位圖;
(4)聲音、聲道控制:調(diào)節(jié)音量、調(diào)整音道功能。
按照播放器的功能,將播放器模塊進(jìn)行劃分,得到系統(tǒng)的功能結(jié)構(gòu)圖如下:
媒體播放器的定位接口的獲取、全屏實現(xiàn)、音量控制和靜音設(shè)置關(guān)鍵代碼實例。
首先獲取Filter Graph的各個控制接口,查詢接口函數(shù)的代碼如下:
//得到播放器控制接口、定位接口等
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);
//得到音頻相關(guān)接口
hr|= mGraph->QueryInterface (IID_IBasicVideo, (void **)&mBasicVideo);
//得到音頻相關(guān)接口
hr|= mGraph->QueryInterface (IID_IBasicAudio, (void **)&mBasicAudio);
{
mSeeking->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);
}
return SUCCEEDED(hr);
圖1 播放AVI文件的過濾器圖管理器
圖2
}
return false;
}
//設(shè)置視頻窗口并設(shè)置消息通知窗口
mFilterGraph->SetDisplayWindow(mVideoWindow.GetSafeHwnd());
mFilterGraph->SetNotifyWindow(this->Get SafeHwnd());
獲取聲音控制接口指針mBasicAudio,聲音大小控制函數(shù):
bool CDXGraph::SetAudioVolume(long inVolume)
{
if(mBasicAudio)
{
HRESULT hr=mBasicAudio->put_Volume(inVolume);
return SUCCEEDED(hr);
}
return false;
}
進(jìn)行靜音設(shè)置:
void CSimplePlayerDlg::OnMute()
{
m_bMute=!m_bMute;
//當(dāng)播放鏈路存在時,設(shè)置是否靜音
if(mFilterGraph){
if(m_bMute)
mFilterGraph->SetAudioVolume(VOLUME_MUTE);
else
mFilterGraph->SetAudioVolume(VOLUME_NORMAL);
}
//播放鏈路尚未建立時,設(shè)置是否靜音(isInitedSilence在播放按鈕響應(yīng)函數(shù)中使用,指示初次播放是否靜音)
else
{
if(m_bMute)
{
isInitedSilence=0;
}
else
{
isInitedSilence=1;
}
}
通過QueryInterfaces函數(shù)獲取IVideoWindow視頻窗口控制接口,根據(jù)傳入的布爾值,設(shè)置為全屏播放文件(在全屏模式下,按ESC將恢復(fù)到正常模式)。
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系統(tǒng)自帶的Media Player進(jìn)行測試,測試視頻為BBC記錄片《美麗中國》的發(fā)行版,分辨率為1024*576,該紀(jì)錄片是第一部表現(xiàn)中國野生動植物和自然人文景觀的大型電視紀(jì)錄片,從一個前所未有的角度,向電視觀眾展示中國的魅力。
測試平臺主要配置:
操作系統(tǒng) Windows XP專業(yè)版32位SP3(DirectX 9.0c)
處理器英特爾第二代酷睿i7-2670QM@2.20GHz
內(nèi)存 4 GB(Team DDR3 1333MHz)
顯卡 Nvidia GeForce GT 540M
本播放器基于2002年Microsoft發(fā)布的Directshow SDK 9.0進(jìn)行開發(fā),而測試中使用的2015年編譯的Mplayer和VLC Media Player發(fā)布版本雖然對Intel酷睿2架構(gòu)有更好的支持,更好的利用了最新的SSE4等指令集,OpenGL的功能也很強(qiáng)大,但因為Directshow在windows平臺上的優(yōu)勢,在性能上依然與本設(shè)計存在一定差距。而本播放器因為功能較為精簡的原因,在性能上對同出自于Directshow的Windows Media Player仍有一定優(yōu)勢。
DirectShow提供的良好開發(fā)環(huán)境,使得媒體播放器開發(fā)實現(xiàn)比較方便。本系統(tǒng)采用的是智能連接,只要是曾在系統(tǒng)注冊過的Filter均可以使用,避免了重復(fù)編寫Filter的麻煩,造成代碼的冗余。雖然在性能上相對于同類軟件有一定優(yōu)勢,然而并沒有網(wǎng)絡(luò)功能,這也是今后要探索的方向。
[1]龐然.基于DirectX的音視頻播放器軟件設(shè)計[D].浙江:浙江大學(xué),2006.
[2]趙炯.利用VC_實現(xiàn)基于DirectShow的視頻播放器開發(fā)[J].成都大學(xué)學(xué)報,2011.
[3]路錦正,周冬梅.VisualC++音頻/視頻處理技術(shù)及工程實踐[M].北京:電子工業(yè)出版社,2009.
[4]陸其明.DirectShow開發(fā)指南[M].北京:清華大學(xué)出版社:2003.
[5]張玲玲.VisualC++音頻/視頻技術(shù)開發(fā)與實戰(zhàn)[M].北京:清華大學(xué)出版社,2012.
[6]蒿淑勤.音視頻播放器的開發(fā)大連[D].大連理工大,2010.