基於DirectShow的流媒體解碼和回放

來源:互聯網
上載者:User
一、 前言

  流媒體的定義很廣泛,大多數時候指的是把連續的影像和聲音資訊經過壓縮處理後放上網站伺服器,讓使用者一邊下載一邊觀看、收聽,而不需要等整個壓縮檔下載到自己機器就可以觀看的視頻/音頻傳輸、壓縮技術。流媒體也指代由這種支援人員的某種特定檔案格式:壓縮流式檔案,它通過網路傳輸,並通過個人電腦軟體進行解碼。

  MCI是微軟為Windows最初提出的多媒體編程介面,隨著多媒體技術的迅速發展,各種壓縮演算法在該領域的的應用,MCI技術越來越顯的力不從心,最明顯的是它不支援可變位元速率的壓縮演算法,對於處理DVD等近年出現的多種新的媒體格式已顯得無能為力,而使用微軟提供的vfw之類的多媒體庫又太麻煩。怎麼辦呢?
作為MCI的"接班人",微軟又適時推出了建立在DirectX(包含DirectDraw、DirectSound、Direct3D)之上的DirectShow技術,它是在DirectX之上的媒體層,支援來自本地或網路的各種視頻、音頻壓縮格式的媒體檔案的解碼和回放,可以從裝置上捕捉多媒體流,也可以處理各種壓縮演算法處理的流媒體。這些格式包括:MPEG的音頻和視頻標準、音頻和視頻互動標準(AVI)、WAVE、MIDI和進階系統格式 (ASF)ASF。DirectShow對媒體資料處理採用流媒體(Multimedia Stream)的方式,在應用中使用該方式可以大大的減少編程的複雜程度,同時又可以自動協商從資料來源到應用的轉換,流介面提供了統一的、可以預測的資料存取的控制方法,這樣應用程式在播放媒體資料時不需要考慮它最初的來源和格式。
 
  二、理解DirectX

  DirectX是一個用於多媒體應用程式和硬體增強編程環境,它是微軟為了將其Windows建設成適應各種多媒體的最好平台而開發設計的。DirectX目前已經成為微軟自身SDK的一部分,而Windows 98/Windows 2000內則整合了DirectX,表明它已成為作業系統的一部分。

  DirectX技術是一種API(應用程式介面),每個DirectX組件都是使用者可調用的API的總和,通過它應用程式可以直接存取電腦的硬體。這樣,應用程式就可以利用硬體加速器(Hardware Accelerator)。如果硬體加速器不能使用,DirectX還可以模擬加速器以提供強大的多媒體環境。

  為了理解DirectX,我們可以把系統分為四層:

  ●硬體/網路層:放置有多媒體裝置,包括圖形加速器、音效卡、輸入裝置以及網路通訊裝置等;

  ●DirectX基礎層:為映像、聲音和裝置提供多媒體基本服務;

  ●DirectX媒體層:為動畫製作、音頻和視頻等提供API功能;

  ●組件層:包括ActiveX控制和應用,它利用DirectX的API功能的優勢為使用者提供多媒體服務。

  DirectShow就是建立在DirectX媒體層之上的技術,其前身是ActiveMovie2.0。它以一組API函數或ActiveX控制項出現,用途是讓開發人員能夠在網路上傳遞高品質的音頻和視頻訊號。值得一提的是,DirectShow為我們提供了一個開放式的開發環境,我們可以根據自己的需要定製組件。

  三、DirectShow技術結構

  DirectShow定義了如何利用標準組件來處理流媒體資料,這些組件稱為過濾器。過濾器帶有輸入、輸出針角(pin),或二者兼而有之。在DirectShow技術中處於最核心位置的就是作為"過濾器"的可插入標準組件,它是執行特定任務的COM對象。過濾器又可被細分為源過濾器(Source filter)、變換過濾器(Transform filter)、表現過濾器(Renderer filter)等。過濾器通過向檔案讀寫、修改資料和顯示資料到輸出裝置上來操作流媒體。為了完成整個任務,必須要將所有的過濾器Filter串連起來,這三種過濾器組成了過濾器圖表結構,3.1所示:


圖3.1 過濾器圖表結構(Filter Graph)

  從圖3.1中可以看出,過濾器圖表是各種過濾器的集合,它是通過過濾器的輸入輸出針腳"pin"順序串連而成的,這些過濾器的針腳通過協商來決定它們將支援何種形式多媒體。由於DirectShow支援可重構的過濾器圖表結構,所以使用相同的軟體組件可以播放多種類型的媒體。開發人員可以通過定義自己的過濾器來擴充DirectShow對媒體的支援功能。

  在過濾器圖表結構中,源過濾器用來從資料來源擷取資料,並將資料傳送到過濾器圖表中,這裡的資料來源可以是攝像機、網際網路、磁碟檔案等;轉換過濾器用來擷取、處理和傳送媒體資料,它包括分離視頻和音訊分解變換過濾器(Splitter transform filter)、解壓視頻資料的視頻轉換過濾器(Video transform filter)、解壓音頻資料的音頻轉換過濾器(Audio transform filter);表現過濾器用來在硬體上表現媒體資料,如顯卡和音效卡,或者是任何可以接受媒體資料的地方,如磁碟檔案。它包括用來顯示映像的視頻表現過濾器(Video renderer filter)、將音頻資料送到音效卡上去的音頻表現過濾器(Audio renderer filter)。

  在過濾器圖表中,為了完成特定的任務,必須將所有需要的過濾器串連起來,因此前級過濾器的輸出必定成為下級過濾器的輸入。一個過濾器至少有一個輸入針(Input pin),並將特定的輸出送到輸出針(Output pin);圖3.2顯示了一個過濾器串連圖:


