DirectShow編程(1)- DirectShow介紹

來源:互聯網
上載者:User

    學習DirectShow有一段時間了,把這段學習過程中翻譯出來的SDK與大家分享,同時也希望專家們指出我理解上的錯誤,萬分感謝。
1. DirectShow介紹
    DirectShow是一個windows平台上的流媒體架構,提供了高品質的多媒體流採集和回放功能。它支援多種多樣的媒體檔案格式,包括ASF、MPEG、AVI、MP3和WAV檔案,同時支援使用WDM驅動或早期的VFW驅動來進行多媒體流的採集。DirectShow整合了其它的DirectX技術,能自動地偵測並使用可利用的音視頻硬體加速,也能支援沒有硬體加速的系統。
    DirectShow大大簡化了媒體回放、格式轉換和採集工作。但與此同時,它也為使用者自訂的解決方案提供了底層流量控制架構,從而使使用者可以自行建立支援新的檔案格式或其它用途的DirectShow組件。
    以下是幾個使用DirectShow編寫的典型應用:DVD播放器、視頻編輯應用、AVI到ASF轉換器、MP3播放器和數位視訊採集應用。
    DirectShow是建立在元件物件模型(COM)上的,因此當你編寫DirectShow應用時,你必須具備COM用戶端程式編寫的知識。對於大部分的應用,你不需要實現自己的COM對象,DirectShow提供了大部分你需要的DirectShow組件,但是假如你需要編寫自己的DirectShow組件,你還需要具備編寫COM組件的知識。
1.1. DirectShow支援的格式
    DirectShow是一個開放的架構,因此只要有合適的filter來分析和解碼,它可以支援任何格式。DirectShow預設支援以下的檔案類型和壓縮格式:
    註:打*號的需要Windows Media Format SDK支援
    檔案類型:
      Windows Media? Audio (WMA)*
      Windows Media? Video (WMV)*
      Advanced Systems Format (ASF)*
      Motion Picture Experts Group (MPEG)
      Audio-Video Interleaved (AVI)
      QuickTime (version 2 and lower)
      WAV
      AIFF
      AU
      SND
      MIDI
    壓縮格式:
      Windows Media Video*
      ISO MPEG-4 video version 1.0*
      Microsoft MPEG-4 version 3*
      Sipro Labs ACELP*
      Windows Media Audio*
      MPEG Audio Layer-3 (MP3) (decompression only)
      Digital Video (DV)
      MPEG-1 (decompression only)
      MJPEG
      Cinepak
    微軟自己沒有提供MPEG2解碼器,一些可用的DirectShow MPEG2硬體或軟體解碼器是由第三方提供的。
1.2. 常見問題集(摘錄)
1.2.1. 一般問題

    *DirectShow支援哪些作業系統?
      DirectShow支援Windows9X、Windows2000、Windows Me和Windows XP。
   
    *使用DirectShow需要多少COM知識?
      應用程式開發人員只需要基本的COM組件知識:執行個體化COM組件、調用介面、管理介面的引用計數。Filter開發人員則需要更多。
     
    *有與DirectShow相容的硬體列表(HCL)嗎?
      沒有。如果硬體相容DirectShow,DirectShow會使用它們,如果沒有相容的硬體,DirectShow使用GDI繪製視頻,以及使用WaveOut系列多媒體API來播放音頻。
     
    *可以使用哪些語言來編寫DirectShow應用?
      DirectShow主要為C/C++開發設計。Visual Basic只能使用其中的很小一部分。可以通過MS JScript或VB Script來支援基於指令碼的DVD和TV應用。也可能用Delphi來編寫,但SDK文檔不提供這方面的內容。
     
    *DirectShow會通過Managed 程式碼實現嗎?
      目前還沒有這個計劃。DirectX SDK提供了有限的使用音視頻回放類的託管回放功能,你可以使用COM interop建立Managed 程式碼的DirectShow用戶端應用,但是因為效能上的原因,不推薦建立運行在CLR上的filter。

    *DirectShow開發需要什麼樣的編譯器
      任何能夠產生COM對象的編譯器都可以。
     
    *DirectShow和DirectX的其它組件的關係
      DirectShow和DirectX的其它組件在內部進行聯絡。DirectShow在硬體的支援下使用DirectSound和DirectDraw。Video Renderer和Overlay Mixer使用DirectDraw 3和DirectDraw5表面(surfaces)。Video Mixing Renderer 7(只支援WINXP)使用DirectDraw7表面。Video Mixing Renderer 9使用最新的(目前是Directx9)Direct3D API函數。即便是某個應用程式套件組合含了DirectX其它組件,你也不必使用其它組件的API去編寫它。參考SDK的例子:Texture3D Sample。
     
    *DirectShow與ActiveMovie的關係?
      ActiveMovie是DirectShow原來的名稱,現已不再使用,但是一部分API仍保留了"AM"的首碼,比如AM_MEDIA_TYPE和IAMVideoAccelerator。
     
    *DirectShow是限於多媒體應用嗎?
      DirectShow預設包含的組件主要是為音視頻流設計的,但是,DirectShow架構已經成功地用於其它資料流的解決方案中。
     
    *GraphEdit工具有源碼嗎?GraphEdit.exe是否可再發布?
      沒有源碼,不可再發布。
     
    *DMO可以代替DirectShow filter嗎?
      在編寫編碼器、解碼器、效果器應用時,鼓勵用DMO代替DirectShow filter。在其它的應用中,使用DirectShow filter可能會比較合適。
     
