Your SlideShare is downloading. ×
Introduction To Direct Show
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Introduction To Direct Show

3,518
views

Published on

Published in: Technology, Business

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,518
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
99
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Introduction to DirectShow Qing qing@cs.nthu.edu.tw (Email/MSN) 2007/1/12
  • 2. 何謂 DirectShow ?
    • DirectShow 是 DirectX 家族中的一支
    • 除了 DirectShow 之外, DirectShow 尚包括了
      • DirectPlay
      • DirectDraw
      • Direct3D
      • DirectMusic
    • DirectShow 的用途在於多媒體資訊的呈現
      • 視訊
      • 音訊
  • 3. DirectShow 的應用範圍
    • 多媒體訊息的輸入
      • 麥克風
      • 攝影機
      • 檔案
      • 網路串流
    • 多媒體訊息的剖析
    • 多媒體訊息的編碼,解碼
    • 多媒體訊息的撥放
      • 音訊視訊呈現
    • 多媒體訊息的儲存
  • 4. 使用 DirectShow 必備
    • C/C++/VB/C#
    • Windows COM 元件的使用
  • 5. DirectShow 架構的優點
    • 元件化,可重用性高
      • 各種用途的元件,都化身為標準的 Filter ,具備相同的介面,容易搭接各式 Filter
    • 極具彈性,透過對 Filter 的客製及組裝,可以達成各式的目的
  • 6. DirectShow 核心元件
    • IFilterGraph
      • 每個撥放結構都是用一個 IFilterGraph 所描述
    • IGraphBuilder
      • 建立 、 控制 IFilterGraph 的元件
    • IBaseFilter
      • DirectShow 中所有的 Filter 都實作的介面
    • IPin
      • 代表多媒體訊息在 IFilterGraph 中流動的接腳
      • 每個 IBaseFilter 都有一個以上的 IPin
    • IMediaControl
      • 控制多媒體訊息撥放行為的元件
    • IMediaEvent
      • 取得多媒體訊息撥放時的事件
  • 7. 一個最簡單的 DirectShow 範例 ( DSFilePlayer.cpp)
    • 目的:從檔案執行撥放指定的多媒體檔案
    • 步驟:
      • 初始化 COM
      • 建立 IFilterGraph 的 instance
      • 取得 IMediaControl 的介面( IFilterGraph 實作了 IMediaControl 的介面)
      • 取得 IMediaEvent ( IFilterGraph 實作了 IMediaEvent 的介面)
      • 透過 IMediaControl 智慧型的建立 Filter Graph 的內容
      • 透過 IMediaControl 啟動撥放
      • 透過 IMediaEvent 等待撥放結束
  • 8. 初始化 COM
    • HRESULT hr;
    • hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    • if( FAILED(hr) )
    • {
    • CoUninitialize();
    • return hr;
    • }
  • 9. 建立 IFilterGraph 的 instance
    • IFilterGraph *pFilterGraph = NULL;
    • //
    • hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,IID_IFilterGraph, (void**) &pFilterGraph);
  • 10. 取得 IMediaControl/IMediaEvent 的介面
    • IMediaControl *pMC = NULL;
    • IMediaEvent *pME = NULL;
    • hr = pFilterGraph->QueryInterface(IID_IMediaControl, (void **) &pMC);
    • if( FAILED(hr) )
    • {
    • return hr;
    • }
    • hr = pFilterGraph->QueryInterface(IID_IMediaEvent, (void **) &pME);
    • if( FAILED(hr) )
    • {
    • pFilterGraph->Release();
    • pMC->Release();
    • return hr;
    • }
  • 11. 建立 Filter Graph/ 撥放 / 等待停止
    • OAEVENT oEvent;
    • hr = pME->GetEventHandle(&oEvent);
    • if( SUCCEEDED(hr) )
    • {
    • hr = pMC-> RenderFile (fileName);
    • if( SUCCEEDED(hr) )
    • {
    • hr = pMC-> Run ();
    • if( SUCCEEDED(hr) )
    • {
    • LONG levCode;
    • hr = pME-> WaitForCompletion (INFINITE, &levCode);
    • }
    • }
    • }
  • 12. 何謂 Filter Graph ? *Render WMV9 時會自動建立的 Filter Graph *Render MPEG 時會自動建立的 Filter Graph Output Pin Input Pin 分流 Renderer Source Filter Splitter
  • 13. 何謂 Filter ?
    • 一個 Filter 具備一個以上的 Pin
    • Pin 依多媒體訊息流動的方向可分為 Input Pin 或 Output Pin
    • Filter 的 Input Pin ,代表對此 Filter 是訊息流入的 Pin
    • Filter 的 Outut Pin ,代表對此 Filter 是訊息流出的 Pin
  • 14. 何謂 Pin
    • Pin 是 DirectShow 中多媒體訊息藉以流經的元件
    • Pin 是 DirectShow 中,兩個 Filter 相接的介面
    • 每個 Pin 都有可以接受的 Media Type
      • 每個 Media Type 都有一個 major type
        • 例如 MEDIATYPE_Video 或 MEDIATYPE_Audio
      • 每個 Media Type 都有一個 minor type
        • 例如 MEDIASUBTYPE_RGB32
    • 在 Filter Graph 中要接在一起的兩個 Filter ,其中一個的 Output Pin 可接受的 media type 必須和另一個 Filter 的 Input Pin 可接受的 media type 相符
  • 15. Filter Graph 的建立
    • 智慧型連接需要的 Filter
    • 手動建立
      • 自己產生所需的各種 Filter
      • 依據需求把要連接在一起的兩兩 Filter 接在一起
        • 把 Filter A 的 Output Pin 接到 Filter B 的 Input Pin
  • 16. 如何開始 DirectShow 應用程式的開發
    • 安裝 SDK
      • DirectX SDK ,或
      • Platform SDK
    • 將 SDK 的 include 目錄加至 Visual Studio 的 include 目錄中
    • 將 SDK 的 lib 目錄加至 Visual Studio 的 lib 目錄中
    • build DirectX SDK 中附的 DirectShow BaseClasses
      • 例: DirectX 9.0
      • DXSDKSamplesC++DirectShowBaseClasses
    • 產生 BaseClassesDebugstrmbasd.lib ( debug mode 用)
    • 產生 BaseClassesReleasestrmbase.lib ( release mode 用)
  • 17. 如何設定 DirectShow 應用程式的專案
    • 在專案設定中設定 C/C++ 及 Linker 的選項
    • C/C++
      • General
        • Additional Include Directories ,加上: BaseClasses
      • Preprocessor
        • Preprocessor Definitions ,加上: _WIN32_DCOM
    • Linker
      • General
        • Additional Library Directories ,加上: BaseClassesDebug 或 BaseClassesRelease (視 debug mode 或 release 而定,加上這兩個目錄的原因是要將 Input 中指定的 strmbasd.lib 或 strmbase.lib 加入)
      • Input
        • Additional Dependencies ,加上: strmbasd.lib (或 strmbase.lib ,視 debug mode 或 release 而定) winmm.lib
  • 18. BaseClasses 及 DirectShow 範例
    • 雖然 BaseClasses 被放在 DirectShow 的範例程式中,但其實提供了對於 DirectShow COM 介面的高階實作
    • 基於 BaseClasses ,繼承其類別,對於實作 DirectShow 中的各式 Filter 有相當大的幫助
    • 在撰寫各式 Filter 時,建議參考 DirectShow 中的範例程式
      • 例: DirectX 9.0
      • DXSDKSamplesC++DirectShowFilters
  • 19. 範例程式中示範的基本 Filter 類型 (1/2)
    • Async : Pull mode 的 Source Filter
      • Source Filter 是提供多媒體訊息的 Filter (起點)
      • Pull Source Filter 是基於另一 Filter 的 Input Pin 的請求,將資料餵至自己的 Output Pin
    • Dump : Renderer Filter
      • Renderer Filter 是負責呈現多媒體訊息的 Filter (終點)
    • EZRGB24 : Image Processing Filter
      • 針對多媒體訊息進行加工的 Filter
    • Grabber : SampleGrabber Filter
      • 擷錄 Filter Graph 中流動的多媒體訊息用的 Filter
  • 20. 範例程式中示範的基本 Filter 類型 (2/2)
    • INFTee : Infinite Pin Tee Filter
      • Tee Fitler 是分接用的 Filter ,例如一個輸出 Pin 變成兩個輸出 Pin ,將多媒體訊息複製成多份,提供給後續的多個 Filter
      • INFTee 可將一個 Input Pin 的內容,複製至不限個數的 Output Pin
    • NullInPlace : In-Place Transform Filter
      • 於原地(不配置額外的記憶體)處理多媒體訊息的 Filter
    • NullNull : Minimal Null Filter
      • 示範最小的 Filter
    • PushSource : Push Source Filter
      • Push Source Filter 是自己主動將資料餵至自己的 Output Pin 的 Filter
  • 21. 多媒體呈現應用時常用到的 Push Source Filter
    • QPushSource 是一個通用的範例
    • 參考 QPushSource.cpp, QPushSource.h, QPushSourceGuids.h
    • 繼承後覆寫,或直接改寫 QPushSourceStream 的
      • HRESULT GetMediaType(CMediaType *pMediaType)
      • HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest)
    • 改寫
      • CLSID_QPushSource
  • 22. HRESULT GetMediaType(CMediaType *pMediaType)
    • 當兩個 Pin 之間做連接的動作時,會呼叫 GetMediaType() 判斷兩 Filter 是否能夠相接
      • 取決在回傳的 pMediaType 是否相容
    • 如何改寫 GetMediaType() ?
      • 根據你的 Push Source Filter 會回傳的多媒體類型,適時的填入
      • 例如產生 RGB32 的 Video 訊息
      • pMediaType->SetType(& MEDIATYPE_Video);
      • pMediaType->SetSubtype(& MEDIASUBTYPE_RGB32);
      • pvi->bmiHeader.biCompression = BI_RGB;
      • pvi->bmiHeader.biBitCount = 32;
  • 23. HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest)
    • Push Source Filter 的下游 Filter 會呼叫 DecideBufferSize() 來得知究竟應該準備多大的 buffer 空間來接收 Push Source Filter 傳入的資料
    • 例如,對 640x480 的 RGB32 資料來說:
      • pRequest->cbBuffer = 640*480*4;
  • 24. 如何使用 QPushSource
    • 產生 QPushSource 的 instance
      • pPushSource = (QPushSource*) QPushSource::CreateInstance(NULL, &hr);
    • 由 QPushSource 的 Output Pin 開始 Render FilterGraph
  • 25. 使用 QPushSource 的步驟
    • 設定或繼承並覆寫 QPushSourceStream::GetMediaType
      • 指定正確的 Media Type 及 Format
    • 設定或繼承並覆寫 QPushSourceStream::DecideBufferSize
      • 指定足夠大的 buffer 大小
    • 修改範例 main.cpp 中的 HowToAddANewFrame() ,把多媒體訊息加入至 QPushSource 中的 queue
  • 26. main.cpp: 示範如何運用 QPushSource
    • // 初始化 COM
    • CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    • // 產生 QPushSource 的 instance
    • pPushSource = (QPushSource*) QPushSource::CreateInstance(NULL, &hr);
    • // 從 QPushSource 開始 Render 整個 Filter Graph
    • hr = RenderSourceFilter(pPushSource, &pFilterGraph);
    • // 啟動 Filter Graph 的運作,並等待結束
    • hr = RunGraphAndWaitFormCompletion(pFilterGraph);
  • 27. Q&A Thanks