C++ DirectShow手动图形内存泄漏
下面是简单的捕获和渲染图形的手动构建。C++ DirectShow手动图形内存泄漏,c++,directshow,C++,Directshow,下面是简单的捕获和渲染图形的手动构建。 CaptureFilter->SmartTee->(预览)->AVI解压缩器->渲染 所有这些都工作正常,工作时可获得140Mb。 在我停止渲染并释放所有剩余的过滤器和IGraphBuilder 50Mb之后 再次构建相同的过滤器-除ram中的140+50=190Mb外,其他所有功能均可用。 释放后剩余100Mb。 一次又一次。 我尝试了SmartPtr、ComPtr、Release()的任何可以想象的组合,但没有效果。 看来我做错了什么事:( #包括 #
CaptureFilter->SmartTee->(预览)->AVI解压缩器->渲染
所有这些都工作正常,工作时可获得140Mb。
在我停止渲染并释放所有剩余的过滤器和IGraphBuilder 50Mb之后
再次构建相同的过滤器-除ram中的140+50=190Mb外,其他所有功能均可用。
释放后剩余100Mb。
一次又一次。
我尝试了SmartPtr、ComPtr、Release()的任何可以想象的组合,但没有效果。
看来我做错了什么事:(
#包括
#包括
#包括
#包括
#pragma注释(lib,“strmids”)
#定义SafeRelease(Com){if(Com!=nullptr){Com->Release();Com=nullptr;};};
void GetCaptureSource(std::wstring友好名称,IBaseFilter**ppCaptureFilter);
void GetPin(IPin**ppPin,IBaseFilter*pFilter,std::string direction\u str,std::wstring name\u wstr=L“”);
int main()
{
HRESULT hr=共同初始化(0);
//获取捕获过滤器
IBaseFilter*p_CaptureFilter;
GetCaptureSource(L“USB3.0捕获视频”和p_CaptureFilter);
//获取捕获Pin码
IPin*p_CaptureOutPin;
GetPin(&p_CaptureOutPin,p_CaptureFilter,“out”);
//获取智能T形过滤器
IBaseFilter*p_智能T恤;
hr=CoCreateInstance(CLSID_SmartTee,NULL,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&p_SmartTee));
//获得智能T形别针
IPin*p_智能输入PIN;
GetPin(&p_SmartInputPin,p_SmartTee,“in”);
IPin*p_智能输出PIN;
GetPin(&p_SmartOutputPin,p_SmartTee,“输出”,L“预览”);
//获取解压缩过滤器
IBaseFilter*p_AVI减压器;
hr=CoCreateInstance(CLSID_AVIDec,NULL,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&p_AviDecompressor));
//获取Avi解压缩器引脚
IPin*p_AvInputPin;
GetPin(&p_-AvInputPin,p_-AviDecompressor,“in”);
IPin*p_AviOutputPin;
GetPin(&p_AviOutputPin,p_aviodecompressor,“out”);
//获取视频渲染过滤器
IBaseFilter*p_VideoRender;
hr=CoCreateInstance(CLSID\u VideoRenderer,NULL,CLSCTX\u INPROC\u SERVER,IID\u PPV\u ARGS(&p\u VideoRender));
//获取视频渲染Pin
IPin*p_RenderPin;
GetPin(&p_RenderPin,p_VideoRender,“in”);
//创建过滤器图形管理器。
IGraphBuilder*p_图形生成器;
hr=CoCreateInstance(CLSID_FilterGraph,0,CLSCTX_INPROC_服务器,IID_IGraphBuilder,(void**)和p_GraphBuilder);
//添加捕获过滤器
hr=p_GraphBuilder->AddFilter(p_CaptureFilter,L“CaptureFilter”);
//添加智能T形过滤器
hr=p_GraphBuilder->AddFilter(p_SmartTee,L“SmartTee”);
//添加解压缩过滤器
hr=p_GraphBuilder->AddFilter(p_Avi解压缩器,L“Avi解压缩器”);
//添加视频渲染过滤器
hr=p_GraphBuilder->AddFilter(p_VideoRender,L“视频渲染”);
//连接引脚
hr=p_GraphBuilder->Connect(p_CaptureOutPin,p_SmartInputPin);
hr=p_GraphBuilder->Connect(p_SmartOutputPin,p_AviInputPin);
hr=p_图形生成器->连接(p_AviOutputPin,p_RenderPin);
//获取接口
IVideoWindow*p\u视频窗口;
hr=p_GraphBuilder->QueryInterface(IID_IVideoWindow,(void**)和p_VideoWindow);
IMediaControl*p_MediaControl;
hr=p_GraphBuilder->QueryInterface(IID_IMediaControl,(void**)和p_MediaControl);
//释放所有参考销
安全释放(p_CaptureOutPin);
安全释放(p_SmartInputPin);
安全释放(p_SmartOutputPin);
安全释放(p_AvInputPin);
安全释放(p_AviOutputPin);
安全释放(p_RenderPin);
//释放所有过滤器引用
安全释放(p_CaptureFilter);
安全释放(p_SmartTee);
安全释放(减压器);
安全释放(p_VideoRender);
std::cout Run();
视频窗口->放置标题(L“渲染窗口”);
p_VideoWindow->SetWindowPosition(20、20、1920、1080);
LONG lStyle=GetWindowLong(0,GWL_样式);
lStyle&=~(WS_字幕| WS_厚框| WS_最小化| WS_最大化| WS_系统菜单);
p_VideoWindow->put_WindowStyle(lStyle);
//有窗户,一切都很好
std::cout Stop();
hr=p\u VideoWindow->put\u Visible(假);
hr=p\u VideoWindow->put\u Owner(空);
//安全释放(p_MediaControl);
//安全释放(p_VideoWindow);
安全释放(p_GraphBuilder);
coninitialize();
std::cout Next(1,&p_capturemonike,0);
如果(hr!=S_OK)中断;
IPropertyBag*p_PropBag;
hr=p_CaptureMonike->BindToStorage(0,0,IID_IPropertyBag,(void**)和p_PropBag);
变异变量;
方差(var);
方差线性化(&var);
hr=p_PropBag->Read(L“FriendlyName”,&var,0);
安全释放(p_PropBag);
std::wstring输入\名字对象\友好\名称=std::wstring(var.bstrVal);
if(输入\名字对象\友好\名称==友好\名称){
is_capture_find=真;
hr=p_capturemonike->BindToObject(0,0,IID_IBaseFilter,(void**)ppCaptureFilter);
安全释放(p_CaptureMonike);
打破
}
安全释放(p_CaptureMonike);
}虽然(正确);
如果(is_capture_finded==false)MessageBoxW(0,L“capture NOT founded.”,L“ERROR”,MB_OK);
安全释放(p_输入监视器);
返回;
}
void GetPin(IPin**ppPin,IBaseFilter*pFilter,std::string direction\u str,std::wstring name\u wstr){
HRESULT-hr;
IEnumPins*pEnumPins;
hr=pFilter->EnumPins(&pEnumPins);
做{
IPin*pNextPin;
hr=pEnumPins->Next(1,&pNextPin,0);
如果(hr!=S_OK)中断;
引脚信息引脚信息;
hr=pNextPin->QueryPinInfo(&pin_-inf);
bool是感兴趣的pin=true;
如果((方向str==“in”)&&(pin\u inf.dir==PINDIR\u输出))是感兴趣的pin\u=false;
如果((方向str==“out”)&&(pin\u inf.dir==PINDIR\u INPUT))是感兴趣的pin\u=false;
如果((name_wstr!=L“”)和(&(name_wstr!=std::wstring(pin_inf.achName)))是感兴趣的pin=false;
如果(是否感兴趣){
*ppPin=pNextPin;
安全释放(pNextPin);
打破
}
安全释放(pNextPin);
}虽然(正确);
更安全的
#include <windows.h>
#include <dshow.h>
#include <iostream>
#include <string>
#pragma comment(lib, "strmiids")
#define SafeRelease(Com) {if (Com!=nullptr){Com->Release(); Com=nullptr;};};
void GetCaptureSource(std::wstring friendly_name, IBaseFilter** ppCaptureFilter);
void GetPin(IPin** ppPin, IBaseFilter* pFilter, std::string direction_str, std::wstring name_wstr = L"");
int main()
{
HRESULT hr = CoInitialize(0);
//Get Capture Filter
IBaseFilter* p_CaptureFilter;
GetCaptureSource(L"USB3.0 Capture Video", &p_CaptureFilter);
//Get Capture Pin
IPin* p_CaptureOutPin;
GetPin(&p_CaptureOutPin, p_CaptureFilter, "out");
//Get Smart Tee Filter
IBaseFilter* p_SmartTee;
hr = CoCreateInstance(CLSID_SmartTee, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&p_SmartTee));
//Get Smart Tee Pins
IPin* p_SmartInputPin;
GetPin(&p_SmartInputPin, p_SmartTee, "in");
IPin* p_SmartOutputPin;
GetPin(&p_SmartOutputPin, p_SmartTee, "out", L"Preview");
//Get AviDecompressorFilter
IBaseFilter* p_AviDecompressor;
hr = CoCreateInstance(CLSID_AVIDec, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&p_AviDecompressor));
//Get Avi Decompressor Pins
IPin* p_AviInputPin;
GetPin(&p_AviInputPin, p_AviDecompressor, "in");
IPin* p_AviOutputPin;
GetPin(&p_AviOutputPin, p_AviDecompressor, "out");
//Get Video Render Filter
IBaseFilter* p_VideoRender;
hr = CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&p_VideoRender));
//Get Video Render Pin
IPin* p_RenderPin;
GetPin(&p_RenderPin, p_VideoRender, "in");
// Create the Filter Graph Manager.
IGraphBuilder* p_GraphBuilder;
hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&p_GraphBuilder);
//Add Capture Filter
hr = p_GraphBuilder->AddFilter(p_CaptureFilter, L"CaptureFilter");
//Add Smart Tee Filter
hr = p_GraphBuilder->AddFilter(p_SmartTee, L"SmartTee");
//Add Decompressor Filter
hr = p_GraphBuilder->AddFilter(p_AviDecompressor, L"Avi Decompressor");
//Add Video Render Filter
hr = p_GraphBuilder->AddFilter(p_VideoRender, L"Video Render");
//Connect Pins
hr = p_GraphBuilder->Connect(p_CaptureOutPin, p_SmartInputPin);
hr = p_GraphBuilder->Connect(p_SmartOutputPin, p_AviInputPin);
hr = p_GraphBuilder->Connect(p_AviOutputPin, p_RenderPin);
//Get Interfaces
IVideoWindow* p_VideoWindow;
hr = p_GraphBuilder->QueryInterface(IID_IVideoWindow, (void **)&p_VideoWindow);
IMediaControl* p_MediaControl;
hr = p_GraphBuilder->QueryInterface(IID_IMediaControl, (void **)&p_MediaControl);
//Release all pins references
SafeRelease(p_CaptureOutPin);
SafeRelease(p_SmartInputPin);
SafeRelease(p_SmartOutputPin);
SafeRelease(p_AviInputPin);
SafeRelease(p_AviOutputPin);
SafeRelease(p_RenderPin);
//Release all filter references
SafeRelease(p_CaptureFilter);
SafeRelease(p_SmartTee);
SafeRelease(p_AviDecompressor);
SafeRelease(p_VideoRender);
std::cout << "Press any key to START\n";
std::system("pause");
hr = p_MediaControl->Run();
p_VideoWindow->put_Caption(L"render_window");
p_VideoWindow->SetWindowPosition(20, 20, 1920, 1080);
LONG lStyle = GetWindowLong(0, GWL_STYLE);
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
p_VideoWindow->put_WindowStyle(lStyle);
//There Window apears and ALL GOOD
std::cout << "Press any key to STOP\n";
std::system("pause");
hr = p_MediaControl->Stop();
hr = p_VideoWindow->put_Visible(OAFALSE);
hr = p_VideoWindow->put_Owner(NULL);
//SafeRelease(p_MediaControl);
//SafeRelease(p_VideoWindow);
SafeRelease(p_GraphBuilder);
CoUninitialize();
std::cout << "Press any key to QUIT\n";
std::system("pause");
std::cout << "\n\n";
//system("pause");
return 0;
}
void GetCaptureSource(std::wstring friendly_name, IBaseFilter** ppCaptureFilter) {
HRESULT hr;
ICreateDevEnum* devs;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, 0, CLSCTX_INPROC, IID_ICreateDevEnum, (void **)&devs);
IEnumMoniker* p_InputMonikersEnum;
hr = devs->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &p_InputMonikersEnum, 0);
SafeRelease(devs);
bool is_capture_finded = false;
do {
IMoniker* p_CaptureMoniker;
hr = p_InputMonikersEnum->Next(1, &p_CaptureMoniker, 0);
if (hr != S_OK) break;
IPropertyBag* p_PropBag;
hr = p_CaptureMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&p_PropBag);
VARIANT var;
VariantInit(&var);
VariantClear(&var);
hr = p_PropBag->Read(L"FriendlyName", &var, 0);
SafeRelease(p_PropBag);
std::wstring input_moniker_friendly_name = std::wstring(var.bstrVal);
if (input_moniker_friendly_name == friendly_name) {
is_capture_finded = true;
hr = p_CaptureMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)ppCaptureFilter);
SafeRelease(p_CaptureMoniker);
break;
}
SafeRelease(p_CaptureMoniker);
} while (true);
if (is_capture_finded == false) MessageBoxW(0, L"Capture NOT founded.", L"ERROR", MB_OK);
SafeRelease(p_InputMonikersEnum);
return;
}
void GetPin(IPin** ppPin, IBaseFilter* pFilter, std::string direction_str, std::wstring name_wstr) {
HRESULT hr;
IEnumPins* pEnumPins;
hr = pFilter->EnumPins(&pEnumPins);
do {
IPin* pNextPin;
hr = pEnumPins->Next(1, &pNextPin, 0);
if (hr != S_OK) break;
PIN_INFO pin_inf;
hr = pNextPin->QueryPinInfo(&pin_inf);
bool is_pin_of_interest = true;
if ((direction_str == "in") && (pin_inf.dir == PINDIR_OUTPUT)) is_pin_of_interest = false;
if ((direction_str == "out") && (pin_inf.dir == PINDIR_INPUT)) is_pin_of_interest = false;
if ((name_wstr != L"") && (name_wstr != std::wstring(pin_inf.achName))) is_pin_of_interest = false;
if (is_pin_of_interest) {
*ppPin = pNextPin;
SafeRelease(pNextPin);
break;
}
SafeRelease(pNextPin);
} while (true);
SafeRelease(pEnumPins);
return;
}
#include <windows.h>
#include <dshow.h>
#include <iostream>
#include <string>
#pragma comment(lib, "strmiids")
#define SafeRelease(Com) {if (Com!=nullptr){Com->Release(); Com=nullptr;};};
void GetCaptureSource(std::wstring friendly_name, IBaseFilter** ppCaptureFilter);
void GetPin(IPin** ppPin, IBaseFilter* pFilter, std::string direction_str, std::wstring name_wstr = L"");
int main()
{
HRESULT hr = CoInitialize(0);
//Get Capture Filter
IBaseFilter* p_CaptureFilter;
GetCaptureSource(L"USB3.0 Capture Video", &p_CaptureFilter);
//Get Capture Pin
IPin* p_CaptureOutPin;
GetPin(&p_CaptureOutPin, p_CaptureFilter, "out");
//Get Smart Tee Filter
IBaseFilter* p_SmartTee;
hr = CoCreateInstance(CLSID_SmartTee, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&p_SmartTee));
//Get Smart Tee Pins
IPin* p_SmartInputPin;
GetPin(&p_SmartInputPin, p_SmartTee, "in");
IPin* p_SmartOutputPin;
GetPin(&p_SmartOutputPin, p_SmartTee, "out", L"Preview");
//Get AviDecompressorFilter
IBaseFilter* p_AviDecompressor;
hr = CoCreateInstance(CLSID_AVIDec, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&p_AviDecompressor));
//Get Avi Decompressor Pins
IPin* p_AviInputPin;
GetPin(&p_AviInputPin, p_AviDecompressor, "in");
IPin* p_AviOutputPin;
GetPin(&p_AviOutputPin, p_AviDecompressor, "out");
//Get Video Render Filter
IBaseFilter* p_VideoRender;
hr = CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&p_VideoRender));
//Get Video Render Pin
IPin* p_RenderPin;
GetPin(&p_RenderPin, p_VideoRender, "in");
// Create the Filter Graph Manager.
IGraphBuilder* p_GraphBuilder;
hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&p_GraphBuilder);
//Add Capture Filter
hr = p_GraphBuilder->AddFilter(p_CaptureFilter, L"CaptureFilter");
//Add Smart Tee Filter
hr = p_GraphBuilder->AddFilter(p_SmartTee, L"SmartTee");
//Add Decompressor Filter
hr = p_GraphBuilder->AddFilter(p_AviDecompressor, L"Avi Decompressor");
//Add Video Render Filter
hr = p_GraphBuilder->AddFilter(p_VideoRender, L"Video Render");
//Connect Pins
hr = p_GraphBuilder->Connect(p_CaptureOutPin, p_SmartInputPin);
hr = p_GraphBuilder->Connect(p_SmartOutputPin, p_AviInputPin);
hr = p_GraphBuilder->Connect(p_AviOutputPin, p_RenderPin);
//Get Interfaces
IVideoWindow* p_VideoWindow;
hr = p_GraphBuilder->QueryInterface(IID_IVideoWindow, (void **)&p_VideoWindow);
IMediaControl* p_MediaControl;
hr = p_GraphBuilder->QueryInterface(IID_IMediaControl, (void **)&p_MediaControl);
//DONT RELEASE IPINS REFERENSES!!!!!!!!
//IT CAUSE ERROR WHEN YOU TRY TO RELEASE FILTERS OR GRAPH WERY LATER
//AND WILL BE WERY HARD TO FIND IT
//p_CaptureOutPin->Release();
//p_SmartInputPin->Release();
//p_SmartOutputPin->Release();
//p_AviInputPin->Release();
//p_AviOutputPin->Release();
//p_RenderPin->Release();
//Release all filter references
p_CaptureFilter->Release();
p_SmartTee->Release();
p_AviDecompressor->Release();
p_VideoRender->Release();
std::cout << "Press any key to START\n";
std::system("pause");
hr = p_MediaControl->Run();
p_VideoWindow->put_Caption(L"render_window");
p_VideoWindow->SetWindowPosition(20, 20, 1920, 1080);
LONG lStyle = GetWindowLong(0, GWL_STYLE);
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
p_VideoWindow->put_WindowStyle(lStyle);
//There Window apears and ALL GOOD
std::cout << "Press any key to STOP\n";
std::system("pause");
hr = p_MediaControl->Stop();
hr = p_VideoWindow->put_Visible(OAFALSE);
hr = p_VideoWindow->put_Owner(NULL);
// Enumerate the filters in the graph.
IEnumFilters *pEnum = NULL;
hr = p_GraphBuilder->EnumFilters(&pEnum);
do {
IBaseFilter *pFilter = NULL;
hr = pEnum->Next(1, &pFilter, NULL);
if (hr != S_OK) break;
// Remove the filter.
p_GraphBuilder->RemoveFilter(pFilter);
// RESET THE ENUMERATOR IN CYCLE (WERY STRANGE CODE BUT ELSEWERE NOTHING WORKS)
pEnum->Reset();
pFilter->Release();
} while (true);
pEnum->Release();
std::cout << "Press any key to QUIT\n";
std::system("pause");
std::cout << "\n\n";
//system("pause");
return 0;
}
void GetCaptureSource(std::wstring friendly_name, IBaseFilter** ppCaptureFilter) {
HRESULT hr;
ICreateDevEnum* devs;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, 0, CLSCTX_INPROC, IID_ICreateDevEnum, (void **)&devs);
IEnumMoniker* p_InputMonikersEnum;
hr = devs->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &p_InputMonikersEnum, 0);
SafeRelease(devs);
bool is_capture_finded = false;
do {
IMoniker* p_CaptureMoniker;
hr = p_InputMonikersEnum->Next(1, &p_CaptureMoniker, 0);
if (hr != S_OK) break;
IPropertyBag* p_PropBag;
hr = p_CaptureMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&p_PropBag);
VARIANT var;
VariantInit(&var);
VariantClear(&var);
hr = p_PropBag->Read(L"FriendlyName", &var, 0);
SafeRelease(p_PropBag);
std::wstring input_moniker_friendly_name = std::wstring(var.bstrVal);
if (input_moniker_friendly_name == friendly_name) {
is_capture_finded = true;
hr = p_CaptureMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)ppCaptureFilter);
SafeRelease(p_CaptureMoniker);
break;
}
SafeRelease(p_CaptureMoniker);
} while (true);
if (is_capture_finded == false) MessageBoxW(0, L"Capture NOT founded.", L"ERROR", MB_OK);
SafeRelease(p_InputMonikersEnum);
return;
}
void GetPin(IPin** ppPin, IBaseFilter* pFilter, std::string direction_str, std::wstring name_wstr) {
HRESULT hr;
IEnumPins* pEnumPins;
hr = pFilter->EnumPins(&pEnumPins);
do {
IPin* pNextPin;
hr = pEnumPins->Next(1, &pNextPin, 0);
if (hr != S_OK) break;
PIN_INFO pin_inf;
hr = pNextPin->QueryPinInfo(&pin_inf);
bool is_pin_of_interest = true;
if ((direction_str == "in") && (pin_inf.dir == PINDIR_OUTPUT)) is_pin_of_interest = false;
if ((direction_str == "out") && (pin_inf.dir == PINDIR_INPUT)) is_pin_of_interest = false;
if ((name_wstr != L"") && (name_wstr != std::wstring(pin_inf.achName))) is_pin_of_interest = false;
pin_inf.pFilter->Release();
if (is_pin_of_interest) {
*ppPin = pNextPin;
SafeRelease(pNextPin);
break;
}
SafeRelease(pNextPin);
} while (true);
SafeRelease(pEnumPins);
return;
}