1.2.2. 程式編寫問題
    *如何設定編譯環境,需要哪些標頭檔和庫?
      參考"設定編譯環境"章節
     
    *GraphEdit列示了很多沒有文檔支援的filter,它們都是些什嗎?
      GraphEdit枚舉了所有作為filter類型註冊在系統中的filter,包括由第三方應用程式安裝的filter,以及其它微軟技術如Windows Media或NetMeeting安裝的,另外,一些DirectShow filter被用來做寫入程式碼或硬解碼驅動的外殼。Microsoft H.263 Video Codec用於NetMeeting,不再被DirectShow支援。
   
    *如何知道DirectShow已經被安裝?
      調用CoCreateInstance建立一個Filter Graph Manager執行個體,如果成功,表示DirectShow已經被安裝,下面是一個例子:

      IGraphBuilder *pGraph;

       HRESULT hr = CoCreateInstance(CLSID_FilterGraph,
             NULL, CLSCTX_INPROC_SERVER,
             IID_IGraphBuilder, (void **) &pGraph);

           
    *如果不通過屬性設定頁來更改filter的設定?
      當然是通過filter提供的介面羅。如果沒有提供,就沒有辦法啦
     
    *DirectShow能通知應用程式當前回放位置嗎?
      不提供回調來通知位置,需要使用一個計時器定時調用IMediaSeeking::GetCurrentPosition方法來得到當前回放位置。
     
    *filter運行在哪個特權層級下?
      運行在Ring 3特權層級下,某些流量控制驅動(如音視頻採集驅動)運行在Ring 0特權層級下。
     
    *需要一個Kernel調試器嗎?
      這依據具體的項目。安裝DirectX調試執行階段程式庫(DirectX debug runtime library)意味著安裝調試驅動(Debug driver)和其它核心組件(kernel mode component),因此如果你的應用程式在其中的某個組件中產生了一個調試斷言(debug assert),你的機器就會自動重啟除非你擁有一個kernal調試器。
     
    *DEFINE_GUID宏是怎麼工作的?
      使用DEFINE_GUID宏可以讓你通過包含同一個標頭檔來定義GUID值而不必使用extern關鍵詞。比如,你的工程中有三個源檔案:src1.cpp,src2.cpp,src3.cpp,它們都使用一個相同的GUID值,而為了保證一致性,這個GUID只能在你的工程中定義一次,這時,其它的源檔案必須定義外部參考來使用它。用了DEFINE_GUID,你可以使用在所有源檔案中包含同一個標頭檔,在標頭檔中這樣定義GUID:

    DEFINE_GUID(CLSID_MyObject,
         0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);

            這個例子中GUID為0,實際編程中請用Guidgen工具來產生一個GUID,在其中的一個源檔案中,在你的標頭檔前包含initguid.h,如:

  // Src1.cpp
 #include
 #include "MyGuids.h"
 
 // Src2.cpp
 #include "MyGuids.h"

 // Src3.cpp
 #include "MyGuids.h"

      
 在沒有包含Initguid.h的地方,DEFINE_GUID宏建立外部參考來使用GUID值,在包含Initguid.h的地方,DEFINE_GUID重定義DEFINE_GUID宏以產生GUID的定義。
 如是沒有在任何地方添加Initguid.h,你會得到一個連結錯誤:"unresolved external symbol." ,如果同樣的GUID包含Initguid.h兩次,會得到編譯錯誤"redefinition; multiple initialization."要解決這些問題,請確認Initguid.h只包含一次。同樣的,不要包含Initguid.h到先行編譯標頭檔中去,因為先行編譯標頭檔會被每個源檔案包含。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.