topical media & game development

talk show tell print

hush-src-multi-GamePlayer-VMR9Subgraph.cpp / cpp



  //------------------------------------------------------------------------------
  // File: VMR9Subgraph.cpp
  //
  // Desc: DirectShow sample code - MultiVMR9 GamePlayer
  //
  // Copyright (c) Microsoft Corporation.  All rights reserved.
  //------------------------------------------------------------------------------
  
  include <stdafx.h>
  include <MultiVMR9.h>
  include <VMR9Subgraph.h>
  
  include <vip.h>
  
  // AE
  
  HRESULT CVMR9Subgraph::CaptureAndRender(CComPtr<IMultiVMR9Wizard> pWizard, int num, WCHAR *wcPath)
  {
      HRESULT hr = S_OK;
      CComPtr<IVMRFilterConfig9> pConfig;
      CComPtr<IGraphBuilder>  pGb;
  
          //if( !wcPath )
      //{
        //  return E_POINTER;
      //}
  
      USES_CONVERSION;
          if (wcPath) {
      wcsncpy( m_wcPath, wcPath, MAX_PATH);
      _tcsncpy( m_achPath, W2T(wcPath), MAX_PATH);
          }
      // first, check that file exists
      //if( INVALID_FILE_ATTRIBUTES == GetFileAttributes( m_achPath))
      //{
        //  MessageBox(NULL, TEXT("Requested media file was not found"), TEXT("Error"), MB_OK);
          //return VFW_E_NOT_FOUND;
      //}
  
          // AE
              ICaptureGraphBuilder2 *pBuild = NULL;
          CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, 
          CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuild);
          
      // create graph
      hr = CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
          IID_IFilterGraph, (void**)&(m_pGraph.p) );
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Failed to create the filter graph"), TEXT("Error"), MB_OK);
          return hr;
      }
  
          
  
      // create and add VMR9
      hr = CoCreateInstance( CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER,
          IID_IBaseFilter, (void**)&(m_pVMR.p) );
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Failed to create instance of VMR9"), TEXT("Error"), MB_OK);
          return hr;
      }
  
      hr = m_pGraph->AddFilter( m_pVMR, L"VMR9");
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Failed to add VMR9 to the graph"), TEXT("Error"), MB_OK);
          return hr;
      }
      // configure VMR9
      hr = m_pVMR->QueryInterface( IID_IVMRFilterConfig9, (void**)&(pConfig.p) );
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Cannot get IVMRFilterConfig9 from VMR9"), TEXT("Error"), MB_OK);
          return hr;
      }
      
      // if wizard is provided, set VMR to the renderless code and attach to the wizard
      if( pWizard )
      {
          // set VMR to the renderless mode
          hr = pConfig->SetRenderingMode( VMR9Mode_Renderless );
          if( FAILED(hr))
          {
              MessageBox(NULL, TEXT("Failed to set VMR9 to the renderless mode"), TEXT("Error"), MB_OK);
              return hr;
          }
  
          hr = pWizard->Attach( m_pVMR, &m_dwID );
          if( FAILED(hr))
          {
              MessageBox(NULL, TEXT("Failed to attach graph to the wizard"), TEXT("Error"), MB_OK);
              return hr;
          }
      }
          
  
      // try to render media source
      hr = m_pGraph->QueryInterface( IID_IGraphBuilder, (void**)&(pGb.p) );
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Cannot get IGraphBuilder from the filter graph"), TEXT("Error"), MB_OK);
          return hr;
      }
  
          // AE
      pBuild->SetFiltergraph(pGb);
  
          IBaseFilter *pSource;
     // FindCaptureDevice(&pSource);
          //GetVideoInputFilter(&pSource, 0);
          if (0) {//vip::find_video(0,0,&pSource,wcPath,0,0);
            pGb->AddSourceFilter( wcPath, L"Video Source", &pSource);
        //vip::find_capture0(&pSource,wcPath);
          } else {
          vip::find_capture(&pSource,0, num);
      pGb->AddFilter(pSource, L"Video Capture");
          }
      //&MEDIATYPE_Video
     pBuild->RenderStream(0, 0, pSource, 0, m_pVMR); 
          //pBuild->RenderStream(0, &MEDIATYPE_Video, pSource, 0, m_pVMR);  
          //pBuild->RenderStream(0, &MEDIATYPE_Audio, pSource, 0, NULL);
  
      //hr = pGb->RenderFile( m_wcPath, NULL);
      //if( FAILED(hr))
      //{
        //  MessageBox(NULL, TEXT("Failed to render specified media file"), TEXT("Error"), MB_OK);
          //return hr;
      //}
  
          
  
      hr = CheckVMRConnection();
      if( FAILED(hr))
      {
          hr = pWizard->Detach( m_dwID );
          MessageBox(NULL, TEXT("Application does not support this media type.\r\nTry some other media source"),
              TEXT("Error"), MB_OK);
          return hr;
      }
  
      // ok, all is rendered, now get MediaControl, MediaSeeking and continue
      hr = m_pGraph->QueryInterface( IID_IMediaControl, (void**)&(m_pMc.p) );
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Cannot find IMediaControl interface"), TEXT("Error"), MB_OK);
          return hr;
      }
  
      hr = m_pGraph->QueryInterface( IID_IMediaSeeking, (void**)&(m_pMs.p) );
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Cannot find IMediaSeeking interface"), TEXT("Error"), MB_OK);
          return hr;
      }
  
          return hr;
  }
  
  
