DXManager.cpp
上传用户:lijia5631
上传日期:2008-11-10
资源大小:1214k
文件大小:26k
源码类别:

视频捕捉/采集

开发平台:

MultiPlatform

  1. /**   * HandVu - a library for computer vision-based hand gesture   * recognition.   * Copyright (C) 2004 Mathias Kolsch, matz@cs.ucsb.edu   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License   * as published by the Free Software Foundation; either version 2   * of the License, or (at your option) any later version.   *   * This program is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * GNU General Public License for more details.   *   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 59 Temple Place - Suite 330,    * Boston, MA  02111-1307, USA.   *   * $Id: DXManager.cpp,v 1.14 2005/10/30 23:00:43 matz Exp $ **/ #include "stdafx.h"
  2. #include "HandVuFilterGUIDs.h"
  3. #include <initguid.h> // need this before MainFrm.h
  4. #include "Common.h"
  5. #include "DXManager.h"
  6. #include "DXAppView.h"
  7. #include "Dvdmedia.h"
  8. #include "Exceptions.h"
  9. DXManager::DXManager() :
  10.   m_video_scale(1.0),
  11.   m_pParentView(NULL),
  12.   m_handvu_logfilename(""),
  13.   m_two_windows(false)
  14. {
  15.   NullComPtrs();
  16.   /*
  17.   // start GestureEventServer
  18.   int m_gesture_server_port = 7047;
  19.   int m_osc_port = 57120;
  20.   string m_osc_ip = "128.111.28.75"; 
  21. //  string m_osc_ip = "localhost"; 
  22.   m_pGestureServer = new CGestureEventServer(m_gesture_server_port);
  23.   m_pGestureServer->UseOSC(m_osc_ip, m_osc_port);
  24.   m_pGestureServer->Start();
  25. */
  26.   // for event timestamps
  27.   _ftime(&m_startTime);
  28.   // debugging
  29.   m_ROTregister   = 0;
  30. //  DbgInitialise(g_hInst);
  31.   DbgSetModuleLevel(LOG_CUSTOM1, 3);
  32. }
  33. DXManager::~DXManager()
  34. {
  35.   StopPlayback();
  36.   DestroyFilterGraph();
  37. //  DbgDumpObjectRegister();
  38. //  DbgTerminate();
  39. }
  40. void DXManager::NullComPtrs()
  41. {
  42.   m_GraphBuilder = NULL;
  43.   m_MediaControl = NULL;
  44.   m_MediaEventEx = NULL;
  45.   m_FilterGraph = NULL;
  46.   m_HandVuFilterProp = NULL;
  47.   m_HandVuFilter = NULL;
  48.   m_SourceFilter = NULL;
  49.   m_CameraControl = NULL;
  50.   m_VideoWindow = NULL;
  51.   m_SourceVideoWindow = NULL;
  52.   m_pIAMTCReader = NULL;
  53. }
  54. void DXManager::StartPlayback() 
  55. {
  56.   if (m_HandVuFilterProp) {
  57.     HRESULT hr = m_HandVuFilterProp->AddListener(this);
  58.     ASSERT(SUCCEEDED(hr));
  59.   }
  60.   if (m_MediaControl) {
  61.     m_VideoWindow->put_Owner((OAHWND)m_pParentView->m_hWnd);
  62.     m_VideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
  63.     m_VideoWindow->put_MessageDrain((OAHWND)m_pParentView->m_hWnd);
  64.     m_VideoWindow->put_Visible(OATRUE);
  65.     /*
  66.     if (m_MediaEventEx) {
  67.       // Have the graph signal event via window callbacks for performance
  68.       m_MediaEventEx->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0);
  69.     }
  70.     */
  71.     m_MediaControl->Run();
  72.   }
  73. }
  74. void DXManager::StopPlayback() 
  75. {
  76.   if (m_HandVuFilterProp) {
  77.     HRESULT hr = m_HandVuFilterProp->RemoveListener(this);
  78.     ASSERT(SUCCEEDED(hr));
  79.   }
  80.   if (m_MediaControl) {
  81.     m_MediaControl->Stop();
  82.     m_VideoWindow->put_Visible(OAFALSE);
  83.     m_VideoWindow->put_Owner(NULL);
  84.     m_VideoWindow->put_MessageDrain(0);
  85.   }
  86. }
  87. bool DXManager::BuildGraph(bool two_windows, CDXAppView* parent)
  88. {
  89.   m_pParentView = parent;
  90.   m_two_windows = two_windows;
  91.   DestroyFilterGraph();
  92.   bool success = RealBuildGraph();
  93.   if (!success) {
  94.     DestroyFilterGraph();
  95.   }
  96.   return success;
  97. }
  98. void DXManager::FrameTransformed(bool processed)
  99. {
  100. }
  101. IHandVuFilter* DXManager::HV()
  102. {
  103.   ASSERT(m_HandVuFilterProp);
  104.   return m_HandVuFilterProp.p;
  105. }
  106. void DXManager::ToggleExposureControl()
  107. {
  108.   SetExposureControl(-1);
  109. }
  110. void DXManager::SetExposureControl(int on/*=1*/)
  111. {
  112.   if (!m_CameraControl) {
  113.     return;
  114.   }
  115.   if (!m_HandVuFilterProp) {
  116.     return;
  117.   }
  118.   bool possible;
  119.   HRESULT hr = m_HandVuFilterProp->CanAdjustExposure(&possible);
  120.   ASSERT(SUCCEEDED(hr));
  121.   if (!possible) {
  122.     return;
  123.   }
  124.   if (on==-1) {
  125.     bool is_on;
  126.     hr = m_HandVuFilterProp->IsAdjustingExposure(&is_on);
  127.     ASSERT(SUCCEEDED(hr));
  128.     on = is_on?0:1;
  129.   }
  130.   if (on) {
  131.     hr = m_HandVuFilterProp->SetAdjustExposure(true);
  132.     ASSERT(SUCCEEDED(hr));
  133.   } else {
  134.     // turn it off in HandVu
  135.     hr = m_HandVuFilterProp->SetAdjustExposure(false);
  136.     ASSERT(SUCCEEDED(hr));
  137.     // turn Auto exposure on in the camera itself
  138.     SetCameraAutoExposure(true);
  139.   }
  140. }
  141. /* CameraControl function
  142. * returns true if camera was successfully set to adjust the exposure
  143. */
  144. bool DXManager::SetCameraAutoExposure(bool enable)  {   long exposure, flags;
  145.   HRESULT hr = m_CameraControl->Get(CameraControl_Exposure, &exposure, &flags);
  146.   if (SUCCEEDED(hr)) {
  147.     if (enable) {
  148.       flags = CameraControl_Flags_Auto;
  149.     } else {
  150.       flags = CameraControl_Flags_Manual;
  151.     }
  152.     hr = m_CameraControl->Set(CameraControl_Exposure, exposure, flags);
  153.     if (SUCCEEDED(hr)) {
  154.       VERBOSE1(3, "camera does %sauto-expose now", ((enable)?"":"not "));
  155.     }
  156.   }
  157.   if (!SUCCEEDED(hr)) {
  158.     VERBOSE0(2, "can't set camera to do auto-exposure");
  159.   }
  160.   return (SUCCEEDED(hr));
  161. } /* CameraControl function
  162. */
  163. double DXManager::GetCurrentExposure()  {   if (!m_CameraControl) {
  164.     throw HVException("no camera control found");
  165.   }
  166.   long minExp, maxExp, stepping_delta, dflt, flags;
  167.   HRESULT hr = m_CameraControl->GetRange(CameraControl_Exposure, &minExp, &maxExp, 
  168.     &stepping_delta, &dflt, &flags);
  169.   if (!SUCCEEDED(hr)) {
  170.     throw HVException("could not get exposure range from camera control");
  171.   }
  172.   
  173.   long currExp;
  174.   hr = m_CameraControl->Get(CameraControl_Exposure, &currExp, &flags);
  175.   if (!SUCCEEDED(hr)) {
  176.     throw HVException("could not get current exposure from camera control");
  177.   }
  178.   
  179.   double newval = (double)(currExp-minExp)/(double)(maxExp-minExp);
  180.   VERBOSE1(5, "DXManager: GetCurrentExposure = %f",
  181.     (float)newval);
  182.   return newval;
  183. } /* CameraControl function
  184. * true if change has an effect, false if step is too small */
  185. bool DXManager::SetExposure(double exposure)  {   VERBOSE1(5, "DXManager: SetExposure(%f) ...",
  186.     (float)exposure);
  187.   if (!m_CameraControl) {
  188.     throw HVException("no camera control found");
  189.   }
  190.   long minExp, maxExp, stepping_delta, dflt, flags;
  191.   HRESULT hr = m_CameraControl->GetRange(CameraControl_Exposure, &minExp, &maxExp, 
  192.     &stepping_delta, &dflt, &flags);
  193.   if (!SUCCEEDED(hr)) {
  194.     throw HVException("could not get exposure range from camera control");
  195.   }
  196.   
  197.   long oldExp;
  198.   hr = m_CameraControl->Get(CameraControl_Exposure, &oldExp, &flags);
  199.   if (!SUCCEEDED(hr)) {
  200.     throw HVException("could not get current exposure from camera control");
  201.   }
  202.   int newExp = (int) (exposure*(maxExp-minExp) + minExp);
  203.   flags = CameraControl_Flags_Manual;
  204.   hr = m_CameraControl->Set(CameraControl_Exposure, newExp, flags);
  205.   if (!SUCCEEDED(hr)) {
  206.     throw HVException("could not set new exposure for camera control");
  207.   }
  208.   long currExp;
  209.   hr = m_CameraControl->Get(CameraControl_Exposure, &currExp, &flags);
  210.   if (!SUCCEEDED(hr)) {
  211.     throw HVException("could not get current exposure from camera control");
  212.   }
  213.   VERBOSE1(5, "DXManager: SetExposure completed (%s)",
  214.     (oldExp!=currExp)?"changed":"unchanged");
  215.   return oldExp!=currExp;
  216. } /* CameraControl function
  217. */
  218. bool DXManager::CanAdjustExposure()  {   return m_CameraControl!=NULL;
  219. }
  220. void DXManager::ToggleFullscreen()
  221. {
  222.   long fullscreen;
  223.   CComPtr<IVideoWindow> vw = NULL;
  224.   vw = m_VideoWindow;
  225.   HRESULT hr = vw->get_FullScreenMode(&fullscreen);
  226.   if (SUCCEEDED(hr)) {
  227.     if (fullscreen==OATRUE) {
  228.       fullscreen = OAFALSE;
  229.       ReleaseCapture();
  230.       ShowCursor(true);
  231.       m_pParentView->SetTrapMouse(false);
  232.     } else {
  233.       ASSERT(fullscreen==OAFALSE);
  234.       fullscreen = OATRUE;
  235.       SetCapture(m_pParentView->m_hWnd);
  236.       ShowCursor(false);
  237.       m_pParentView->SetTrapMouse(true);
  238.     }
  239.    hr = vw->put_FullScreenMode(fullscreen);
  240.   }
  241.   if (!SUCCEEDED(hr)) {
  242.     AfxMessageBox("can not render in full-screen mode");
  243.   }
  244. }
  245. bool DXManager::RealBuildGraph()
  246. {
  247.   HRESULT hr;
  248. //  hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, 
  249. //                        IID_ICaptureGraphBuilder2, (void **)&m_GraphBuilder);
  250.   hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
  251.                         IID_IGraphBuilder, (void **)&m_GraphBuilder);
  252.   if (!SUCCEEDED(hr) || !m_GraphBuilder) { 
  253.     AfxMessageBox("Can't access graph builder interface");
  254.     return false; 
  255.   }
  256.   CreateCamera();
  257.   if (m_SourceFilter==0) {
  258.     AfxMessageBox("Can't connect to a camera");
  259.     return false;
  260.   }
  261.   if (!CreateHandVuFilter()) {
  262.     AfxMessageBox("Can't create HandVu filter");
  263.     return false;
  264.   }
  265.   /* create generic graph objects */
  266.   m_GraphBuilder->QueryInterface(IID_IMediaControl,(void**)&m_MediaControl);
  267.   m_GraphBuilder->QueryInterface(IID_IMediaEventEx,(void**)&m_MediaEventEx);
  268.   m_GraphBuilder->QueryInterface(IID_IVideoWindow, (void**)&m_VideoWindow );
  269.   m_GraphBuilder->QueryInterface(IID_IFilterGraph, (void**)&m_FilterGraph);
  270.   if (!m_FilterGraph) {
  271.     AfxMessageBox("Can't access filter graph interface");
  272.     return false;
  273.   }
  274.   if (!ConnectFilters()) {
  275.     int device;
  276.     for (device=1; device<=10; device++) {
  277.       CreateCamera(device);
  278.       if (ConnectFilters()) {
  279.         break;
  280.       }
  281.     }
  282.     if (device==11) {
  283.       AfxMessageBox("Can't connect to a camera, tried 10 devices");
  284.       return false;
  285.     }
  286.   }
  287. #ifdef DEBUG
  288.   // ROT debugging stuff
  289.   hr = AddToROT(m_GraphBuilder, &m_ROTregister);
  290.   ASSERT(SUCCEEDED(hr));
  291. #endif // DEBUG
  292.   return true;
  293. }
  294. /* link the created filters */
  295. bool DXManager::ConnectFilters()
  296. {
  297.   HRESULT hr;
  298.   bool success = false;
  299.   CComPtr<IPin> pSourceOut          = NULL;
  300.   CComPtr<IPin> pHandVuIn           = NULL;
  301.   CComPtr<IPin> pHandVuOut          = NULL;
  302.   CComPtr<IBaseFilter> pSmartTee    = NULL;
  303.   CComPtr<IBaseFilter> pColorConv   = NULL;
  304.   CComPtr<IPin> pProcessThis        = NULL;
  305.   CComPtr<IBaseFilter> pAppRenderer = NULL;
  306.   CComPtr<IPin> pSmartTPreviewOut   = NULL;
  307.   // get a video output pin
  308.   hr = AddFilter(m_SourceFilter, L"Video Source" );
  309.   pSourceOut = GetVideoPin(m_SourceFilter, PINDIR_OUTPUT);
  310.   if (!SUCCEEDED(hr) || pSourceOut==NULL) goto release_and_return;
  311.   // make two application windows
  312.   if (!m_two_windows) {
  313.     pProcessThis = pSourceOut;
  314.   } else {
  315.     hr = CoCreateInstance(CLSID_SmartTee, NULL, CLSCTX_INPROC_SERVER, 
  316.                       IID_IBaseFilter, (void**)&pSmartTee);
  317.     if (!SUCCEEDED(hr)) goto release_and_return;
  318.     hr = AddFilter(pSmartTee, L"SmartT");
  319.     CComPtr<IPin> pSmartTIn         = GetPin(pSmartTee, PINDIR_INPUT);
  320.     CComPtr<IPin> pSmartTCaptureOut = GetPin(pSmartTee, PINDIR_OUTPUT, 0);//, &PIN_CATEGORY_CAPTURE);
  321.     pSmartTPreviewOut = GetPin(pSmartTee, PINDIR_OUTPUT, 1);//, &PIN_CATEGORY_PREVIEW);
  322.     if (!SUCCEEDED(hr) || !pSmartTIn || !pSmartTCaptureOut || !pSmartTPreviewOut) goto release_and_return;
  323.     hr = ConnectPins(pSourceOut, pSmartTIn);
  324.     if (!SUCCEEDED(hr)) goto release_and_return;
  325.     hr = CoCreateInstance( CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, 
  326.       IID_IBaseFilter, (void**)&pAppRenderer );
  327.     if (!SUCCEEDED(hr)) goto release_and_return;
  328.     pAppRenderer->QueryInterface(IID_IVideoWindow,(void**)&m_SourceVideoWindow);
  329.     if (!SUCCEEDED(hr) || !m_SourceVideoWindow) goto release_and_return;
  330.     m_SourceWin.m_pDXManager = this;
  331.     if (m_SourceWin.m_hWnd==NULL) {
  332.   //    m_SourceWin.CreateEx(NULL, "", "source display", WS_POPUP | WS_MAXIMIZE, CRect(10, 10, 300, 200), m_pParent, 1, NULL);
  333.       m_SourceWin.Create(NULL, "source display", WS_CHILD, CRect(50, 50, 160, 120), m_pParentView, 1, NULL);
  334.     }
  335.     m_SourceVideoWindow->put_Owner((OAHWND)m_SourceWin.m_hWnd);
  336.     m_SourceVideoWindow->put_MessageDrain((OAHWND)m_SourceWin.m_hWnd);
  337.     m_SourceVideoWindow->SetWindowPosition(50, 50, 160, 120);
  338.     hr = CoCreateInstance( CLSID_Colour, NULL, CLSCTX_INPROC_SERVER, 
  339.     IID_IBaseFilter, (void**)&pColorConv );
  340.     if (!SUCCEEDED(hr) || !pColorConv) goto release_and_return;
  341.     CComPtr<IPin> pColorConvIn    = GetPin(pColorConv, PINDIR_INPUT);
  342.     CComPtr<IPin> pColorConvOut   = GetPin(pColorConv, PINDIR_OUTPUT);
  343.     hr = AddFilter(pColorConv, L"Source Renderer" );
  344.     if (!SUCCEEDED(hr)) goto release_and_return;
  345.     hr = ConnectPins(pSmartTCaptureOut, pColorConvIn );
  346.     if (!SUCCEEDED(hr)) goto release_and_return;
  347.     pSmartTIn.Release();
  348.     pProcessThis = pColorConvOut;
  349.   }
  350.   hr = AddFilter(m_HandVuFilter, L"HandVuFilter");
  351.   pHandVuIn         = GetPin(m_HandVuFilter, PINDIR_INPUT);
  352.   pHandVuOut        = GetPin(m_HandVuFilter, PINDIR_OUTPUT);
  353.   if (!SUCCEEDED(hr) || !pHandVuIn || !pHandVuOut) goto release_and_return;
  354.   hr = ConnectPins(pProcessThis, pHandVuIn);      
  355.   if (!SUCCEEDED(hr)) goto release_and_return;
  356.   if (!InitHandVuFilter()) goto release_and_return;
  357.   hr = m_GraphBuilder->Render(pHandVuOut);
  358.   if (!SUCCEEDED(hr)) goto release_and_return;
  359.   if (m_two_windows) {
  360.     CComPtr<IPin> pAppRendererIn    = GetPin(pAppRenderer, PINDIR_INPUT);
  361.     hr = AddFilter(pAppRenderer, L"Source Renderer" );
  362.     if (!SUCCEEDED(hr) || !pAppRendererIn) goto release_and_return;
  363.     hr = ConnectPins(pSmartTPreviewOut, pAppRendererIn );
  364.     if (!SUCCEEDED(hr)) goto release_and_return;
  365.     m_SourceWin.EnableWindow(TRUE);
  366.     m_SourceWin.Invalidate();
  367.     pAppRenderer.Release();
  368.     pAppRendererIn.Release();
  369. //    pSmartTCaptureOut.Release();
  370.   }
  371.   success = true;
  372. release_and_return:
  373.   pProcessThis.Release();
  374.   pHandVuIn.Release();
  375.   pHandVuOut.Release();
  376.   pSmartTee.Release();
  377.   pAppRenderer.Release();
  378.   pSmartTPreviewOut.Release();
  379.   return success;
  380. }
  381. // Destroy DirectShow Filter Graph
  382. void DXManager::DestroyFilterGraph()
  383. {
  384.   if (m_FilterGraph) {
  385.     CComPtr<IEnumFilters> pEnumFilters = 0;
  386.     m_FilterGraph->EnumFilters( &pEnumFilters );
  387.     if( pEnumFilters ) {
  388.       CComPtr<IBaseFilter> pFilter = 0;
  389.       ULONG cFetched = 0;
  390.       while( pEnumFilters->Next( 1, &pFilter, &cFetched ) == S_OK && pFilter != 0 ) {
  391.         m_FilterGraph->RemoveFilter( pFilter );
  392.         pFilter.Release();
  393.         cFetched = 0;
  394.       }
  395.       pEnumFilters.Release();
  396.     }
  397.   }
  398. #ifdef DEBUG
  399.   RemoveFromROT(m_ROTregister);
  400. #endif
  401.   m_GraphBuilder.Release();
  402.   m_MediaControl.Release();
  403.   m_MediaEventEx.Release();
  404.   m_FilterGraph.Release();
  405.   m_HandVuFilter.Release();
  406.   m_HandVuFilterProp.Release();
  407.   m_SourceFilter.Release();
  408.   m_CameraControl.Release();
  409.   m_VideoWindow.Release();
  410.   m_SourceVideoWindow.Release();
  411.   NullComPtrs();
  412. }
  413. bool DXManager::CreateHandVuFilter()
  414. {
  415.   HRESULT hr = CoCreateInstance( CLSID_HandVuFilter, NULL, CLSCTX_INPROC_SERVER, 
  416.                              IID_IBaseFilter, (void**)&m_HandVuFilter );
  417.   if (SUCCEEDED(hr)) {
  418.     m_HandVuFilter->QueryInterface(IID_IHandVuFilter, (void**)&m_HandVuFilterProp);
  419.   }
  420.   if (m_HandVuFilterProp) {
  421.     
  422.     hr = m_HandVuFilterProp->AddListener(this);
  423.     ASSERT(SUCCEEDED(hr));
  424.     
  425.     if (m_pIAMTCReader) {
  426.       hr = m_HandVuFilterProp->SetTimecodeReader(m_pIAMTCReader);
  427.       ASSERT(SUCCEEDED(hr));
  428.     }
  429.     hr = m_HandVuFilterProp->SetVerbosity(g_verbose, m_handvu_logfilename);
  430.     ASSERT(SUCCEEDED(hr));
  431.   }
  432.   return m_HandVuFilterProp != 0;
  433. }
  434. bool DXManager::InitHandVuFilter()
  435. {
  436.   ASSERT(m_SourceFilter);
  437.   CComPtr<IPin> pPin = GetVideoPin(m_SourceFilter, PINDIR_OUTPUT);
  438.   AM_MEDIA_TYPE media_type;
  439.   pPin->ConnectionMediaType(&media_type);
  440.   BITMAPINFOHEADER* pHdr=NULL;
  441.   if (media_type.formattype==FORMAT_VideoInfo) {
  442.     pHdr = &((VIDEOINFOHEADER*) media_type.pbFormat)->bmiHeader;
  443.   } else if (media_type.formattype==FORMAT_VideoInfo2) {
  444.     pHdr = &((VIDEOINFOHEADER2*) media_type.pbFormat)->bmiHeader;
  445.   } else {
  446.     return false;
  447.   }
  448.   ASSERT(pHdr);
  449.   int width = pHdr->biWidth;
  450. int height = pHdr->biHeight;
  451.   int iPixelSize = pHdr->biBitCount / 8;
  452.   HRESULT hr = m_HandVuFilterProp->Initialize(width, height, iPixelSize, this);
  453.   ASSERT(SUCCEEDED(hr));
  454.   return SUCCEEDED(hr);
  455. }
  456. bool DXManager::CreateCamera( int idx )
  457. {
  458.   CComPtr<ICreateDevEnum> pCreateDevEnum = 0;
  459.   CComPtr<IEnumMoniker>   pEnumMon = 0;
  460.   ULONG           cFetched = 0;
  461.   m_SourceFilter.Release();
  462.   CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
  463.                 IID_ICreateDevEnum, (void**)&pCreateDevEnum );
  464.   /* Create capture device */
  465.   if( pCreateDevEnum ) {
  466.     CComPtr<IMoniker> pMon = 0;
  467.     pCreateDevEnum->CreateClassEnumerator( CLSID_VideoInputDeviceCategory, &pEnumMon, 0);
  468.     if( pEnumMon && idx > 0 ) {
  469.       pEnumMon->Skip( idx );
  470.       ASSERT(0); // need to give user a choice
  471.     }
  472.     if( pEnumMon && SUCCEEDED( pEnumMon->Next(1, &pMon, &cFetched)) && cFetched == 1 ) {
  473.       pMon->BindToObject(0, 0, IID_IBaseFilter, (void **)&m_SourceFilter );
  474.       pMon.Release();
  475.     }
  476.     pEnumMon.Release();
  477.     pCreateDevEnum.Release();
  478.   }
  479.   if (!m_SourceFilter) {
  480.     // try file input
  481.     CFileDialog open_dlg(true, 0, 0, OFN_FILEMUSTEXIST, 
  482.       "All Media Files (*.avi;*.mpg;*.mpeg;*.mov;*.wm;*.wmv;*.wma)|*.avi; *.mpg; *.mpeg; *.mov; *.wm; *.wmv; *.wma|"
  483.       "Movie Files (*.avi;*.mpg;*.mpeg;*.mov)|*.avi; *.mpg; *.mpeg; *.mov|"
  484.       "Windows Media Files (*.wm;*.wmv;*.wma)|*.wm;*.wmv;*.wma|"
  485.       "All Files (*.*)|*.*||");
  486.     if (open_dlg.DoModal()==IDOK) {
  487.       CString str = open_dlg.GetPathName();
  488.       if (str.GetLength()>0) {
  489.         WCHAR wname[1000] = L"";
  490.         MultiByteToWideChar( CP_ACP, 0, str, -1, wname, sizeof(wname)/2 );
  491.         HRESULT hr = m_GraphBuilder->AddSourceFilter(wname, L"Mmh da sauze filter", &m_SourceFilter);
  492.         if (!SUCCEEDED(hr) || m_SourceFilter==NULL) {
  493.           VERBOSE0(3, "DXManager: could not add source filter");
  494.           return false;
  495.         }
  496.       }
  497.     }
  498.   }
  499.   if (m_SourceFilter) {
  500.     HRESULT hr = m_SourceFilter->QueryInterface(IID_IAMCameraControl, (void **)&m_CameraControl);
  501.     if (SUCCEEDED(hr) && m_CameraControl) {
  502.       VERBOSE0(5, "IAMCameraControl is implemented");
  503.       // make sure it works
  504.       try {
  505.         double exposure = GetCurrentExposure();
  506.         double new_exposure = SetExposure(exposure);
  507.       } catch (HVException& hve) {
  508.         VERBOSE1(2, "IAMCameraControl operation test failed: %s",
  509.           hve.GetMessage().c_str());
  510.         m_CameraControl.Release();
  511.         m_CameraControl = NULL;
  512.       }
  513.       if (m_CameraControl) {
  514.         VERBOSE0(5, "IAMCameraControl functional - got CameraController");
  515.       }
  516.     } else {
  517.       VERBOSE0(2, "IAMCameraControl not implemented");
  518.     }
  519.     hr = m_SourceFilter->QueryInterface(IID_IAMTimecodeReader, (void **) &m_pIAMTCReader);
  520.     if (!SUCCEEDED(hr)) {
  521.       VERBOSE0(3, "DXManager: no DV TimecodeReader available");
  522.       m_pIAMTCReader = NULL;
  523.     }
  524.   }
  525.   return m_SourceFilter != 0;
  526. }
  527. #ifdef DEBUG
  528. /////////////////////////////////////////////////////////////////////////////
  529. // this allows GraphEdit to connect to the filter graph
  530. // (File ... connect)
  531. HRESULT DXManager::AddToROT(IUnknown *pUnkGraph, DWORD *pdwRegister) 
  532. {
  533.   IMoniker * pMoniker;
  534.   IRunningObjectTable *pROT;
  535.   if (FAILED(GetRunningObjectTable(0, &pROT))) {
  536.     return E_FAIL;
  537.   }
  538.   int const sz = 256;
  539.   WCHAR wsz[sz];
  540.   size_t cbDest = sz * sizeof(WCHAR);
  541. //  StringCbPrintfW(wsz, cbDest, L"FilterGraph %08p pid %08x", (DWORD *) pUnkGraph, GetCurrentProcessId());
  542.   wsprintfW(wsz, L"FilterGraph %08p pid %08x", (DWORD *) pUnkGraph, GetCurrentProcessId());
  543.   HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
  544.   //HRESULT hr = CreateItemMoniker(L"!", L"HandVuDXApp", &pMoniker);
  545.   if (SUCCEEDED(hr)) {
  546.     hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
  547.     pMoniker->Release();
  548.   }
  549.   pROT->Release();
  550.   return hr;
  551. }
  552. /////////////////////////////////////////////////////////////////////////////
  553. // remove filter graph from Running Object Table
  554. void DXManager::RemoveFromROT(DWORD pdwRegister)
  555. {
  556.   IRunningObjectTable *pROT;
  557.   if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
  558.     pROT->Revoke(pdwRegister);
  559.     pROT->Release();
  560.   }
  561. }
  562. #endif // DEBUG
  563. void DXManager::GetVideoSourceSize(int* pWidth, int* pHeight) 
  564. {
  565.   *pWidth = -1;
  566. *pHeight = -1;
  567.   if (m_SourceFilter!=0) {
  568.     CComPtr<IPin> pPin = GetVideoPin(m_SourceFilter, PINDIR_OUTPUT);
  569.     AM_MEDIA_TYPE media_type;
  570.     pPin->ConnectionMediaType(&media_type);
  571.     BITMAPINFOHEADER* pHdr=NULL;
  572.     if (media_type.formattype==FORMAT_VideoInfo) {
  573.       pHdr = &((VIDEOINFOHEADER*) media_type.pbFormat)->bmiHeader;
  574.     } else if (media_type.formattype==FORMAT_VideoInfo2) {
  575.       pHdr = &((VIDEOINFOHEADER2*) media_type.pbFormat)->bmiHeader;
  576.     }
  577.     if (pHdr!=NULL) {
  578.       *pWidth = pHdr->biWidth;
  579.    *pHeight = abs(pHdr->biHeight);
  580.       VERBOSE2(4, "DXManager: got real size %d %d", *pWidth, *pHeight);
  581.     }
  582.   } 
  583.   if (*pWidth==-1 || *pHeight==-1)  {
  584.     *pWidth = 640;
  585.   *pHeight = 480;
  586.     VERBOSE2(4, "DXManager: got fake size %d %d", *pWidth, *pHeight);
  587.   }
  588. }
  589. void DXManager::SetVideoWindowPosition(int left, int top, int width, int height) 
  590. {
  591.   if (m_VideoWindow) {
  592.     VERBOSE4(4, "DXManager: setting left %d, top %d, width %d, height %d", 
  593.       left, top, width, height);
  594.     m_VideoWindow->SetWindowPosition( left, top, width, height );
  595.   }
  596. }
  597. void DXManager::SetSourceVideoWindowPosition(int left, int top, int width, int height) 
  598. {
  599.   if (m_SourceVideoWindow) {
  600.     m_SourceVideoWindow->SetWindowPosition( left, top, width, height );
  601.   }
  602. }
  603. HRESULT DXManager::AddFilter(IBaseFilter* filter, LPCWSTR name) {
  604.   HRESULT hr = m_FilterGraph->AddFilter(filter, name);
  605. #ifdef DEBUG
  606.   if (!SUCCEEDED(hr)) {
  607.     char buf[MAX_ERROR_TEXT_LEN];
  608.     AMGetErrorText(hr, buf, MAX_ERROR_TEXT_LEN);
  609.     ASSERT(0);
  610.   }
  611. #endif // DEBUG
  612.   return hr;
  613. }
  614. HRESULT DXManager::ConnectPins(IPin* from, IPin* to) {
  615.   HRESULT hr = m_GraphBuilder->Connect(from, to);
  616. #ifdef DEBUG
  617.   if (!SUCCEEDED(hr)) {
  618.     char buf[MAX_ERROR_TEXT_LEN];
  619.     AMGetErrorText(hr, buf, MAX_ERROR_TEXT_LEN);
  620.     ASSERT(0);
  621.   }
  622. #endif // DEBUG
  623.   return hr;
  624. }
  625. void DXManager::GetVersion(string& version) const
  626. {
  627.   string dxm_version = "DXManager: $Id: DXManager.cpp,v 1.14 2005/10/30 23:00:43 matz Exp $";
  628.   string filter_version = "no HandVuFilter loaded";
  629.   if (m_HandVuFilterProp) {
  630.     HRESULT hr = m_HandVuFilterProp->GetVersion(filter_version);
  631.     ASSERT(SUCCEEDED(hr));
  632.   }
  633.   version = dxm_version + "n" + filter_version;
  634. }
  635. BOOL PinMatchesCategory(CComPtr<IPin> pPin, const GUID& Category)
  636. {
  637.   if (pPin == NULL) {
  638.     return false;
  639.   }
  640.   BOOL bFound = FALSE;
  641.   IKsPropertySet *pKs;
  642.   HRESULT hr = pPin->QueryInterface(IID_IKsPropertySet, (void **)&pKs);
  643.   if (SUCCEEDED(hr))
  644.   {
  645.     GUID PinCategory;
  646.     DWORD cbReturned;
  647.     hr = pKs->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0, 
  648.       &PinCategory, sizeof(GUID), &cbReturned);
  649.     if (SUCCEEDED(hr))
  650.     {
  651.       bFound = (PinCategory == Category);
  652.     }
  653.     pKs->Release();
  654.   }
  655.   return bFound;
  656. }
  657. static CComPtr<IPin> GetPin(CComPtr<IBaseFilter> pFilter, PIN_DIRECTION PinDir, int skip/*=0*/, const GUID* pCategory /*= NULL*/)
  658. {
  659.     CComPtr<IEnumPins>  pEnum;
  660.     CComPtr<IPin>       pPin;
  661.     HRESULT hr = pFilter->EnumPins(&pEnum);
  662.     if (FAILED(hr)) {
  663.         return NULL;
  664.     }
  665.     while((hr=pEnum->Next(1, &pPin.p, 0)) == S_OK) {
  666.         PIN_DIRECTION PinDirThis;
  667.         pPin->QueryDirection(&PinDirThis);
  668.         if (PinDir==PinDirThis) {
  669.           if (pCategory==NULL || PinMatchesCategory(pPin, *pCategory)) {
  670.             if (skip) {
  671.               skip--;
  672.             } else {
  673.               break;
  674.             }
  675.           }
  676.         }
  677.         pPin.Release();
  678.     }
  679.     pEnum.Release();
  680.     return pPin;  
  681. }
  682. // get a video output pin
  683. static CComPtr<IPin> GetVideoPin(CComPtr<IBaseFilter> pFilter, PIN_DIRECTION PinDir) //, int skip/*=0*/, const GUID* pCategory /*= NULL*/)
  684. {
  685.   CComPtr<IPin>       pPin;
  686.   bool got_one = false;
  687.   int skip = 0;
  688.   BITMAPINFOHEADER* pHdr=NULL;
  689.   do {
  690.     pPin = GetPin(pFilter, PINDIR_OUTPUT, skip);
  691.     if (pPin==NULL) {
  692.       return NULL;
  693.     }
  694.     CComPtr<IEnumMediaTypes> pEnum;
  695.     HRESULT hr = pPin->EnumMediaTypes(&pEnum);
  696.     if (!SUCCEEDED(hr) || !pEnum) return NULL;
  697.     AM_MEDIA_TYPE* pMediaType = NULL;
  698.     hr = pEnum->Next(1, &pMediaType, NULL);
  699.     while (hr==S_OK) {
  700.       if (pMediaType->formattype==FORMAT_VideoInfo || 
  701.           pMediaType->majortype==MEDIATYPE_Video || 
  702.           pMediaType->majortype==MEDIATYPE_Interleaved || 
  703.           pMediaType->majortype==MEDIATYPE_Stream || 
  704.           pMediaType->majortype==MEDIATYPE_AnalogVideo) 
  705.       {
  706.         DeleteMediaType(pMediaType);
  707.         pMediaType = NULL;
  708.         got_one = true;
  709.         break;
  710.       }
  711.       DeleteMediaType(pMediaType);
  712.       pMediaType = NULL;
  713.       hr = pEnum->Next(1, &pMediaType, NULL);
  714.     }
  715.     skip++;
  716.     if (!got_one) {
  717.       pPin.Release();
  718.     }
  719.   } while (!got_one);
  720.   return pPin;
  721. }
  722. IMPLEMENT_DYNCREATE(CSourceView, CScrollView)
  723. BEGIN_MESSAGE_MAP(CSourceView, CScrollView)
  724.   ON_WM_SIZE()
  725. END_MESSAGE_MAP()
  726. CSourceView::CSourceView()
  727. {
  728. }
  729. CSourceView::~CSourceView()
  730. {
  731. }
  732. BOOL CSourceView::PreCreateWindow(CREATESTRUCT& cs)
  733. {
  734. return CView::PreCreateWindow(cs);
  735. }
  736. void CSourceView::OnInitialUpdate()
  737. {
  738. CScrollView::OnInitialUpdate();
  739.   SetVideoWindowSize(0, 0);
  740. }
  741. void CSourceView::OnSize(UINT nType, int cx, int cy) 
  742. {
  743. CScrollView::OnSize(nType, cx, cy);
  744.   SetVideoWindowSize(cx, cy);
  745. Invalidate(true);
  746. }
  747. void CSourceView::SetVideoWindowSize(int width, int height) 
  748. {
  749.   int source_width, source_height;
  750.   m_pDXManager->GetVideoSourceSize(&source_width, &source_height);
  751.   if (source_height<0) {
  752.     source_height = -source_height;
  753.   }
  754.   CRect rc;
  755.   GetClientRect( &rc );
  756.   if (width==0 && height==0) {
  757.     width = source_width;
  758.     height = source_height;
  759. //      MoveWindow(&rc);
  760.   } else {
  761.     width = max(width, source_width);
  762.     height = max(height, source_height);
  763.     double ratio = (double)source_width/(double)source_height;
  764.     width = min(width, (int)((double)height*ratio));
  765.     height = min(height, (int)((double)width/ratio));
  766.   }
  767.   m_pDXManager->SetSourceVideoWindowPosition( rc.left, rc.top, width, height );
  768. SetScrollSizes(MM_TEXT, CSize(source_width, source_height));
  769. }