qazxswedcgat 2015-09-04 02:01 采纳率: 100%
浏览 2729
已采纳

关于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();,就是被我注释掉的那句,但运行后发现内存还是不断增加,搞不清楚是什么原因,求解,谢谢各位!

  • 写回答

2条回答 默认 最新

  • qazxswedcgat 2015-10-05 12:04
    关注

    最近有空研究了下。。自己手动连接filters就行了。。是RenderFileToVideoRenderer这个函数的问题

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 idea右下角设置编码是灰色的
  • ¥15 全志H618ROM新增分区
  • ¥20 jupyter保存图像功能的实现
  • ¥15 在grasshopper里DrawViewportWires更改预览后,禁用电池仍然显示
  • ¥15 NAO机器人的录音程序保存问题
  • ¥15 C#读写EXCEL文件,不同编译
  • ¥15 MapReduce结果输出到HBase,一直连接不上MySQL
  • ¥15 扩散模型sd.webui使用时报错“Nonetype”
  • ¥15 stm32流水灯+呼吸灯+外部中断按键
  • ¥15 将二维数组,按照假设的规定,如0/1/0 == "4",把对应列位置写成一个字符并打印输出该字符