下面贴出来我的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;
      }
    }
  }
}

解决方案 »

  1.   

    将程序发给我看一下。
    [email protected]
      

  2.   

    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;
    }
    }
      

  3.   

    to: DentistryDoctor(雅克医生<改行做程序员了>) 
        源代码已发送,请查收邮件,谢谢!to::changpei(饱汉不知饿汉饥,饿了一日,方知饿乃天下第一大事!) 
        我在DirectShowFree中没有释放mGraph,是因为释放后经常出现在DirectShowInit中创建mGraph失败,我也不知道原因,是不是因为没有调用RemoveFromObjectTable()的原故?你这里的RemoveFromObjectTable() 是干什么用的?如何实现?
        能否留下你的email,我把源代码发一份给你,帮我看看?谢谢 !
      

  4.   

    该死的MSN,它把你的邮件当作垃圾邮件了,难怪半天我没看到。