程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程綜合問答 >> 內存-關於directshow的釋放問題

內存-關於directshow的釋放問題

編輯:編程綜合問答
關於directshow的釋放問題

解碼器: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這個函數的問題

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved