DirectShow: 象这样释放DirectShow资源,ActiveMovieWindow窗口为何没有正常销毁?

wmrwinhap 2004-12-23 11:31:55
下面贴出来我的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;
}
}
}
}
...全文
268 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
DentistryDoctor 2004-12-24
  • 打赏
  • 举报
回复
该死的MSN,它把你的邮件当作垃圾邮件了,难怪半天我没看到。
wmrwinhap 2004-12-24
  • 打赏
  • 举报
回复
to: DentistryDoctor(雅克医生<改行做程序员了>)
源代码已发送,请查收邮件,谢谢!

to::changpei(饱汉不知饿汉饥,饿了一日,方知饿乃天下第一大事!)
我在DirectShowFree中没有释放mGraph,是因为释放后经常出现在DirectShowInit中创建mGraph失败,我也不知道原因,是不是因为没有调用RemoveFromObjectTable()的原故?你这里的RemoveFromObjectTable() 是干什么用的?如何实现?
能否留下你的email,我把源代码发一份给你,帮我看看?谢谢 !
张佩 2004-12-24
  • 打赏
  • 举报
回复
void CDXGraph::Release(void)
{
if (mSeeking)
{
mSeeking->Release();
mSeeking = NULL;
}
if (mMediaControl)
{
mMediaControl->Release();
mMediaControl = NULL;
}
if (mEvent)
{
mEvent->Release();
mEvent = NULL;
}
if (mBasicVideo)
{
mBasicVideo->Release();
mBasicVideo = NULL;
}
if (mBasicAudio)
{
mBasicAudio->Release();
mBasicAudio = NULL;
}
if (mVideoWindow)
{
mVideoWindow->put_Visible(OAFALSE);
mVideoWindow->put_MessageDrain((OAHWND)NULL);
mVideoWindow->put_Owner(OAHWND(0));
mVideoWindow->Release();
mVideoWindow = NULL;
}
RemoveFromObjectTable();
if (mGraph)
{
mGraph->Release();
mGraph = NULL;
}
}
DentistryDoctor 2004-12-24
  • 打赏
  • 举报
回复
将程序发给我看一下。
DentistryDoctor@msn.com
wmrwinhap 2004-12-24
  • 打赏
  • 举报
回复
Help !!!

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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