关于Directshow轮换播放不同视频文件内存泄漏问题

sghcpt 2010-09-26 09:29:26
我的情况是这样的,我要弄一个播放窗口,轮换播放节目列表的不同视频文件,我的程序使用VMR的windowless模式来循环的播放视频文件,但每播放一次,内存就会增加,代码是根据DX文档哪里的windowless代码来修改的.程序是这样的我弄一个定时器,一到时间我就转换播放文件,而不管文件播放没有.就这样循环下来,内存不断的增加,我也试过自己析放Com对象或者用了智能指针,但还是内存泄漏.请教解决办法或者测试在那里内存泄漏的办法.大概代码如下,其中CComPtr<IGraphBuilder> m_pGraph;
CComPtr<IMediaEventEx> m_pEvent;CComPtr<IMediaSeeking>m_pMediaSeeking; CComPtr<IMediaControl> m_pMediaControl;

CMyPlayer::CMyPlayer(void)
{
m_nPlayStatus = 0;
m_pGraph = NULL;
m_pMediaControl = NULL;
m_pEvent = NULL;
m_pMediaSeeking = NULL;
}

CMyPlayer::~CMyPlayer(void)
{
m_nPlayStatus = 0;
CoUninitialize();
}

BEGIN_MESSAGE_MAP(CMyPlayer, CPlayer)
ON_WM_CREATE()
ON_MESSAGE(WM_GRAPHNOTIFY, OnGraphNotify)
END_MESSAGE_MAP()

int CMyPlayer::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}

BOOL CMyPlayer::Create(const RECT& rect, CWnd* pParent)
{
CString strClassName = AfxRegisterWndClass(CS_DBLCLKS);
return CreateEx(0, strClassName, _T("Media Player"), WS_EX_TRANSPARENT|WS_CHILD|WS_VISIBLE|WS_TABSTOP, rect, pParent, 0, 0);
}
bool CMyPlayer::CreatePlayer(const CRect& rect, CWnd* pParent, HWND hWnd)
{
if (!Create(rect, pParent))
return false;

MoveWindow(rect);
m_hParent = pParent->m_hWnd;
m_hBasePlayer = hWnd;
if (FAILED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
{
AfxMessageBox(_T("CoInitialize Failed!\r\n"));
return false;
}
return true;
}
bool CMyPlayer::CommonPlay(LPCTSTR lpFileName)
{
m_strFileName = lpFileName;
if (m_nPlayStatus == 0)
{
InitPlay();
}
else if (m_nPlayStatus == 2)
return true;
BOOL bRet = Play();
if (bRet)
m_nPlayStatus = 2;
else
{
m_nPlayStatus = 0;
return false;
}
return true;
}
BOOL CMyPlayer::Play(void)
{
if (m_pGraph)
{
if (m_pMediaControl == NULL)
m_pGraph->QueryInterface(IID_IMediaControl, (void**)&m_pMediaControl);
if (m_pMediaControl)
m_pMediaControl->Run();
return TRUE;
}
return FALSE;
}
HRESULT CMyPlayer::InitWindowlessVMR(
HWND hwndApp, // Window to hold the video.
IGraphBuilder* pGraph, // Pointer to the Filter Graph Manager.
IVMRWindowlessControl** ppWc // Receives a pointer to the VMR.
)
{
if (pGraph == NULL || ppWc == NULL)
{
return E_POINTER;
}
CComPtr<IBaseFilter> pVmr = NULL;
CComPtr<IVMRWindowlessControl> pWc = NULL;
// Create the VMR.
HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);
if (FAILED(hr))
{
return hr;
}
// Add the VMR to the filter graph.
hr = pGraph->AddFilter(pVmr, L"Video Mixing Renderer");
if (FAILED(hr))
{
return hr;
}
CComPtr<IVMRFilterConfig> pConfig = NULL;
hr = pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pConfig);
if (SUCCEEDED(hr))
{
hr = pConfig->SetRenderingMode(VMRMode_Windowless);
}
if (SUCCEEDED(hr))
{
hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&pWc);
if (SUCCEEDED(hr))
{
hr = pWc->SetVideoClippingWindow(hwndApp);
if (SUCCEEDED(hr))
{
*ppWc = pWc;
(*ppWc)->AddRef();
}
else
{
;
}
}
}
return hr;
}
int CMyPlayer::CleanUp(void)
{
CComPtr<IVideoWindow> pVidWin = NULL;
if (m_pGraph)
{
m_pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVidWin);
pVidWin->put_Visible(OAFALSE);
}
return 0;
}
void CMyPlayer::InitPlay()
{
HRESULT hr;
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void**)&m_pGraph);
CComPtr<IVMRWindowlessControl> g_pWC = NULL;
if (m_pGraph != NULL)
{
hr = InitWindowlessVMR(m_hWnd, m_pGraph, &g_pWC);
}
if (SUCCEEDED(hr))
{
USES_CONVERSION;
m_pGraph->RenderFile(m_strFileName, 0);
long lWidth, lHeight;
hr = g_pWC->GetNativeVideoSize(&lWidth, &lHeight, NULL, NULL);
if (SUCCEEDED(hr))
{
RECT rcSrc, rcDest;
// Set the source rectangle.
SetRect(&rcSrc, 0, 0, lWidth, lHeight);
// Get the window client area
GetClientRect(&rcDest);
// Set the destination rectangle.
SetRect(&rcDest, 0, 0, rcDest.right, rcDest.bottom);

g_pWC->SetAspectRatioMode(VMR_ARMODE_NONE);
hr = g_pWC->SetVideoPosition(&rcSrc, &rcDest);
}
}
if (m_pGraph != NULL)
{
m_pGraph->QueryInterface(IID_IMediaEventEx, (void**)&m_pEvent);// 注意此处Filter Graph Manager的事件以WM_GRAPHNOTIFY发出(用户定义的消息).
m_pEvent->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0);
m_pGraph->QueryInterface(IID_IMediaSeeking, (void**)&m_pMediaSeeking);//设置Seeking
}
}
bool CMyPlayer::CommonPlay()
{
return CommonPlay(m_strFileName);
}