****************************Public*Routine******************************\ CVMR9Subgraph constructor \*************************************************************************

  
  
  CVMR9Subgraph::CVMR9Subgraph()
      : m_dwID( NULL)
  {
          capture = 0;
      m_wcPath[0] = L'\0';
      m_achPath[0] = TEXT('\0');
  }
  
  
****************************Public*Routine******************************\ CVMR9Subgraph destructor \*************************************************************************

  
  CVMR9Subgraph::~CVMR9Subgraph()
  {
  }
  
  
****************************Public*Routine******************************\ BuildAndRender Builds the filter graph to render the media file located at wcPath with use of VMR9; if wizard is provided, VMR9 is set to the renderless mode and custom allocator- presenter (which is pWizard in this sample) is advised. Return values: errors from the filter graph and wizard \*************************************************************************

  
  HRESULT CVMR9Subgraph::BuildAndRender( WCHAR *wcPath, CComPtr<IMultiVMR9Wizard> pWizard )
  {
      HRESULT hr = S_OK;
      CComPtr<IVMRFilterConfig9> pConfig;
      CComPtr<IGraphBuilder>  pGb;
          
          ICaptureGraphBuilder2 *pBuild = NULL;
         // CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, 
         // CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuild);
  
      if( !wcPath )
      {
          return E_POINTER;
      }
  
      USES_CONVERSION;
      wcsncpy( m_wcPath, wcPath, MAX_PATH);
      _tcsncpy( m_achPath, W2T(wcPath), MAX_PATH);
  
      // first, check that file exists
      if( INVALID_FILE_ATTRIBUTES == GetFileAttributes( m_achPath))
      {
          MessageBox(NULL, TEXT("Requested media file was not found"), TEXT("Error"), MB_OK);
          return VFW_E_NOT_FOUND;
      }
  
      // create graph
      hr = CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
          IID_IFilterGraph, (void**)&(m_pGraph.p) );
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Failed to create the filter graph"), TEXT("Error"), MB_OK);
          return hr;
      }
  
      // create and add VMR9
      hr = CoCreateInstance( CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER,
          IID_IBaseFilter, (void**)&(m_pVMR.p) );
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Failed to create instance of VMR9"), TEXT("Error"), MB_OK);
          return hr;
      }
  
      hr = m_pGraph->AddFilter( m_pVMR, L"VMR9");
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Failed to add VMR9 to the graph"), TEXT("Error"), MB_OK);
          return hr;
      }
      // configure VMR9
      hr = m_pVMR->QueryInterface( IID_IVMRFilterConfig9, (void**)&(pConfig.p) );
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Cannot get IVMRFilterConfig9 from VMR9"), TEXT("Error"), MB_OK);
          return hr;
      }
      
      // if wizard is provided, set VMR to the renderless code and attach to the wizard
      if( pWizard )
      {
          // set VMR to the renderless mode
          hr = pConfig->SetRenderingMode( VMR9Mode_Renderless );
          if( FAILED(hr))
          {
              MessageBox(NULL, TEXT("Failed to set VMR9 to the renderless mode"), TEXT("Error"), MB_OK);
              return hr;
          }
  
          hr = pWizard->Attach( m_pVMR, &m_dwID );
          if( FAILED(hr))
          {
              MessageBox(NULL, TEXT("Failed to attach graph to the wizard"), TEXT("Error"), MB_OK);
              return hr;
          }
      }
  
      // try to render media source
      hr = m_pGraph->QueryInterface( IID_IGraphBuilder, (void**)&(pGb.p) );
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Cannot get IGraphBuilder from the filter graph"), TEXT("Error"), MB_OK);
          return hr;
      }
  
          //pBuild->RenderStream(0, 0, fSource, 0, g_filter); 
          //hr = pBuild->RenderStream(0, &MEDIATYPE_Audio, fSource, 0, NULL);
     
          
          if (0) {
     pBuild->SetFiltergraph(pGb);
     IBaseFilter *pSource;
     pGb->AddSourceFilter( wcPath, L"Video Source", &pSource);
     hr = pBuild->RenderStream(0, 0, pSource, 0, m_pVMR); 
          } else {
                  hr = pGb->RenderFile( m_wcPath, NULL);
          }
                  //hr = pGb->RenderStream(0, 0, pSource, 0, m_pVMR); 
          // &MEDIATYPE_Video
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Failed to render specified media file"), TEXT("Error"), MB_OK);
          return hr;
      }
  
      hr = CheckVMRConnection();
      if( FAILED(hr))
      {
          hr = pWizard->Detach( m_dwID );
          MessageBox(NULL, TEXT("Application does not support this media type.\r\nTry some other media source"),
              TEXT("Error"), MB_OK);
          return hr;
      }
  
      // ok, all is rendered, now get MediaControl, MediaSeeking and continue
      hr = m_pGraph->QueryInterface( IID_IMediaControl, (void**)&(m_pMc.p) );
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Cannot find IMediaControl interface"), TEXT("Error"), MB_OK);
          return hr;
      }
  
      hr = m_pGraph->QueryInterface( IID_IMediaSeeking, (void**)&(m_pMs.p) );
      if( FAILED(hr))
      {
          MessageBox(NULL, TEXT("Cannot find IMediaSeeking interface"), TEXT("Error"), MB_OK);
          return hr;
      }
  
      return hr;
  }
  
  
