2012-06-28 42 views
1

我試圖使用SDK(PushSourceDesktop)附帶的桌面捕獲過濾器。我編譯它,似乎成功地使用它,因爲它實際上捕獲了我的桌面並將其保存到文件中。但是應用程序在完成/退出時會崩潰。退出後DirectShow代碼崩潰(PushSourceDesktop示例)

當我解決錯誤時,它只會說沒有可用的源,調用堆棧位置是KernelBase.dll!7560280C()。

我想我在這裏試試看看是否有人可以識別出某個問題,或者我是否做了可能導致崩潰的明顯錯誤。提前致謝!

編輯:工作代碼

int main() 
{ 

HRESULT hr; 

hr = CoInitialize(NULL); 
{ 
CComPtr<IBaseFilter> pMux; 
CComPtr<IMediaControl> pMC; 
CComPtr<IBaseFilter> pFilterr; 
CComPtr<IGraphBuilder> pGraph; 
CComPtr<ICaptureGraphBuilder2> pBuild; 
CComPtr<IUnknown> pUnk; 

hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, 
    IID_ICaptureGraphBuilder2, (void**)&pBuild); 


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

hr = pBuild->SetFiltergraph(pGraph); 


static CLSID const clsid = {0x4ea6930a, 0x2c8a, 0x4ae6, {0xa5, 0x61, 0x56, 0xe4, 0xb5, 0x4, 0x44, 0x37}}; //Pushsourcedesktop 

hr = CreateObjectFromPath(TEXT("c:\\filters\\PushSource.dll"), clsid, &pUnk); 

pFilterr = pUnk; 

if (SUCCEEDED(hr)) 
{ 
    HRESULT hr = pGraph->AddFilter(pFilterr, L"Private Filter"); 
} 

hr = pBuild->SetOutputFileName(
    &MEDIASUBTYPE_Avi, // Specifies AVI for the target file. 
    L"C:\\wav\\Example2.avi", // File name. 
    (IBaseFilter**)&pMux,    // Receives a pointer to the mux. 
    NULL); 


hr = pBuild->RenderStream(
    NULL,//PIN_CATEGORY_CAPTURE,//NULL,//&PIN_CATEGORY_CAPTURE, // Pin category. 
    NULL,//&MEDIATYPE_Video,//&MEDIATYPE_Interleaved,//NULL,//&MEDIATYPE_Audio,  // Media type. 
    pFilterr,//pSrc,   // Capture filter. 
    NULL,//pCompression2, //pCompression,     // Intermediate filter (optional). 
    (IBaseFilter*)pMux);     // Mux or file sink filter. 


    hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pMC); 
    printf("START"); 


    pMC->Pause(); 
    hr = pMC->Run(); 
    Sleep(4000); 
     hr = pMC->Stop(); 
    printf("END"); 

} 
CoUninitialize(); 
return 0; 
} 

回答

3

的問題是,你必須調用CoUninitialize所有的COM指針被釋放之後。現在你使用的是原始指針而不是類似CComPtr的智能模板,你的代碼的可讀性很差,而且容易犯一個錯誤,並忘記釋放其中一個指針。 CoUninitialize清理了一些東西,然後看起來有些COM對象仍然存在,它很快就會陷入困境並崩潰你的應用程序。

除此之外,我沒有看到你使用COINIT_MULTITHREADED公寓的理由。爲了避免麻煩,您應該對來自STA線程的過濾器圖形執行所有頂級管理。流和工作線程將是MTA,並且沒問題。

ATL優惠CComPtr在MSDN上很好地描述了模板。 DirectShow BaseClass爲您提供輕量級模擬QzCComPtr,我建議您開始使用,以方便您的使用。

您的代碼將是這樣的:

CoInitialize(...); 
{ 
    CComPtr<IFooA> pFooA; 
    CComPtr<IFooB> pFooB; 
    // ... 
} 
CoUninitialize(); 

的想法是,代碼達到CoUninitialize之前的所有~CComPtr完成。

+1

看到我上面的代碼片段。 –

+0

啊,我想我現在明白了,我在代碼中添加了更改。謝謝你澄清那個重要的一點! –