3.2 過濾器串連圖

  你的應用程式不需要對過濾器圖表中的各個過濾器進行單獨的處理,因為在更高的層次上,DirectShow提供的一個稱為過濾圖表管理器的組件(FGM)管理著這些過濾器的串連和流媒體資料在過濾器之間的流動,FGM提供了一套COM介面,應用程式可以通過它來訪問過濾器圖表、控制流程媒體或者接收過濾器事件。如果需要,它可以自動的插入一個合適的解碼器,並將轉換過濾器的輸出針腳串連到表現過濾器。應用程式可以通過與過濾圖表管理器的通訊來控制過濾器圖表的活動。程式開發人員只需要調用API函數來實現對流媒體的控制,如run方法啟動流媒體在過濾器圖表(Filter graph)中的流動;pause方法暫停流媒體的播放;stop方法停止播放流媒體等。

  另外,利用Filter Graph Manager能夠將事件資訊傳送到應用程式層這一特點,可以使應用程式可以響應事件處理,例如播放或搜尋流媒體中的特定時間段的資料、流結束資訊等。

  圖3.3是一個MPEG解碼播放的執行個體,可以看出Source filter將擷取的多媒體資料通過Outpin送到MPEG分解轉換過濾器,MPEG分解轉換過濾器有一個輸入針腳,兩個輸出針角分別將視頻和音頻解釋碼器進行解碼,最後兩路資料分別通過視頻表示過濾器、音頻表示過濾器送到顯卡和音效卡進行回放。


圖3.3 MPEG解碼執行個體

四、DirectShow程式開發

  DirectShow建立在COM組件技術基礎上,所以開發DirectShow程式必須要掌握COM組件技術。DirectShow與COM緊密相連,它所有的組件和功能都由COM介面來構造和實現,其開發方式相當靈活,沒有固定的模式,通常隨不同的需要使用不同的COM介面。但是其中幾個重要的介面確實經常需要用到的:IGraphBuilder介面,這是最為重用的COM介面,用來建立Filter Graph Manager;IMediaControl介面,用來控制流程媒體在濾波器圖表(Filter Graph)中的流動,例如流媒體的啟動和停止;IMediaEvent介面,該介面在Filter Graph發生一些事件時用來建立事件的標誌資訊並傳送給應用程式。

  一個典型的DirectShow應用程式的開發通常遵循的步驟為:

  1)通過API函數CoCreateInstance()建立一個Filter Graph Manager 執行個體;

  2)通過調用QueryInterface ( )函數來擷取Filter Graph 和IMediaEvent組件的指標;

  3)對Filter Graph進行控制和對事件作出響應。

  下面舉一個簡單的例子來說明如何利用DirectShow技術對多媒體流進行解碼回放的。首先產生一個名為MediaPlay的單文檔應用程式,定義一個名字為MediaPlay的函數,該函數的具體實現代碼為:

void PlayMovie(LPTSTR lpszMovie)
{
 IMediaControl *pMC = NULL;
 IGraphBuilder *pGB = NULL;
 IMediaEventEx *pME = NULL;
 long eVCode; // something to hold a returned event code
 hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
 IID_IMediaControl, (void **)&pMC);
 hr = pMC->QueryInterface(IID_IGraphBuilder, (void **)&pGB);
 hr = pMC->QueryInterface(IID_IMediaEventEx, (void **)&pME);
 hr = pGB->RenderFile(lpszMovie, NULL);
 hr = pMC->Run();
 hr = pME->WaitForCompletion(INFINITE, &evCode);
 if(pMC)pMC->Release();
  if(pGB)pGB->Release();
   if(pME)pME->Release();
}

  上述代碼中,CoCreateInstance()函數建立了一個過濾器圖表(Filter Graph)對象,並返回一個媒體控制(ImediaControl)介面,這個介面通過過濾器來實現播放、暫停、停止等媒體放映功能,但是這時候圖表對象並不包含具體的過濾器,因為此時DirectX並不清楚需要播放何種類型的媒體;接下來建立一個圖表構建介面,該介面可以實現建立過濾器圖表、向圖表對象添加、刪除各種過濾器、列舉當前過濾器圖表中所有的過濾器、連通圖對象中的各個過濾器等功能;本例中使用了IGraphBuilder 介面的RenderFile()函數,告訴DirectX需要播放的媒體檔案名,此時IgraphBuilder對象介面根據多媒體檔案的類型,自動向過濾器圖表添加播放該類型媒體所需的的各種過濾器,並實現其串連。

  最後,函數調用ImediaControl介面對象的Run()函數,就可以開始播放媒體檔案了。為了實現從頭至尾的順序播放完多媒體檔案,需要調用IMediaEventEx 對象介面的WaitForCompletion()阻塞函數的運行,直到媒體檔案結束後才可以釋放對象、結束函數的運行。

相關關鍵詞:
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.