****************************Public*Routine******************************\ CheckVMRConnection \*************************************************************************

  
  HRESULT CVMR9Subgraph::CheckVMRConnection()
  {
      HRESULT hr = S_OK;
      bool bConnected = false;
  
      CComPtr<IEnumPins> pEnum;
      CComPtr<IPin> pPin;
  
      if( !m_pVMR )
          return E_UNEXPECTED;
  
      hr = m_pVMR->EnumPins( &pEnum );
      if( FAILED(hr))
          return hr;
  
      hr = pEnum->Next( 1, &pPin, NULL);
      while( SUCCEEDED(hr) && pPin)
      {
          CComPtr<IPin> pConnectedPin;
          hr = pPin->ConnectedTo( &pConnectedPin );
  
          if( SUCCEEDED(hr) && pConnectedPin )
          {
              bConnected = true;
              break;
          }
  
          pPin = NULL;
          hr = pEnum->Next( 1, &pPin, NULL);
      }// while
  
      hr = (true == bConnected) ? S_OK : E_FAIL;
      return hr;
  }
  
  
****************************Public*Routine******************************\ Run \*************************************************************************

  
  HRESULT CVMR9Subgraph::Run()
  {
      HRESULT hr = S_OK;
  
      if( !m_pMc )
      {
          return E_UNEXPECTED;
      }
      hr = m_pMc->Run();
  
      return hr;
  }
  
  
****************************Public*Routine******************************\ Pause \*************************************************************************

  
  HRESULT CVMR9Subgraph::Pause()
  {
      HRESULT hr = S_OK;
  
      if( !m_pMc )
      {
          return E_UNEXPECTED;
      }
      hr = m_pMc->Pause();
  
      return hr;
  }
  
  
****************************Public*Routine******************************\ Stop \*************************************************************************

  
  HRESULT CVMR9Subgraph::Stop()
  {
      HRESULT hr = S_OK;
      OAFilterState state;
  
      if( !m_pMc )
      {
          return E_UNEXPECTED;
      }
  
      hr = m_pMc->Stop();
      state = State_Running;
  
      while( State_Stopped != state && SUCCEEDED(hr))
      {
          hr = m_pMc->GetState(100, &state);
          Sleep(100);
      }
  
      return hr;
  }
  
  
****************************Public*Routine******************************\ GetState Returns OAFilterState from IMediaControl of the graph Return values: errors from the filter graph and wizard \*************************************************************************

  
  OAFilterState CVMR9Subgraph::GetState()
  {
      OAFilterState state = State_Stopped;
      if( m_pMc )
      {
          HRESULT hr = m_pMc->GetState( 20, &state );
      }
      return state;
  }
  
  
