DirectShow: 象这样释放DirectShow资源,ActiveMovieWindow窗口为何没有正常销毁?
下面贴出来我的DirectShow初始化及销毁的主要代码
程序运行后,调用DirectShowInit能初始化成功,并能正常播放视频,但是调用DirectShowFree后,经常出现虽然最后一帧视频输出不再显示了,但是有两个奇怪的现象:
1. 窗口没有恢复原来的背景色,还是ActiveMovieWindow的黑色背景
2. 重新调用DirectShowInit并播放视频时,有时出现窗口内视频播放正常,但桌面左上角还出现了一个ActiveMovie窗口
感觉是原来调用DirectShowFree时原ActiveMovieWindow并没有销毁.
是我的DirectShowFree的代码有问题吗?盼高手指教!!!
CDlg::Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_pFilter=NULL;
m_pGraph=NULL;
m_pBaseFilter=NULL;
m_pMediaControl=NULL;
m_pVideoWindow=NULL;
CoInitialize(NULL);
// 创建 GRAPH
if(CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,IID_IGraphBuilder,(void**)&m_pGraph)!=S_OK) m_pGraph=NULL;
}
CDlg::~CDlg()
{
// 如果DirectShow已初始化但未释放
DirectShowFree();
// 释放 GRAPH
if(m_pGraph) {
m_pGraph->Release();
m_pGraph=NULL;
}
CoUninitialize();
}
HRESULT CDlg::DirectShowInit()
{
HRESULT hr=S_FALSE;
if(m_pGraph) {
// 取得 IID_IVideoWindow 接口
hr=m_pGraph->QueryInterface(IID_IVideoWindow, (void**)&m_pVideoWindow);
if(SUCCEEDED(hr)) {
m_pVideoWindow->put_AutoShow(OAFALSE);
// 添加自定义的FILTER,因为是专用FILTER,无需注册,直接创建FILTER对象加入GRAPH即可
m_pFilter=new CNvsFilter(m_nSrcWidth, m_nSrcHeight, NULL, &hr);
if(m_pFilter) {
m_pFilter->AddRef();
m_pBaseFilter=NULL;
hr = m_pFilter->QueryInterface(IID_IBaseFilter,(void**)&m_pBaseFilter);
if(SUCCEEDED(hr)) {
hr=m_pGraph->AddFilter(m_pBaseFilter,L"NVS Filter");
if(SUCCEEDED(hr)) {
IPin* pOutPin=0;
// 取未连接的PIN,自定义FILTER有一个YUY2格式的输出PIN
hr=GetUnConnectedPin(m_pBaseFilter,PINDIR_OUTPUT,&pOutPin);
if(SUCCEEDED(hr)) {
// 自动连接显示FILTER以播放YUY2媒体流
hr=m_pGraph->Render(pOutPin);
pOutPin->Release();
if(SUCCEEDED(hr)) {
// 初始化ActiveMovieWindow
m_pVideoWindow->put_Owner((OAHWND)m_hWnd);
m_pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
m_pVideoWindow->SetWindowPosition(m_nDispX, m_nDispY, m_nDispWidth, m_nDispHeight);
m_pVideoWindow->put_Visible(OATRUE);
m_pVideoWindow->SetWindowForeground(OATRUE);
m_pVideoWindow->put_MessageDrain((OAHWND)m_hWnd);
hr=m_pGraph->QueryInterface(IID_IMediaControl,(void**)&m_pMediaControl);
if(SUCCEEDED(hr)) {
// 运行GRAPH
hr=m_pMediaControl->Run();
if(SUCCEEDED(hr)) TRACE("DirectShow Graph Running ...\n");
else TRACE("DirectShow Graph run fail\n");
} else TRACE("QueryInterface IID_IMediaControl fail\n");
} else TRACE("Graph render fail\n");
} else TRACE("Get output pin fail\n");
} else TRACE("AddFilter into graph fail\n");
} else TRACE("QueryInterface IID_IBaseFilter fail\n");
} else {
hr = E_OUTOFMEMORY;
TRACE("New NVS-Filter object fail\n");
}
} else TRACE("QueryInterface IID_IVideoWindow fail\n");
if(FAILED(hr)) {
if(m_pVideoWindow) {
if(m_pFilter) {
if(m_pBaseFilter) {
if(m_pMediaControl) {
m_pMediaControl->Stop();
m_pMediaControl->Release();
m_pMediaControl=NULL;
}
m_pGraph->RemoveFilter(m_pBaseFilter);
m_pBaseFilter->Release();
m_pBaseFilter=NULL;
}
delete m_pFilter;
m_pFilter=NULL;
}
m_pVideoWindow->put_MessageDrain((OAHWND)NULL);
m_pVideoWindow->put_Visible(OAFALSE);
m_pVideoWindow->Release();
m_pVideoWindow=NULL;
}
}
}
return hr;
}
void CDlg::DirectShowFree()
{
if(m_pGraph) {
if(m_pVideoWindow) {
// 销毁ActiveMovieWindow
m_pVideoWindow->put_MessageDrain((OAHWND)NULL);
m_pVideoWindow->put_Visible(OAFALSE);
m_pVideoWindow->Release();
m_pVideoWindow=NULL;
// 销毁Filter
if(m_pFilter) {
if(m_pBaseFilter) {
if(m_pMediaControl) {
hr=m_pMediaControl->Stop();
m_pMediaControl->Release();
m_pMediaControl=NULL;
}
hr=m_pGraph->RemoveFilter(m_pBaseFilter);
m_pBaseFilter->Release();
m_pBaseFilter=NULL;
}
delete m_pFilter;
m_pFilter=NULL;
}
}
}
}