bool CMyPlayer::CommonPause()
{
if (m_pMediaControl)
m_pMediaControl->Pause();
m_nPlayStatus = 1;
return true;
}

bool CMyPlayer::CommonStop()
{
CComPtr<IVideoWindow> pVidWin = NULL;
HRESULT hr;
if (m_pMediaControl)
{
LONGLONG lPos = 0;
if (m_pMediaControl)
hr = m_pMediaControl->Stop();
if (m_pMediaSeeking)
hr = m_pMediaSeeking->SetPositions(&lPos, AM_SEEKING_AbsolutePositioning, &lPos, AM_SEEKING_NoPositioning);
if (m_pGraph)
{
m_pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVidWin);
pVidWin->put_Visible(OAFALSE);
}
long lLevCode;
if (m_pEvent)
m_pEvent->WaitForCompletion(INFINITE, &lLevCode);
}
m_nPlayStatus = 0;
m_bPlayEnd = true;
CleanUp();
return true;
}
int CMyPlayer::GetPlayStatus()
{
return m_nPlayStatus;
}

HRESULT CMyPlayer::OnGraphNotify(WPARAM wParam, LPARAM lParam)
{
long lLevCode, lParam1, lParam2;
HRESULT hr;
while (m_pEvent, hr = m_pEvent->GetEvent(&lLevCode, &lParam1, &lParam2, 0), SUCCEEDED(hr))
{
hr = m_pEvent->FreeEventParams(lLevCode, lParam1, lParam2);
if ((EC_COMPLETE == lLevCode) || (EC_USERABORT == lLevCode) || (EC_ERRORABORT == lLevCode))
{
CommonStop();
m_nPlayStatus = 0;
break;
}
}
return hr;
}
...全文
141 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
pengderun 2010-09-27
  • 打赏
  • 举报
回复
路过帮顶。。。
falloween 2010-09-27
  • 打赏
  • 举报
回复
dingding
sghcpt 2010-09-26
  • 打赏
  • 举报
回复
怎么没有人回答的呀, 只能自己顶了.

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