****************************Public*Routine******************************\ SetTime \*************************************************************************

  
  HRESULT CVMR9Subgraph::SetTime( LONGLONG llCur)
  {
      HRESULT hr = S_OK;
      LONGLONG llDur = 0L;
  
      if( !m_pMs )
          return E_FAIL;
  
      hr = m_pMs->SetPositions(   &llCur, AM_SEEKING_AbsolutePositioning, 
                                  &llDur, AM_SEEKING_NoPositioning);
  
      return hr;
  }
  
  
****************************Public*Routine******************************\ GetTimes \*************************************************************************

  
  HRESULT CVMR9Subgraph::GetTimes( LONGLONG& llCur, LONGLONG& llDur)
  {
      HRESULT hr = S_OK;
      if( !m_pMs )
          return E_FAIL;
  
      hr = m_pMs->GetPositions( &llCur, &llDur );
      return hr;
  }
  
  
****************************Public*Routine******************************\ GetPathT, GetPathW \*************************************************************************

  
  void CVMR9Subgraph::GetPathT( TCHAR* achPath )
  {
      if( achPath )
      {
          _tcscpy( achPath, m_achPath);
      }
  }
  
  void CVMR9Subgraph::GetPathW( WCHAR* wcPath )
  {
      if( wcPath )
      {
          wcscpy( wcPath, m_wcPath);
      }
  }
  
  
****************************Public*Routine******************************\ DestroyGraph Stops the graph, destroys and removes all the filters (VMR9 is removed last) \*************************************************************************

  
  HRESULT CVMR9Subgraph::DestroyGraph()
  {
      HRESULT hr = S_OK;
      OAFilterState state;
  
      if( !m_pGraph )
      {
          return E_POINTER;
      }
  
      FILTER_INFO fi;
      CComPtr<IMediaControl> pMc;
      CComPtr<IEnumFilters> pEnum;
      CComPtr<IBaseFilter> pFilter;
      CComPtr<IBaseFilter> pVMR = NULL;
  
      // 1. stop the graph
      hr = m_pGraph->QueryInterface( IID_IMediaControl, (void**)&(pMc.p) );
      if( FAILED(hr))
      {
          return hr;
      }
  
      do
      {
          hr = pMc->GetState(100, &state);
      } while( S_OK == hr && State_Stopped != state );
  
      hr = m_pGraph->EnumFilters( &(pEnum.p) );
      if( FAILED(hr))
      {
          return hr;
      }
  
      // tear off
      hr = pEnum->Next(1, &(pFilter.p), NULL);
      while( S_OK == hr && pFilter )
      {
          hr = DisconnectPins( pFilter );
          pFilter = NULL;
          hr = pEnum->Next(1, &(pFilter.p), NULL);
      }
      pFilter = NULL;
  
      // remove filters
      hr = pEnum->Reset();
      hr = pEnum->Next(1, &(pFilter.p), NULL);
      while( S_OK == hr && pFilter )
      {
          hr = pFilter->QueryFilterInfo( &fi);
          if( fi.pGraph)
              fi.pGraph->Release();
  
          if( 0 == wcscmp( fi.achName, L"VMR9"))
          {
              pVMR = pFilter;
          }
          hr = m_pGraph->RemoveFilter( pFilter);
          pFilter = NULL;
  
          hr = pEnum->Reset();
          hr = pEnum->Next(1, &pFilter, NULL);
      }
  
      pFilter = NULL;
      pEnum = NULL;
      pVMR = NULL;
  
      return S_OK;
  }
  
  
****************************Public*Routine******************************\ DisconnectPins Disconnects pins of a filter \*************************************************************************

  
  HRESULT CVMR9Subgraph::DisconnectPins( CComPtr<IBaseFilter> pFilter)
  {
      HRESULT hr = S_OK;
  
      CComPtr<IEnumPins> pEnum;
      CComPtr<IPin> pPin;
  
      if( !pFilter )
      {
          return E_POINTER;
      }
  
      hr = pFilter->EnumPins( &pEnum );
      if( FAILED(hr))
      {
          return hr;
      }
      hr = pEnum->Next( 1, &pPin, NULL);
  
      while( S_OK == hr && pPin )
      {
          hr = pPin->Disconnect();
          pPin = NULL;
          hr = pEnum->Next( 1, &pPin, NULL);
      }
  
      pPin = NULL;
      pEnum = NULL;
  
      return S_OK;
  }
  
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.