⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dxmanager.cpp

📁 tracciatore di mani con webcam
💻 CPP
📖 第 1 页 / 共 2 页
字号:

  }

  success = true;

release_and_return:
  pProcessThis.Release();
  pHandVuIn.Release();
  pHandVuOut.Release();
  pSmartTee.Release();
  pAppRenderer.Release();
  pSmartTPreviewOut.Release();

  return success;
}



// Destroy DirectShow Filter Graph
void DXManager::DestroyFilterGraph()
{
  if (m_FilterGraph) {
    CComPtr<IEnumFilters> pEnumFilters = 0;
    m_FilterGraph->EnumFilters( &pEnumFilters );

    if( pEnumFilters ) {
      CComPtr<IBaseFilter> pFilter = 0;
      ULONG cFetched = 0;

      while( pEnumFilters->Next( 1, &pFilter, &cFetched ) == S_OK && pFilter != 0 ) {
        m_FilterGraph->RemoveFilter( pFilter );
        pFilter.Release();
        cFetched = 0;
      }
      pEnumFilters.Release();
    }
  }
#ifdef DEBUG
  RemoveFromROT(m_ROTregister);
#endif

  m_GraphBuilder.Release();
  m_MediaControl.Release();
  m_MediaEventEx.Release();
  m_FilterGraph.Release();
  m_HandVuFilter.Release();
  m_HandVuFilterProp.Release();
  m_SourceFilter.Release();
  m_CameraControl.Release();
  m_VideoWindow.Release();
  m_SourceVideoWindow.Release();

  NullComPtrs();
}



bool DXManager::CreateHandVuFilter()
{
  HRESULT hr = CoCreateInstance( CLSID_HandVuFilter, NULL, CLSCTX_INPROC_SERVER, 
		                             IID_IBaseFilter, (void**)&m_HandVuFilter );
  if (SUCCEEDED(hr)) {
    m_HandVuFilter->QueryInterface(IID_IHandVuFilter, (void**)&m_HandVuFilterProp);
  }
  if (m_HandVuFilterProp) {
    
    hr = m_HandVuFilterProp->AddListener(this);
    ASSERT(SUCCEEDED(hr));
    
    if (m_pIAMTCReader) {
      hr = m_HandVuFilterProp->SetTimecodeReader(m_pIAMTCReader);
      ASSERT(SUCCEEDED(hr));
    }

    hr = m_HandVuFilterProp->SetVerbosity(g_verbose, m_handvu_logfilename);
    ASSERT(SUCCEEDED(hr));
  }
  return m_HandVuFilterProp != 0;
}

bool DXManager::InitHandVuFilter()
{
  ASSERT(m_SourceFilter);

  CComPtr<IPin> pPin = GetVideoPin(m_SourceFilter, PINDIR_OUTPUT);
  AM_MEDIA_TYPE media_type;
  pPin->ConnectionMediaType(&media_type);
  BITMAPINFOHEADER* pHdr=NULL;
  if (media_type.formattype==FORMAT_VideoInfo) {
    pHdr = &((VIDEOINFOHEADER*) media_type.pbFormat)->bmiHeader;
  } else if (media_type.formattype==FORMAT_VideoInfo2) {
    pHdr = &((VIDEOINFOHEADER2*) media_type.pbFormat)->bmiHeader;
  } else {
    return false;
  }

  ASSERT(pHdr);
  int width = pHdr->biWidth;
	int height = pHdr->biHeight;
  int iPixelSize = pHdr->biBitCount / 8;
  HRESULT hr = m_HandVuFilterProp->Initialize(width, height, iPixelSize, this);
  ASSERT(SUCCEEDED(hr));

  return SUCCEEDED(hr);
}


