我在使用EVR(增强型视频渲染器)的相机应用程序中遇到重要的内存泄漏。当我多次准备,运行,停止和取消准备图表时(每个周期几MB,具体取决于视频分辨率),就会发生泄漏。
我尽可能地简化了代码;你可以在这里下载: https://daptech.box.com/s/6csm91vhcawiw18u42kq
该图表具有视频捕获过滤器,SampleGrabber过滤器和渲染器。连接时,它会创建一个AVI Decompressor过滤器来完成图形。
以下是一些摘录......
声明:
CComPtr<IGraphBuilder> pGraphBuilder;
CComPtr<IBaseFilter> pSource; // The capture device filter
CComPtr<IBaseFilter> pSampleGrabberFilter; // Filter to capture data that flows through the graph
CComPtr<IBaseFilter> pRenderer; // EVR
图表准备(删除验证):
hr = m_p->pGraphBuilder.CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC);
hr = m_p->pSampleGrabberFilter.CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC);
CComQIPtr<ISampleGrabber, &IID_ISampleGrabber> pSampleGrabber(m_p->pSampleGrabberFilter);
hr = pSampleGrabber->SetBufferSamples(FALSE); // Don't copy image data for better performances
// Setup the callback
hr = pSampleGrabber->SetCallback(&m_p->cb, 1); // 0: SampleCB() is called, so that we directly access the buffer. 1: BufferCB() is called. The doc states that the function always makes a copy of the data.
CComPtr<IPin> pSampleGrabberInputPin( FindPin(m_p->pSampleGrabberFilter, PINDIR_INPUT, NULL) );
CComPtr<IPin> pSampleGrabberOutputPin( FindPin(m_p->pSampleGrabberFilter, PINDIR_OUTPUT, NULL) );
hr = m_p->pGraphBuilder->AddFilter(m_p->pSampleGrabberFilter, L"SampleGrabber");
hr = FindVideoCaptureDevice(m_p->pSource, (unsigned)iCameraIndex);
CComPtr<IPin> pSourceOutputPin( FindPin(m_p->pSource, PINDIR_OUTPUT, L"CAPTURE") );
hr = m_p->pGraphBuilder->AddFilter(m_p->pSource, L"Camera");
hr = m_p->pRenderer.CoCreateInstance(CLSID_EnhancedVideoRenderer, NULL, CLSCTX_INPROC);
hr = m_p->pGraphBuilder->AddFilter(m_p->pRenderer, L"Renderer");
hr = ConfigEVR(m_p->pRenderer, m_staticPreview.m_hWnd, uWidth, uHeight);
CComPtr<IPin> pRendererInputPin( FindPin(m_p->pRenderer, PINDIR_INPUT, NULL) );
// Now select the format:
if (!SelectFormat(pSourceOutputPin, uWidth, uHeight, bCompression))
{ MessageBox(L"No appropriate format found.\n"); return; }
// Connection:
hr = m_p->pGraphBuilder->Connect(pSourceOutputPin, pSampleGrabberInputPin);
hr = m_p->pGraphBuilder->Connect(pSampleGrabberOutputPin, pRendererInputPin);
此功能被调用到&#34;无准备&#34;图表:
void FreeDirectShowGraph()
{
if (pSource) DisconnectDownstream(pSource);
RemoveAndRelease(pRenderer);
RemoveAndRelease(pSampleGrabberFilter);
RemoveAndRelease(pSource);
if (pGraphBuilder) pGraphBuilder.Release();
}
任何线索都将不胜感激!