基於DIRECTSHOW平台的視頻程式開發

來源:互聯網
上載者:User

1)directshow初識(2009.12.05)

建立DirectShow應用程式步驟:

第一步,首先,需要調用CoInitialize來作初始化,然後調用CoCreateInstance建立Filter Graph Manager:

 HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
      return;
    }
    IGraphBuilder *pGraph;
    HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);

  類別識別項(CLSID)是CLSID_FilterGraph。Filter Graph Manager由進程內DLL(in-process DLL)提供,因此參數3,dwClsContext的值為CLSCTX_INPROC_SERVER。由於DirectShow運行自由線程模式(free-threading model),所以你同樣可以使用COINIT_MULTITHREADED參數來調用CoInitializeEx

PS:HRESULT 是一種簡單的資料類型,通常被屬性和 ATL 用作傳回值。

下表說明各種不同的值。標頭檔 winerror.h 中包含更多的值。

  名稱 說明 值

  S_OK 操作成功 0x00000000

  E_UNEXPECTED 意外的失敗 0x8000FFFF

  E_NOTIMPL 未實現 0x80004001

  E_OUTOFMEMORY 未能分配所需的記憶體 0x8007000E

  E_INVALIDARG 一個或多個參數無效 0x80070057

  E_NOINTERFACE 不支援此介面 0x80004002

  E_POINTER 無效指標 0x80004003

  E_HANDLE 無效控制代碼 0x80070006

  E_ABORT 操作已中止 0x80004004

  E_FAIL 未指定的失敗 0x80004005

  E_ACCESSDENIED 一般的訪問被拒絕錯誤 0x80070005

  不能簡單地把傳回值與 S_OK 和 S_FALSE 比較,而要用 SUCCEEDED 和 FAILED 宏進行判斷。

第二步,建立filter graph

調用CoCreateInstance得到的IGraphBuilder介面包含了大部分建立filter graph的方法。在這個例子中還需要另外兩個介面:IMediaControl和IMediaEvent。IMediaControl控制資料流,它包含開啟和停止graph的方法;IMediaEvent包含從Filter Graph Manager擷取事件的方法,在這個例子中,這個介面用來得到回放結束事件。所有這些介面由Filter Graph Manager提供,使用得到的IGraphBuiler介面指標來查詢得到。

    IMediaControl *pControl;
    IMediaEvent   *pEvent;
    hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
    hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

第三步,建立filter graph

對於檔案回放只需要一個簡單的調用:

 hr = pGraph->RenderFile(L"C://Example.avi", NULL);

 IGraphBuilder::RenderFile方法建立了一個能夠播放指定檔案的filter graph,事實上,原本需要做的一些如建立filter執行個體及將這些filter串連起來的工作,都由這個方法自動完成了,如果是視頻檔案,這個filter graph看起來應該是這個樣子:
    ->[如果是縮格式,這裡是個解碼器]->[Video Renderer]
要開始回放,調用IMediaControl::Run方法:

     hr = pControl->Run();

當filter graph運行時,資料經過各個filter最後回放為視頻或音頻。回放發生在一個單獨的線程中。你可以通過調用IMediaEvent::WaitForCompletion方法來等待回放的結束:

    long evCode = 0;
    pEvent->WaitForCompletion(INFINITE, &evCode);

  上面這個方法在播放期間被阻塞,直至播放結束或逾時。
  當應用程式結束時,需要釋放介面指標並關閉COM庫:

    pControl->Release();
    pEvent->Release();
    pGraph->Release();
    CoUninitialize();

建立簡單的directshow播放程式過程的完整代碼如下所示:

#include <dshow.h>
void main(void)
{
    IGraphBuilder *pGraph = NULL;
    IMediaControl *pControl = NULL;
    IMediaEvent   *pEvent = NULL;

 

    // Initialize the COM library.
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
        printf("ERROR - Could not initialize COM library");
        return;
    }

 

    // Create the filter graph manager and query for interfaces.
    hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
    if (FAILED(hr))
    {
        printf("ERROR - Could not create the Filter Graph Manager.");
        return;
    }

    hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
    hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

 

    // Build the graph. IMPORTANT: Change this string to a file on your system.
    hr = pGraph->RenderFile(L"C://Example.avi", NULL);
    if (SUCCEEDED(hr))
    {
        // Run the graph.
        hr = pControl->Run();
        if (SUCCEEDED(hr))
        {
            // Wait for completion.
            long evCode;
            pEvent->WaitForCompletion(INFINITE, &evCode);

            // Note: Do not use INFINITE in a real application, because it
            // can block indefinitely.
        }
    }
    pControl->Release();
    pEvent->Release();
    pGraph->Release();
    CoUninitialize();
}

PS:

1.這裡所使用的fiter graph manag構建graph filter採用igraphbuilder::renderfile方法構建一個完成的檔案回放graph

2.該程式只支援.avi格式視頻播放,只有播放直至結束的回放功能。

 

二 VS2005 C++ 項目添加“依賴”、“庫目錄”和“包含目錄”2009-12-08
1. 添加編譯所需要(依賴)的 lib 檔案

“項目->屬性->配置屬性->連接器->輸入->附加依賴項”裡填寫“winsock.lib”,多個 lib 以空格隔開。
(等同於“#pragma comment(lib, "winsock.lib") ”語句)

2. 添加庫(Libs)檔案目錄

方法 1“項目->屬性->配置屬性->連接器->常規->附加庫目錄”
方法 2:[菜單]“工具->選項->項目和解決方案->C++ 目錄”,選擇對應平台,然後添加所需“庫檔案”目錄

3. 添加包含(include)檔案目錄

方法 1:[方案總管]“項目->屬性->配置屬性->C/C++->常規->附加元件封裝含目錄”
方法 2:[菜單]“工具->選項->項目和解決方案->C++ 目錄”,選擇對應平台,然後添加所需“包括檔案”目錄

 

聯繫我們

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