bool DXManager::CreateCamera( int idx )
{
  CComPtr<ICreateDevEnum> pCreateDevEnum = 0;
  CComPtr<IEnumMoniker>   pEnumMon = 0;
  ULONG           cFetched = 0;

  m_SourceFilter.Release();

  CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
		                IID_ICreateDevEnum, (void**)&pCreateDevEnum );

  /* Create capture device */
  if( pCreateDevEnum ) {
    CComPtr<IMoniker> pMon = 0;
    pCreateDevEnum->CreateClassEnumerator( CLSID_VideoInputDeviceCategory, &pEnumMon, 0);

    if( pEnumMon && idx > 0 ) {
      pEnumMon->Skip( idx );
      ASSERT(0); // need to give user a choice
    }
    if( pEnumMon && SUCCEEDED( pEnumMon->Next(1, &pMon, &cFetched)) && cFetched == 1 ) {
      pMon->BindToObject(0, 0, IID_IBaseFilter, (void **)&m_SourceFilter );
      pMon.Release();
    }
    pEnumMon.Release();
    pCreateDevEnum.Release();
  }

  if (!m_SourceFilter) {
    // try file input
    CFileDialog open_dlg(true, 0, 0, OFN_FILEMUSTEXIST, 
      "All Media Files (*.avi;*.mpg;*.mpeg;*.mov;*.wm;*.wmv;*.wma)|*.avi; *.mpg; *.mpeg; *.mov; *.wm; *.wmv; *.wma|"
      "Movie Files (*.avi;*.mpg;*.mpeg;*.mov)|*.avi; *.mpg; *.mpeg; *.mov|"
      "Windows Media Files (*.wm;*.wmv;*.wma)|*.wm;*.wmv;*.wma|"
      "All Files (*.*)|*.*||");

    if (open_dlg.DoModal()==IDOK) {
      CString str = open_dlg.GetPathName();
      if (str.GetLength()>0) {
        WCHAR wname[1000] = L"";
        MultiByteToWideChar( CP_ACP, 0, str, -1, wname, sizeof(wname)/2 );

        HRESULT hr = m_GraphBuilder->AddSourceFilter(wname, L"Mmh da sauze filter", &m_SourceFilter);
        if (!SUCCEEDED(hr) || m_SourceFilter==NULL) {
          VERBOSE0(3, "DXManager: could not add source filter");
          return false;
        }
      }
    }
  }

  if (m_SourceFilter) {
    HRESULT hr = m_SourceFilter->QueryInterface(IID_IAMCameraControl, (void **)&m_CameraControl);
    if (SUCCEEDED(hr) && m_CameraControl) {
      VERBOSE0(5, "IAMCameraControl is implemented");
      // make sure it works
      try {
        double exposure = GetCurrentExposure();
        double new_exposure = SetExposure(exposure);
      } catch (HVException& hve) {
        VERBOSE1(2, "IAMCameraControl operation test failed: %s",
          hve.GetMessage().c_str());
        m_CameraControl.Release();
        m_CameraControl = NULL;
      }
      if (m_CameraControl) {
        VERBOSE0(5, "IAMCameraControl functional - got CameraController");
      }
    } else {
      VERBOSE0(2, "IAMCameraControl not implemented");
    }

    hr = m_SourceFilter->QueryInterface(IID_IAMTimecodeReader, (void **) &m_pIAMTCReader);
    if (!SUCCEEDED(hr)) {
      VERBOSE0(3, "DXManager: no DV TimecodeReader available");
      m_pIAMTCReader = NULL;
    }
  }

  return m_SourceFilter != 0;
}






#ifdef DEBUG
/////////////////////////////////////////////////////////////////////////////
// this allows GraphEdit to connect to the filter graph
// (File ... connect)
HRESULT DXManager::AddToROT(IUnknown *pUnkGraph, DWORD *pdwRegister) 
{
  IMoniker * pMoniker;
  IRunningObjectTable *pROT;
  if (FAILED(GetRunningObjectTable(0, &pROT))) {
    return E_FAIL;
  }
  int const sz = 256;
  WCHAR wsz[sz];
  size_t cbDest = sz * sizeof(WCHAR);
//  StringCbPrintfW(wsz, cbDest, L"FilterGraph %08p pid %08x", (DWORD *) pUnkGraph, GetCurrentProcessId());
  wsprintfW(wsz, L"FilterGraph %08p pid %08x", (DWORD *) pUnkGraph, GetCurrentProcessId());
  HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
  //HRESULT hr = CreateItemMoniker(L"!", L"HandVuDXApp", &pMoniker);
  if (SUCCEEDED(hr)) {
    hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
    pMoniker->Release();
  }
  pROT->Release();
  return hr;
}

