解碼器:Lav Filter,發現每次播放新的視頻內存都不斷增加20-50M不等,幾個視頻播放下來內存占用就超過500M,懷疑是directshow沒有釋放
以下是主要代碼
// DirectShow interfaces
IGraphBuilder *pGB = NULL;
IMediaControl *pMC = NULL;
IMediaEventEx *pME = NULL;
IBasicAudio *pBA = NULL;
IMediaSeeking *pMS = NULL;
IMediaPosition *pMP = NULL;
// VMR9 interfaces
IVMRWindowlessControl9 *pWC = NULL;
#define JIF(x) if (FAILED(hr=(x))) \
{Msg(TEXT("FAILED(hr=0x%x) in ") TEXT(#x) TEXT("\n\0"), hr); return hr; }
HRESULT PlayMovieInWindow(LPTSTR szFile)
{
HRESULT hr;
// hr = CoInitialize(NULL);
// Get the interface for DirectShow's GraphBuilder
JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **)&pGB));
if (SUCCEEDED(hr))
{
IBaseFilter *pVmr;
// Create the VMR and add it to the filter graph.
HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer9, NULL,
CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);
if (SUCCEEDED(hr))
{
hr = pGB->AddFilter(pVmr, L"Video Mixing Renderer 9");
//向Filter Graph中添加filter
IBaseFilter *pLavSplitterSource, *pLavVideoDecoder, *pLavAudioDecoder, *pAudioRender;
IFileSourceFilter *pFileSourceFilter;
hr = AddFilterByCLSID(pGB, CLSID_LavSplitter_Source, &pLavSplitterSource, L"Lav Splitter Source");
hr = pLavSplitterSource->QueryInterface(IID_IFileSourceFilter, (void **)&pFileSourceFilter);
hr = pFileSourceFilter->Load(szFile, NULL);
hr = AddFilterByCLSID(pGB, CLSID_LavVideoDecoder, &pLavVideoDecoder, L"Lav Video Decoder");
hr = AddFilterByCLSID(pGB, CLSID_LavAudioDecoder, &pLavAudioDecoder, L"Lav Audio Decoder");
hr = AddFilterByCLSID(pGB, CLSID_DSoundRender, &pAudioRender, L"DirectSound Audio render");
if (SUCCEEDED(hr))
{
// Set the rendering mode and number of streams
IVMRFilterConfig9 *pConfig;
JIF(pVmr->QueryInterface(IID_IVMRFilterConfig9, (void**)&pConfig));
JIF(pConfig->SetRenderingMode(VMR9Mode_Windowless));
hr = pVmr->QueryInterface(IID_IVMRWindowlessControl9, (void**)&pWC);
if (SUCCEEDED(hr))
{
JIF(pWC->SetVideoClippingWindow(hVideo));
JIF(pWC->SetBorderColor(RGB(0, 0, 0)));
}
SAFE_RELEASE(pConfig);
SAFE_RELEASE(pVmr);
}
}
// Render the file programmatically to use the VMR9 as renderer.
// Pass TRUE to create an audio renderer also.
if (FAILED(hr = RenderFileToVideoRenderer(pGB, szFile, FALSE))) return hr;
// QueryInterface for DirectShow interfaces
JIF(pGB->QueryInterface(IID_IMediaControl, (void **)&pMC));
JIF(pGB->QueryInterface(IID_IMediaEventEx, (void **)&pME));
JIF(pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS));
JIF(pGB->QueryInterface(IID_IMediaPosition, (void **)&pMP));
JIF(pGB->QueryInterface(IID_IBasicAudio, (void **)&pBA));
// Have the graph signal event via window callbacks for performance
JIF(pME->SetNotifyWindow((OAHWND)hVideo, WM_GRAPHNOTIFY, 0));
JIF(pMC->Run());
}
return hr;
}
void CloseInterfaces(void)
{
HRESULT hr;
// Stop media playback
if (pMC)
hr = pMC->Stop();
// Disable event callbacks
if (pME)
hr = pME->SetNotifyWindow((OAHWND)NULL, 0, 0);
// Enumerate the filters And remove them
IEnumFilters *pEnum = NULL;
hr = pGB->EnumFilters(&pEnum);
if (SUCCEEDED(hr))
{
IBaseFilter *pFilter = NULL;
while (S_OK == pEnum->Next(1, &pFilter, NULL))
{
// Remove the filter.
pGB->RemoveFilter(pFilter);
// Reset the enumerator.
pEnum->Reset();
pFilter->Release();
}
pEnum->Release();
}
// Release and zero DirectShow interfaces
SAFE_RELEASE(pME);
SAFE_RELEASE(pMS);
SAFE_RELEASE(pMP);
SAFE_RELEASE(pMC);
SAFE_RELEASE(pBA);
SAFE_RELEASE(pWC);
SAFE_RELEASE(pGB);
// CoUninitialize();
}
每次播放新視頻都會CloseInterfaces(); 然後 PlayMovieInWindow();
我試過在CloseInterfaces(); 加上 CoUninitialize();,就是被我注釋掉的那句,但運行後發現內存還是不斷增加,搞不清楚是什麼原因,求解,謝謝各位!
最近有空研究了下。。自己手動連接filters就行了。。是RenderFileToVideoRenderer這個函數的問題