DirectShow 代码在退出后崩溃(PushSourceDesktop 示例)

DirectShow code crashes after exit (PushSourceDesktop sample)

本文关键字:PushSourceDesktop 示例 崩溃 代码 退出 DirectShow      更新时间:2023-10-16

我正在尝试使用SDK(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;
}

最大的问题是,只有在释放所有COM指针之后,您才必须调用CoUninitialize。现在您使用的是原始指针而不是类似CComPtr智能模板,您的代码既可读性差,而且很容易出错并忘记发布其中一个指针。 CoUninitialize清理了东西,然后似乎某个COM对象仍然处于活动状态,它很快就会遇到麻烦并使您的应用程序崩溃。

除此之外,我看不出你有什么理由使用COINIT_MULTITHREADED公寓。为了避免麻烦,您应该对来自 STA 线程的筛选器图进行所有顶级管理。流线程和工作线程将是 MTA,这很好。

ATL提供了 MSDN 上描述良好的CComPtr模板。DirectShow BaseClasses为您提供了一个轻量级的模拟QzCComPtr我建议您开始使用它以方便自己。

您的代码将如下所示:

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

这个想法是所有~CComPtr都是在代码到达CoUninitialize之前完成的。

相关文章:
  • 没有找到相关文章