/////////////////////////////////////////////////////////////////////////////
// remove filter graph from Running Object Table
void DXManager::RemoveFromROT(DWORD pdwRegister)
{
  IRunningObjectTable *pROT;
  if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
    pROT->Revoke(pdwRegister);
    pROT->Release();
  }
}
#endif // DEBUG


void DXManager::GetVideoSourceSize(int* pWidth, int* pHeight) 
{
  *pWidth = -1;
	*pHeight = -1;
  if (m_SourceFilter!=0) {
    CComPtr<IPin> pPin = GetVideoPin(m_SourceFilter, PINDIR_OUTPUT);
    AM_MEDIA_TYPE media_type;
    pPin->ConnectionMediaType(&media_type);
    BITMAPINFOHEADER* pHdr=NULL;
    if (media_type.formattype==FORMAT_VideoInfo) {
      pHdr = &((VIDEOINFOHEADER*) media_type.pbFormat)->bmiHeader;
    } else if (media_type.formattype==FORMAT_VideoInfo2) {
      pHdr = &((VIDEOINFOHEADER2*) media_type.pbFormat)->bmiHeader;
    }
    if (pHdr!=NULL) {
      *pWidth = pHdr->biWidth;
	  	*pHeight = abs(pHdr->biHeight);
      VERBOSE2(4, "DXManager: got real size %d %d", *pWidth, *pHeight);
    }
  } 
  if (*pWidth==-1 || *pHeight==-1)  {
    *pWidth = 640;
	  *pHeight = 480;
    VERBOSE2(4, "DXManager: got fake size %d %d", *pWidth, *pHeight);
  }
}

void DXManager::SetVideoWindowPosition(int left, int top, int width, int height) 
{
  if (m_VideoWindow) {
    VERBOSE4(4, "DXManager: setting left %d, top %d, width %d, height %d", 
      left, top, width, height);
    m_VideoWindow->SetWindowPosition( left, top, width, height );
  }
}

void DXManager::SetSourceVideoWindowPosition(int left, int top, int width, int height) 
{
  if (m_SourceVideoWindow) {
    m_SourceVideoWindow->SetWindowPosition( left, top, width, height );
  }
}

HRESULT DXManager::AddFilter(IBaseFilter* filter, LPCWSTR name) {
  HRESULT hr = m_FilterGraph->AddFilter(filter, name);
#ifdef DEBUG
  if (!SUCCEEDED(hr)) {
    char buf[MAX_ERROR_TEXT_LEN];
    AMGetErrorText(hr, buf, MAX_ERROR_TEXT_LEN);
    ASSERT(0);
  }
#endif // DEBUG
  return hr;
}

HRESULT DXManager::ConnectPins(IPin* from, IPin* to) {
  HRESULT hr = m_GraphBuilder->Connect(from, to);
#ifdef DEBUG
  if (!SUCCEEDED(hr)) {
    char buf[MAX_ERROR_TEXT_LEN];
    AMGetErrorText(hr, buf, MAX_ERROR_TEXT_LEN);
    ASSERT(0);
  }
#endif // DEBUG
  return hr;
}

void DXManager::GetVersion(string& version) const
{
  string dxm_version = "DXManager: $Id: DXManager.cpp,v 1.14 2005/10/30 23:00:43 matz Exp $";
  string filter_version = "no HandVuFilter loaded";
  if (m_HandVuFilterProp) {
    HRESULT hr = m_HandVuFilterProp->GetVersion(filter_version);
    ASSERT(SUCCEEDED(hr));
  }
  version = dxm_version + "\n" + filter_version;
}


BOOL PinMatchesCategory(CComPtr<IPin> pPin, const GUID& Category)
{
  if (pPin == NULL) {
    return false;
  }

  BOOL bFound = FALSE;
  IKsPropertySet *pKs;
  HRESULT hr = pPin->QueryInterface(IID_IKsPropertySet, (void **)&pKs);
  if (SUCCEEDED(hr))
  {
    GUID PinCategory;
    DWORD cbReturned;
    hr = pKs->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0, 
      &PinCategory, sizeof(GUID), &cbReturned);
    if (SUCCEEDED(hr))
    {
      bFound = (PinCategory == Category);
    }
    pKs->Release();
  }
  return bFound;
}

