Hi,
I think that there is a memory leak when I execute IMFActivate::ActivateObject.
I found that when method IMFActivate::ActivateObject is executed, the inner COM counter is increased on 1, but when I execute IMFActivate::DetachObject() it is not decreased. I wrote simple test for this. When function CreateVideoDeviceSource() is called
with argument activateIMFMediaSource = false method IMFActivate::ActivateObject is not called and Release of IMFActive return 0 - full release and it is OK.
void CreateVideoDeviceSource(bool activateIMFMediaSource) { IMFMediaSource *pSource = NULL; IMFAttributes *pAttributes = NULL; IMFActivate **ppDevices = NULL; HRESULT hr = MFCreateAttributes(&pAttributes, 1); if (FAILED(hr)) { goto done; } hr = pAttributes->SetGUID( MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID ); if (FAILED(hr)) { goto done; } UINT32 count; hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count); if (FAILED(hr)) { goto done; } if (count == 0) { hr = E_FAIL; goto done; } if(activateIMFMediaSource) { for(UINT32 index = 0; index < count; index++) { ULONG eSource = -1; hr = ppDevices[index]->ActivateObject(IID_PPV_ARGS(&pSource)); if (FAILED(hr)) { goto done; } ppDevices[index]->DetachObject(); pSource->Shutdown(); eSource = pSource->Release(); eSource = -1; } } done: ULONG eDevice = -1; for (UINT32 index = 0; index < count; index++) { eDevice = ppDevices[index]->Release(); } CoTaskMemFree(ppDevices); ULONG epAttributes = -1; epAttributes = pAttributes->Release(); epAttributes = -1; return; }
However, when I state argument activateIMFMediaSource = true IMFActive::Release() return 1.
ULONG eDevice = -1; for (UINT32 index = 0; index < count; index++) { eDevice = ppDevices[index]->Release(); }
in funtion it calls IMFActivate::ActivateObject and activate IMFMediaSource. I read about using IMFMediaSource and in function it calls IMFActivate::DetachObject(), IMFMediaSource::Shutdown() and IMFMediaSource::Release().
ULONG eSource = -1; hr = ppDevices[index]->ActivateObject(IID_PPV_ARGS(&pSource)); if (FAILED(hr)) { goto done; } ppDevices[index]->DetachObject(); pSource->Shutdown(); eSource = pSource->Release();
Ans it is OK - eSource has 0 after calling IMFMediaSource::Release(). But inner COM counter IMFActivate is rised on 1 - and I don't know how to resolve it. I tried to call IMFActivate::Release() two times, but it leads to memory leak. I wrote simple
programm - when I call this program with argument function CreateVideoDeviceSource() - true I see on yhe task manager that the size of the memory of progremm rise. When it is called with argument - false - the size of memory is constant.
int _tmain(int argc, _TCHAR* argv[]) { HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (FAILED(hr)) { goto finish; } hr = MFStartup(MF_VERSION); if (FAILED(hr)) { goto finish; } for(int index = 0; index < 100; index++) { CreateVideoDeviceSource(true); Sleep(500); } finish: MFShutdown(); ::CoUninitialize(); return 0; }
I have spent much time on searching info on MSDN, but did not find any resolvig this problem. Please, help with this situation.