2014-03-02 89 views
-1

我想模擬一個使用C++在graphedt中創建的工作過濾器圖。Filtergraph生成空文件

這是過濾器圖表: enter image description here

這是我的代碼產生一個空的輸出文件。

#include <dshow.h> 
#include "MyFilter.h" 

IPin *GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir) 
{ 
    BOOL  bFound = FALSE; 
    IEnumPins *pEnum; 
    IPin  *pPin; 

    pFilter->EnumPins(&pEnum); 
    while (pEnum->Next(1, &pPin, 0) == S_OK) 
    { 
     PIN_DIRECTION PinDirThis; 
     pPin->QueryDirection(&PinDirThis); 
     if (bFound = (PinDir == PinDirThis)) 
      break; 
     pPin->Release(); 
    } 
    pEnum->Release(); 
    return (bFound ? pPin : 0); 
} 
int CALLBACK WinMain(
    _In_ HINSTANCE hInstance, 
    _In_ HINSTANCE hPrevInstance, 
    _In_ LPSTR lpCmdLine, 
    _In_ int nCmdShow 
    ) 
{ 
    //INIT GRAPH 
    CoInitialize(NULL); 

    IGraphBuilder* graphBuilder = NULL; 
    IMediaControl* mediaControl = NULL; 
    IMediaEvent* mediaEvent = NULL; 

    HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IFilterGraph, (void **)&graphBuilder); 

    graphBuilder->QueryInterface(IID_IMediaControl, (void **)&mediaControl); 
    graphBuilder->QueryInterface(IID_IMediaEvent, (void **)&mediaEvent); 


    //SOURCE FILTER 
    IBaseFilter* pSource; 

    graphBuilder->AddSourceFilter(L"C:\\TEMP\\Zim.avi", NULL, &pSource); 


    IPin* sourceOUT = GetPin(pSource, PINDIR_OUTPUT); 

    //AVI SPLITTER 

    IBaseFilter* aviSplitter = NULL; 

    hr = CoCreateInstance(CLSID_AviSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&aviSplitter); 

    IPin* aviSplitIN = GetPin(aviSplitter, PINDIR_INPUT); 
    IPin* aviSplitOUT = GetPin(aviSplitter, PINDIR_OUTPUT); 

    graphBuilder->AddFilter(aviSplitter, L"AVI_SPLITTER"); 

    graphBuilder->Connect(sourceOUT, aviSplitIN); 

    //AVI MUX 

    IBaseFilter* decompressor = NULL; 
    hr = CoCreateInstance(CLSID_AviDest, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&decompressor); 
    graphBuilder->AddFilter(decompressor, L"Decoder"); 

    IPin* decoderIN = GetPin(decompressor, PINDIR_INPUT); 
    IPin* DecoderOUT = GetPin(decompressor, PINDIR_OUTPUT); 

    graphBuilder->Connect(aviSplitOUT, decoderIN); 

    //File Writer 
    IBaseFilter *filewriter = NULL; 
    IFileSinkFilter* filesink = NULL; 

    hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&filewriter); 

    filewriter->QueryInterface(IID_IFileSinkFilter, (void **)&filesink); 
    graphBuilder->AddFilter(filewriter, L"Filewriter"); 
    IPin* filewriterIN = GetPin(filewriter, PINDIR_INPUT); 
    graphBuilder->Connect(DecoderOUT, filewriterIN); 

    filesink->SetFileName(L"C:\\TEMP\\myfilteroutput123.avi", NULL); 

    hr = mediaControl->Run(); 
    if (SUCCEEDED(hr)) 
    { 
     long evCode; 
     mediaEvent->WaitForCompletion(INFINITE, &evCode); 
    } 

    CoUninitialize(); 

} 

編輯:這些問題似乎是,avisplitter只返回一個引腳(輸入引腳)。但我不知道爲什麼或如何添加輸出引腳。

+1

您的代碼不會添加AVI多路複用器,也不會生成您想要的圖形。你也應該檢查返回的值,因爲大概最後一個'Connect'會讓你失敗。 –

回答

0

自從我做了DirectShow以來,它已經有一段時間了,但是我似乎記得,在連接至少一個輸入引腳之前,AVI分配器沒有輸出引腳。

這樣的嘗試執行以下操作:

IPin* aviSplitIN = GetPin(aviSplitter, PINDIR_INPUT); 

graphBuilder->AddFilter(aviSplitter, L"AVI_SPLITTER"); 
graphBuilder->Connect(sourceOUT, aviSplitIN); 

IPin* aviSplitOUT = GetPin(aviSplitter, PINDIR_OUTPUT); 

我敢肯定預期,將工作。

作爲進一步的觀點,總是得到並檢查HRESULT s。 HRESULTConnect返回將告訴你很多關於你正在遭受的錯誤。在通過NULL引腳的情況下,您將得到一個E_POINTER錯誤,這可以幫助您更快地將其關聯起來!