static CComPtr<IPin> GetPin(CComPtr<IBaseFilter> pFilter, PIN_DIRECTION PinDir, int skip/*=0*/, const GUID* pCategory /*= NULL*/)
{
    CComPtr<IEnumPins>  pEnum;
    CComPtr<IPin>       pPin;

    HRESULT hr = pFilter->EnumPins(&pEnum);
    if (FAILED(hr)) {
        return NULL;
    }
    while((hr=pEnum->Next(1, &pPin.p, 0)) == S_OK) {
        PIN_DIRECTION PinDirThis;
        pPin->QueryDirection(&PinDirThis);
        if (PinDir==PinDirThis) {
          if (pCategory==NULL || PinMatchesCategory(pPin, *pCategory)) {
            if (skip) {
              skip--;
            } else {
              break;
            }
          }
        }
        pPin.Release();
    }
    pEnum.Release();
    return pPin;  
}

// get a video output pin
static CComPtr<IPin> GetVideoPin(CComPtr<IBaseFilter> pFilter, PIN_DIRECTION PinDir) //, int skip/*=0*/, const GUID* pCategory /*= NULL*/)
{
  CComPtr<IPin>       pPin;

  bool got_one = false;
  int skip = 0;
  BITMAPINFOHEADER* pHdr=NULL;
  do {
    pPin = GetPin(pFilter, PINDIR_OUTPUT, skip);
    if (pPin==NULL) {
      return NULL;
    }

    CComPtr<IEnumMediaTypes> pEnum;
    HRESULT hr = pPin->EnumMediaTypes(&pEnum);
    if (!SUCCEEDED(hr) || !pEnum) return NULL;
    AM_MEDIA_TYPE* pMediaType = NULL;
    hr = pEnum->Next(1, &pMediaType, NULL);
    while (hr==S_OK) {
      if (pMediaType->formattype==FORMAT_VideoInfo || 
          pMediaType->majortype==MEDIATYPE_Video || 
          pMediaType->majortype==MEDIATYPE_Interleaved || 
          pMediaType->majortype==MEDIATYPE_Stream || 
          pMediaType->majortype==MEDIATYPE_AnalogVideo) 
      {
        DeleteMediaType(pMediaType);
        pMediaType = NULL;
        got_one = true;
        break;
      }
      DeleteMediaType(pMediaType);
      pMediaType = NULL;
      hr = pEnum->Next(1, &pMediaType, NULL);
    }
    skip++;
    if (!got_one) {
      pPin.Release();
    }
  } while (!got_one);

  return pPin;
}








IMPLEMENT_DYNCREATE(CSourceView, CScrollView)

BEGIN_MESSAGE_MAP(CSourceView, CScrollView)
  ON_WM_SIZE()
END_MESSAGE_MAP()


CSourceView::CSourceView()
{
}

CSourceView::~CSourceView()
{
}

BOOL CSourceView::PreCreateWindow(CREATESTRUCT& cs)
{
	return CView::PreCreateWindow(cs);
}

void CSourceView::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();
  SetVideoWindowSize(0, 0);
}

void CSourceView::OnSize(UINT nType, int cx, int cy) 
{
	CScrollView::OnSize(nType, cx, cy);

  SetVideoWindowSize(cx, cy);
	Invalidate(true);
}

void CSourceView::SetVideoWindowSize(int width, int height) 
{
  int source_width, source_height;
  m_pDXManager->GetVideoSourceSize(&source_width, &source_height);
  if (source_height<0) {
    source_height = -source_height;
  }
  CRect rc;
  GetClientRect( &rc );
  if (width==0 && height==0) {
    width = source_width;
    height = source_height;
//      MoveWindow(&rc);
  } else {
    width = max(width, source_width);
    height = max(height, source_height);
    double ratio = (double)source_width/(double)source_height;
    width = min(width, (int)((double)height*ratio));
    height = min(height, (int)((double)width/ratio));
  }
  m_pDXManager->SetSourceVideoWindowPosition( rc.left, rc.top, width, height );

	SetScrollSizes(MM_TEXT, CSize(source_width, source_height));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -