问题描述
我尝试使用SDK(PushSourceDesktop)附带的桌面捕获过滤器。我编译它,似乎使用它成功,因为它实际上捕获我的桌面,并将其保存到一个文件。但应用程序崩溃时,它的完成/退出。
I'm trying to use the Desktop capture filter that comes with the SDK (PushSourceDesktop). I compiled it and seem to use it successfully as it actually captures my desktop and saves it to a file. But the application crashes when its done/exits.
当我断开错误时,它只表示没有源可用,调用堆栈位置是KernelBase.dll!7560280C()。
When I break on the error it only says no source available and the call stack location is KernelBase.dll!7560280C().
我想我在这里给它一个镜头,看看是否有人能认出一些问题,或者如果我做一些明显错误,可能会导致崩溃。提前感谢!
I thought I give it a shot here to see if anyone can recognize some issue or if I am doing something blatantly wrong that might cause the crash. Thanks in advance!
编辑:工作代码
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;
}
推荐答案
/ em>问题是你必须在所有COM指针释放后调用 CoUninitialize
。现在你正在使用原始指针而不是 CComPtr
- 类似的智能模板,你的代码都是可读性差,很容易犯错误,忘记释放一个指针。 CoUninitialize
清理的东西,然后后来似乎一些COM对象仍然活着,它很快陷入麻烦,崩溃了你的应用程序。
The big problem is that you have to call CoUninitialize
only after all COM pointers are released. Now that you are using raw pointers instead of CComPtr
-like smart templates, your code both is poorly readable, and it is so easy to make a mistake and forget to release one of the pointers. CoUninitialize
cleans things up and then later on it appears that some COM object is still alive and it quickly gets into trouble and crashes your app.
除此之外,我没有看到你使用 COINIT_MULTITHREADED
公寓的原因。为了避免麻烦,你应该对STA线程的过滤器图进行所有顶级管理。
Additionally to this, I don't see a reason for you to use COINIT_MULTITHREADED
apartment. To stay away of trouble, you should rather do all top-level management on filter graphs from STA thread. Streaming and worker threads will be MTA, and it is fine.
ATL
提供模板。 DirectShow BaseClasses为您提供一个轻量级的模拟 QzCComPtr
,我建议您开始使用为您自己方便。
ATL
offers CComPtr
templates well described on MSDN. DirectShow BaseClasses offer you a lightweight analog QzCComPtr
which I suggest you start using for your own convenience.
您的代码将如下所示:
CoInitialize(...);
{
CComPtr<IFooA> pFooA;
CComPtr<IFooB> pFooB;
// ...
}
CoUninitialize();
这个想法是所有〜CComPtr
在代码到达 CoUninitialize
之前完成。
The idea is that all ~CComPtr
are done before code reaches CoUninitialize
.
这篇关于退出后DirectShow代码崩溃(PushSourceDesktop示例)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!