我正在使用Viveks捕获过滤器和vlc(http://tmhare.mvps.org/downloads/vcam.zip)来模拟捕获源。当过滤器打开并关闭vlc时,我遇到了崩溃。堆栈跟踪指示仍然存在2个COM对象(我猜测过滤器和引脚)应该在CoUninitialize调用之前释放。我的问题是我不知道在哪里释放过滤器并固定COM对象,我有一个用于fitler和pin的析构函数但是当vlc关闭时它们永远不会被调用。有类似问题的人(Unreleased DirectShow CSource filter makes program crash at process shutdown)。
这是dll的重要注册部分。
STDAPI RegisterFilters( BOOL bRegister )
{
HRESULT hr = NOERROR;
WCHAR achFileName[MAX_PATH];
char achTemp[MAX_PATH];
ASSERT(g_hInst != 0);
if( 0 == GetModuleFileNameA(g_hInst, achTemp, sizeof(achTemp)))
return AmHresultFromWin32(GetLastError());
MultiByteToWideChar(CP_ACP, 0L, achTemp, lstrlenA(achTemp) + 1,
achFileName, NUMELMS(achFileName));
hr = CoInitialize(0);
if(bRegister)
{
hr = AMovieSetupRegisterServer(CLSID_VirtualCam, L"Virtual Cam", achFileName, L"Both", L"InprocServer32");
}
if( SUCCEEDED(hr) )
{
IFilterMapper2 *fm = 0;
hr = CreateComObject( CLSID_FilterMapper2, IID_IFilterMapper2, fm );
if( SUCCEEDED(hr) )
{
if(bRegister)
{
IMoniker *pMoniker = 0;
REGFILTER2 rf2;
rf2.dwVersion = 1;
rf2.dwMerit = MERIT_DO_NOT_USE;
rf2.cPins = 1;
rf2.rgPins = &AMSPinVCam;
hr = fm->RegisterFilter(CLSID_VirtualCam, L"Virtual Cam", &pMoniker, &CLSID_VideoInputDeviceCategory, NULL, &rf2);
}
else
{
hr = fm->UnregisterFilter(&CLSID_VideoInputDeviceCategory, 0, CLSID_VirtualCam);
}
}
// release interface
//
if(fm)
fm->Release();
}
if( SUCCEEDED(hr) && !bRegister )
hr = AMovieSetupUnregisterServer( CLSID_VirtualCam );
CoFreeUnusedLibraries();
CoUninitialize();
return hr;
}
STDAPI DllRegisterServer()
{
return RegisterFilters(TRUE);
}
STDAPI DllUnregisterServer()
{
return RegisterFilters(FALSE);
}
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
}
重要的过滤器部分
CVCamStream::CVCamStream(HRESULT *phr, CVCam *pParent, LPCWSTR pPinName) :
CSourceStream(NAME("Virtual Cam"),phr, pParent, pPinName), m_pParent(pParent)
{
// Set the default media type as 320x240x24@15
GetMediaType(4, &m_mt);
}
CVCamStream::~CVCamStream()
{
m_pParent->Release();
}
答案 0 :(得分:0)
泄露的COM参考文献有点难以确定。假设COM客户端 - 在您的情况下是VLC - 正在做一切正确(可能不是这种情况,但可以从这个假设开始),问题在于您的代码。它通常是两者中的一个:
Release
AddRef
之前完成正如您已经看到有两个对象浮动,一个好的策略是确定它们究竟是哪些类,并跟踪引用计数器更改以查看丢失的IUnknown::Release
。