Main Page | Class Hierarchy | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages | Examples

vetDirectXInput.cpp

Go to the documentation of this file.
00001 
00015 // cercare @ microsoft :  isamplegrabber !!!
00016 
00017 #include "vetDirectXInput.h"
00018 
00019 
00020 #include <dshow.h>
00021 #include <qedit.h>
00022 
00023 
00024 #define _WIN32_WINNT 0x0500   // Because of TryEnterCriticalSection ???????????????????????
00025 
00026 
00027 
00028 
00029 #define SafeRelease(p) { if( (p) != 0 ) { (p)->Release(); (p)= NULL; } }
00030 
00031 /*
00032   The Direct Show Graph is composed by 3 components:
00033     capture source, sample grabber and null renderer.
00034 
00035   Filters are connected:
00036     capture_filter(out)->(in)grabber_filter(out)->(in)null_filter
00037 
00038   But when the graph is rendered other transform filters
00039   can be inserted to connect the capture and the grabber.
00040 
00041   We do not use MFC, ATL and the Direct Show Base Classes.
00042   This module only needs the library "strmiids.lib".
00043   If the extra error functions were used, you will need to link with "quartz.lib" or "dxerr9.lib".
00044 
00045   We use the buffer of the ISampleGrabber. But this can not be done in a user callback,
00046   so we leave the grab loop for the application, it can also be done in the idle function.
00047 
00048   If you use the idle function the WDM Source Dialog is not "live"
00049   just because it is a modal dialog and
00050   it does not use the application message loop.
00051   It can be live using a timer.
00052 
00053   Since there is no gray format, bpp is always 24bpp.
00054 */
00055 
00056 
00057 
00058 
00059 /**************************************************************************
00060                        imTrackingGrabberCB
00061 ***************************************************************************/
00062 
00063 // This is better than using the sample grabber internal buffer
00064 // because we have a more precise control of the data flow.
00065 
00066 class imTrackingGrabberCB :     public ISampleGrabberCB
00067  {
00068         protected:
00069                 int  m_Width, m_Height;
00070                 bool    m_newImageFlag;
00071                 unsigned char *m_ImageData;
00072                 CRITICAL_SECTION m_sect;
00073                 HANDLE m_imageReady;
00074 
00075         public:
00076 
00077                 imTrackingGrabberCB();
00078                 ~imTrackingGrabberCB();
00079 
00080                 STDMETHODIMP SampleCB(double SampleTime, IMediaSample *pSample);
00081                 STDMETHODIMP BufferCB(double SampleTime, BYTE *pBuffer, long BufferLen) {return E_NOTIMPL;}
00082                 STDMETHODIMP_(ULONG) AddRef() {return 2;}
00083                 STDMETHODIMP_(ULONG) Release() {return 1;}
00084                 STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);
00085 
00086                 void SetImageSize(int width, int height);
00087                 int GetImage(unsigned char* data, int color_mode, int timeout);
00088 
00089  };
00090 
00091 imTrackingGrabberCB::imTrackingGrabberCB()
00092  {
00093         InitializeCriticalSection(&m_sect);
00094         m_newImageFlag = 0;
00095         m_ImageData = NULL;
00096         m_imageReady = CreateEvent(NULL, FALSE, TRUE, NULL);
00097  }
00098 
00099 imTrackingGrabberCB::~imTrackingGrabberCB()
00100  {
00101         CloseHandle(m_imageReady);
00102         EnterCriticalSection(&m_sect);
00103         DeleteCriticalSection(&m_sect);
00104         if (m_ImageData)
00105                 delete m_ImageData;
00106  }
00107 
00108 STDMETHODIMP imTrackingGrabberCB::QueryInterface(REFIID riid, void ** ppv)
00109  {
00110         if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown )
00111          {
00112                 *ppv = (void *) static_cast<ISampleGrabberCB*> (this);
00113                 return NOERROR;
00114          }
00115 
00116         return E_NOINTERFACE;
00117  }
00118 
00119 void imTrackingGrabberCB::SetImageSize(int width, int height)
00120  {
00121         EnterCriticalSection(&m_sect);
00122 
00123         // This can be done because the capture system always returns
00124         // images that are a multiple of 4.
00125         int new_size = width * height * 3;
00126 
00127         if (!m_ImageData)
00128          {
00129                 m_ImageData = (BYTE*)calloc(new_size, 1);
00130                 m_Width = width;
00131                 m_Height = height;
00132          }
00133 
00134         if (m_Width*m_Height < new_size)
00135         m_ImageData = (BYTE*)realloc(m_ImageData, new_size);
00136 
00137         m_Width = width;
00138         m_Height = height;
00139 
00140         LeaveCriticalSection(&m_sect);
00141 }
00142 
00143 STDMETHODIMP imTrackingGrabberCB::SampleCB(double, IMediaSample *pSample)
00144 {
00145   if (!m_ImageData) return S_OK;
00146 
00147   EnterCriticalSection(&m_sect);
00148 
00149   int size = pSample->GetSize();
00150   if (size > m_Width*m_Height*3)
00151   {
00152     LeaveCriticalSection(&m_sect);
00153     return S_OK;
00154   }
00155 
00156   BYTE *pData;
00157   pSample->GetPointer(&pData);
00158   CopyMemory(m_ImageData, pData, size);
00159   m_newImageFlag = 1;
00160 
00161   LeaveCriticalSection(&m_sect);
00162 
00163   SetEvent(m_imageReady);
00164 
00165   return S_OK;
00166 }
00167 
00168 int imTrackingGrabberCB::GetImage(unsigned char* data, int color_mode, int timeout)
00169 {
00170         unsigned char* src_data = m_ImageData + m_Width * m_Height * 3;
00171         unsigned char* dst_data = data;
00172 
00173         EnterCriticalSection(&m_sect);
00174 
00175         for (int i = 0; i < m_Width*m_Height; i++)
00176          {
00177                 *(dst_data+2) = *src_data--;
00178                 *dst_data = *src_data--;
00179                 *(dst_data+1) = *src_data--;
00180                 dst_data += 3;
00181          }
00182 
00183         LeaveCriticalSection(&m_sect);
00184 
00185         return VETRET_OK;
00186 }
00187 
00188 
00189 
00190 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 //DX RELATED
00201 
00202 //defined here so application DOES NOT NEED DX headers (and libs)
00203 struct vetDXCapture
00204 {
00205   int registered_graph,
00206       live,
00207       device;                     /* current connected device. -1 if not connected. */
00208 
00209 //  char* dialog_desc[6];
00210 //  vcDialogFunc dialog_func[6];
00211 //  int dialog_count;                /* number of available configuration dialogs for the current connection. */
00212 
00213   IGraphBuilder* filter_builder;  /* The Filter Graph Manager */
00214   ICaptureGraphBuilder2* capture_graph_builder; /* Helps the Filter Graph Manager */
00215   IBaseFilter* capture_filter;    /* the capture device (can vary), it's a source filter. */
00216   IBaseFilter* grabber_filter;    /* returns the capture data, it's a transform filter */
00217   IBaseFilter* null_filter;       /* does nothing, act as a terminator, it's a rendering filter */
00218   ISampleGrabber* sample_grabber; /* Used to access the ISampleGrabber interface, since grabber_filter is a generic IBaseFilter interface based on ISampleGrabber. */
00219   IMediaControl* media_control;   /* Used to Run and Stop the graph flow. */
00220   IBaseFilter* overlay_renderer;  /* Used when there is a video port without a preview */
00221   IBaseFilter *overlay_mixer;
00222 
00223   IAMVideoProcAmp* video_prop;    /* Used to set/get video properties */
00224   IAMCameraControl* camera_prop;  /* Used to set/get camera properties */
00225   IAMVideoControl* videoctrl_prop; /* Used to set/get video properties */
00226 
00227   imTrackingGrabberCB* sample_callback; /* Used to intercept the samples. */
00228 
00229   int format_count;   /* number of supported formats */
00230   int format_current; /* current format */
00231   int format_map[50]; /* table to map returned formats to direct X formats */
00232 
00233 
00234   ISpecifyPropertyPages *pSpec; //capture filter property page
00235 
00236 
00237 
00238 
00239 
00240 /*
00241     IAMStreamConfig *pVSC;      // for video cap
00242 
00243 
00244     double FrameRate;
00245     BOOL fWantPreview;
00246     long lCapStartTime;
00247     long lCapStopTime;
00248 
00249 
00250     BOOL fUseTimeLimit;
00251     BOOL fUseFrameRate;
00252     DWORD dwTimeLimit;
00253 
00254     BOOL fCapturing;
00255     BOOL fPreviewing;
00256 
00257 
00258     long lDroppedBase;
00259     long lNotBase;
00260 */
00261 };
00262 
00263 
00264 
00265 
00266 
00267 
00268 /*
00269 
00270 used in:
00271 
00272 */
00273 
00274 #ifdef INCLUDE_VFW_DEVICES
00275 #define CATEGORY_FLAG 0
00276 #else
00277 #define CATEGORY_FLAG CDEF_DEVMON_FILTER|CDEF_DEVMON_PNP_DEVICE
00278 #endif
00279 
00280 IBaseFilter* vetGetDevice(int device)
00281 {
00282   // Selecting a Capture Device
00283   ICreateDevEnum *pDevEnum = NULL;
00284   IEnumMoniker *pEnum = NULL;
00285 
00286   // Create the System Device Enumerator.
00287   HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
00288                                 CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
00289                                 reinterpret_cast<void**>(&pDevEnum));
00290   if (FAILED(hr)) return NULL;
00291 
00292   // Create an enumerator for the video capture category.
00293   hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, CATEGORY_FLAG);
00294   if (FAILED(hr) || !pEnum)
00295   {
00296     pDevEnum->Release();
00297     return NULL;
00298   }
00299 
00300   IMoniker *pMoniker = NULL;
00301   int d = 0;
00302   while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
00303   {
00304     if (d == device)
00305     {
00306       //create the capture filter for the device
00307       //add the filter to the filter graph
00308       IBaseFilter *capture_filter = NULL;
00309       hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&capture_filter);
00310       if (SUCCEEDED(hr))
00311       {
00312         pMoniker->Release();
00313         pEnum->Release();
00314         pDevEnum->Release();
00315         return capture_filter;
00316       }
00317       else
00318       {
00319         pMoniker->Release();
00320         break;
00321       }
00322     }
00323 
00324     pMoniker->Release();
00325     d++;
00326   }
00327 
00328   pEnum->Release();
00329   pDevEnum->Release();
00330   return NULL;
00331 }
00332 
00333 
00334 IPin* vetGetPin(IBaseFilter* pFilter, PIN_DIRECTION dir)
00335 {
00336   IEnumPins*  pEnumPins = NULL;
00337   IPin*       pPin = NULL;
00338 
00339   pFilter->EnumPins(&pEnumPins);
00340   if(!pEnumPins)
00341     return NULL;
00342 
00343   for(;;)
00344   {
00345     ULONG  cFetched = 0;
00346     PIN_DIRECTION pinDir = PIN_DIRECTION(-1);
00347     pPin = 0;
00348 
00349     if (FAILED(pEnumPins->Next(1, &pPin, &cFetched)))
00350     {
00351       pEnumPins->Release();
00352       return NULL;
00353     }
00354 
00355     if(cFetched == 1 && pPin != 0)
00356     {
00357       pPin->QueryDirection(&pinDir);
00358       if(pinDir == dir) break;
00359       pPin->Release();
00360     }
00361   }
00362 
00363   pEnumPins->Release();
00364   return pPin;
00365 }
00366 
00367 void vetNukeDownstream(IGraphBuilder* filter_builder, IBaseFilter *filter)
00368 {
00369   IPin *pPin=0, *pPinTo=0;
00370   IEnumPins *pEnumPins = NULL;
00371   PIN_INFO pininfo;
00372 
00373   HRESULT hr = filter->EnumPins(&pEnumPins);
00374   if (FAILED(hr)) return;
00375 
00376   pEnumPins->Reset();
00377 
00378   while(hr == NOERROR)
00379   {
00380     hr = pEnumPins->Next(1, &pPin, NULL);
00381     if(hr == S_OK && pPin)
00382     {
00383       pPin->ConnectedTo(&pPinTo);
00384       if(pPinTo)
00385       {
00386         hr = pPinTo->QueryPinInfo(&pininfo);
00387         if(hr == NOERROR)
00388         {
00389           if(pininfo.dir == PINDIR_INPUT)
00390           {
00391             vetNukeDownstream(filter_builder, pininfo.pFilter);
00392             filter_builder->Disconnect(pPinTo);
00393             filter_builder->Disconnect(pPin);
00394             filter_builder->RemoveFilter(pininfo.pFilter);
00395           }
00396 
00397           pininfo.pFilter->Release();
00398         }
00399 
00400         pPinTo->Release();
00401       }
00402 
00403       pPin->Release();
00404     }
00405   }
00406 
00407   pEnumPins->Release();
00408 
00409 }
00410 
00411 int vetDisconnectFilters(IGraphBuilder* filter_builder, IBaseFilter* source, IBaseFilter* destiny)
00412  {
00413         IPin *pOut = vetGetPin(source, PINDIR_OUTPUT);
00414         IPin *pIn = vetGetPin(destiny, PINDIR_INPUT);
00415         HRESULT hr = filter_builder->Disconnect(pOut);
00416         hr = filter_builder->Disconnect(pIn);
00417         pOut->Release();
00418         pIn->Release();
00419 
00420         if (FAILED(hr)) //  if (HARDFAILED(hr))
00421                 return VETRET_INTERNAL_ERR;
00422 
00423         return VETRET_OK;
00424  }
00425 
00426 int vetDisconnectFilterPin(IGraphBuilder* filter_builder, IBaseFilter* filter, PIN_DIRECTION dir)
00427  {
00428         IPin *pIn = vetGetPin(filter, dir);
00429         IPin *pOut;
00430         pIn->ConnectedTo(&pOut);
00431 
00432         HRESULT hr = filter_builder->Disconnect(pIn);
00433         pIn->Release();
00434 
00435         if (FAILED(hr)) //  if (HARDFAILED(hr))
00436          {
00437                 if (pOut)
00438                         pOut->Release();
00439                 return VETRET_INTERNAL_ERR;
00440          }
00441 
00442         if (pOut)
00443          {
00444                 hr = filter_builder->Disconnect(pOut);
00445                 pOut->Release();
00446 
00447                 if (FAILED(hr)) //  if (HARDFAILED(hr))
00448                         return VETRET_INTERNAL_ERR;
00449          }
00450 
00451         return VETRET_OK;
00452 }
00453 
00454 int vetConnectFilters(IGraphBuilder* filter_builder, IBaseFilter* source, IBaseFilter* destiny, int direct)
00455  {
00456         HRESULT hr;
00457 
00458         IPin *pOut = vetGetPin(source, PINDIR_OUTPUT);
00459         IPin *pIn = vetGetPin(destiny, PINDIR_INPUT);
00460 
00461         if (direct)
00462                 hr = filter_builder->ConnectDirect(pOut, pIn, NULL);
00463         else
00464                 hr = filter_builder->Connect(pOut, pIn);
00465 
00466         pOut->Release();
00467         pIn->Release();
00468 
00469         if (FAILED(hr)) //  if (HARDFAILED(hr))
00470                 return VETRET_INTERNAL_ERR;
00471 
00472         return VETRET_OK;
00473  }
00474 
00475 DWORD vetAddGraphToRot(IUnknown *pUnkGraph)
00476 {
00477   IMoniker * pMoniker;
00478   IRunningObjectTable *pROT;
00479   WCHAR wsz[128];
00480   HRESULT hr;
00481 
00482   if (FAILED(GetRunningObjectTable(0, &pROT)))
00483     return 0;
00484 
00485   wsprintfW(wsz, L"FilterGraph %08x pid %08x\0", (DWORD_PTR)pUnkGraph, GetCurrentProcessId());
00486 
00487   hr = CreateItemMoniker(L"!", wsz, &pMoniker);
00488   if (SUCCEEDED(hr))
00489   {
00490     DWORD dwRegister;
00491     hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph, pMoniker, &dwRegister);
00492     pROT->Release();
00493 
00494     pMoniker->Release();
00495 
00496     if (SUCCEEDED(hr))
00497       return dwRegister;
00498   }
00499 
00500   pROT->Release();
00501   return 0;
00502 }
00503 
00504 void vetRemoveGraphFromRot(DWORD pdwRegister)
00505 {
00506   IRunningObjectTable *pROT;
00507 
00508   if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))
00509   {
00510     pROT->Revoke(pdwRegister);
00511     pROT->Release();
00512   }
00513 }
00514 
00515 
00516 
00517 
00518 
00519 
00520 IAMStreamConfig* vetGetStreamConfig(vetDXCapture* vc)
00521 {
00522   IAMStreamConfig *pSC = NULL;
00523   if (FAILED(vc->capture_graph_builder->FindInterface(&PIN_CATEGORY_CAPTURE,
00524         &MEDIATYPE_Video, vc->capture_filter, IID_IAMStreamConfig, (void **)&pSC)))
00525     return NULL;
00526 
00527   return pSC;
00528 }
00529 
00530 
00531 void vetDeleteMediaType(AM_MEDIA_TYPE *pmt)
00532 {
00533   CoTaskMemFree((PVOID)pmt->pbFormat);
00534   CoTaskMemFree(pmt);
00535 }
00536 
00537 
00538 
00539 
00540 
00541 
00542 
00543 static void vetGetFormatName(GUID subtype, char* desc)
00544 {
00545 #define NUM_FORM 7
00546   typedef struct _guid2name {
00547     char* name;
00548     const GUID* subtype;
00549   } guid2name;
00550   static guid2name map_table[NUM_FORM] = {
00551     {"RGB1",&MEDIASUBTYPE_RGB1},
00552     {"RGB4",&MEDIASUBTYPE_RGB4},
00553     {"RGB8",&MEDIASUBTYPE_RGB8},
00554     {"RGB565",&MEDIASUBTYPE_RGB565},
00555     {"RGB555",&MEDIASUBTYPE_RGB555},
00556     {"RGB24",&MEDIASUBTYPE_RGB24},
00557     {"RGB32",&MEDIASUBTYPE_RGB32}
00558   };
00559 
00560   for (int i = 0; i < NUM_FORM; i++)
00561   {
00562     if (*(map_table[i].subtype) == subtype)
00563     {
00564       strcpy(desc, map_table[i].name);
00565       return;
00566     }
00567   }
00568 
00569   desc[0] = (char)(subtype.Data1);
00570   desc[1] = (char)(subtype.Data1 >> 8);
00571   desc[2] = (char)(subtype.Data1 >> 16);
00572   desc[3] = (char)(subtype.Data1 >> 32);
00573   desc[4] = 0;
00574 }
00575 
00576 
00577 
00578 
00579 //used in:  VETRESULT vetDirectXInput::setImageSize(int width, int height)
00580 static IIPDVDec* vetGetDVDecoder(vetDXCapture* vc)
00581 {
00582   IIPDVDec *pDV = NULL;
00583   HRESULT hr = vc->capture_graph_builder->FindInterface(NULL,
00584             &MEDIATYPE_Video, vc->capture_filter, IID_IIPDVDec, (void **)&pDV);
00585   if(FAILED(hr))
00586     return NULL;
00587 
00588   return pDV;
00589 }
00590 
00591 
00592 
00593 
00597 
00598 
00599 
00600 
00608 vetDirectXInput::vetDirectXInput(int device) : vetInput(0)
00609  {
00610         INFO("vetDirectXInput::vetDirectXInput(float fps) : vetInput(fps) [CONTRUCTOR]")
00611 
00612         deviceCount = 0;
00613         enumerateDevices();
00614 
00615         cCap = (vetDXCapture*)malloc(sizeof(vetDXCapture));
00616         memset(cCap, 0, sizeof(vetDXCapture));
00617 
00618         cCap->sample_callback = NULL;
00619         cCap->device = -1;
00620 
00621         connectTo(device);
00622  }
00623 
00624 
00625 vetDirectXInput::vetDirectXInput(int device, float fps) : vetInput(fps)
00626  {
00627         INFO("vetDirectXInput::vetDirectXInput(float fps) : vetInput(fps) [CONTRUCTOR]")
00628 
00629         deviceCount = 0;
00630         enumerateDevices();
00631 
00632         cCap = (vetDXCapture*)malloc(sizeof(vetDXCapture));
00633         memset(cCap, 0, sizeof(vetDXCapture));
00634 
00635         cCap->sample_callback = NULL;
00636         cCap->device = -1;
00637 
00638         connectTo(device);
00639  }
00640 
00645 vetDirectXInput::~vetDirectXInput()
00646  {
00647 
00648 #ifdef REGISTER_FILTERGRAPH
00649         if (vc->registered_graph)
00650                 vc_RemoveGraphFromRot(vc->registered_graph);
00651 #endif
00652 
00653         disconnect();
00654 
00655         if (cCap->sample_callback != NULL)
00656                 delete cCap->sample_callback;
00657 
00658         SafeRelease(cCap->overlay_mixer);
00659         SafeRelease(cCap->overlay_renderer);
00660         SafeRelease(cCap->media_control);
00661         SafeRelease(cCap->sample_grabber);
00662 
00663         if (cCap->null_filter != NULL)
00664                 cCap->null_filter->Release();
00665 
00666         if (cCap->grabber_filter != NULL)
00667                 cCap->grabber_filter->Release();
00668 
00669         if (cCap->filter_builder != NULL)
00670                 cCap->filter_builder->Release();
00671 
00672         if (cCap->capture_graph_builder != NULL)
00673                 cCap->capture_graph_builder->Release();
00674 
00675         free(cCap);
00676  }
00677 
00680 
00681 VETRESULT vetDirectXInput::initCaptureGraphBuilder(vetDXCapture* vdx)
00682  {
00683   HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
00684                                 IID_ICaptureGraphBuilder2, reinterpret_cast<void**>(&vdx->capture_graph_builder));
00685   if (FAILED(hr))
00686         return VETRET_INTERNAL_ERR;
00687 
00688   hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
00689                         IID_IGraphBuilder, reinterpret_cast<void**>(&vdx->filter_builder));
00690   if (FAILED(hr))
00691         return VETRET_INTERNAL_ERR;
00692 
00693   hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
00694                         IID_IBaseFilter, reinterpret_cast<void**>(&vdx->grabber_filter));
00695   if (FAILED(hr))
00696         return VETRET_INTERNAL_ERR;
00697 
00698   hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
00699                         IID_IBaseFilter, reinterpret_cast<void**>(&vdx->null_filter));
00700   if (FAILED(hr))
00701         return VETRET_INTERNAL_ERR;
00702 
00703   // Initialize the Capture Graph Builder.
00704   vdx->capture_graph_builder->SetFiltergraph(vdx->filter_builder);
00705 
00706   hr = vdx->filter_builder->QueryInterface(IID_IMediaControl,(void**)&vdx->media_control);
00707   hr = vdx->grabber_filter->QueryInterface(IID_ISampleGrabber, (void **)&vdx->sample_grabber);
00708 
00709 //  if (FAILED(hr))
00710 //      return VETRET_INTERNAL_ERR;
00711 
00712   AM_MEDIA_TYPE mt;
00713   ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
00714 
00715   mt.majortype = MEDIATYPE_Video;
00716   mt.subtype = MEDIASUBTYPE_RGB24;  // Force 24 bpp
00717 
00718   vdx->sample_grabber->SetMediaType(&mt);
00719   vdx->sample_grabber->SetOneShot(FALSE);
00720   vdx->sample_grabber->SetBufferSamples(FALSE);// WAS FALSE or TRUE
00721 
00722   vdx->sample_callback = new imTrackingGrabberCB();
00723 
00724   hr = vdx->filter_builder->AddFilter(vdx->grabber_filter, L"imSampleGrabber");
00725   hr = vdx->filter_builder->AddFilter(vdx->null_filter, L"imNullRenderer");
00726 
00727   // Remove clock to speed up things
00728   IMediaFilter* pMediaFilter = NULL;
00729   vdx->filter_builder->QueryInterface(IID_IMediaFilter, (void**)&pMediaFilter);
00730   pMediaFilter->SetSyncSource(NULL);
00731   pMediaFilter->Release();
00732 
00733 #ifdef REGISTER_FILTERGRAPH
00734   vdx->registered_graph = vc_AddGraphToRot(vdx->filter_builder);
00735 #endif
00736 
00737 
00738   return VETRET_OK;
00739  }
00740 
00743 
00751 VETRESULT vetDirectXInput::connect()
00752  {
00753         if (deviceCount == 0)
00754          {
00755                 enumerateDevices();
00756                 if (deviceCount == 0)
00757                         return VETRET_ILLEGAL_USE;
00758          }
00759 
00760         if (cCap->device == -1 || cCap->device >= deviceCount)
00761                 return VETRET_ILLEGAL_USE;
00762 
00763         return connectTo(cCap->device);
00764  }
00765 
00766 
00775 VETRESULT vetDirectXInput::connectTo(int device)
00776  {
00777         if (cCap->device == device)
00778                 return VETRET_PARAM_ERR;
00779 
00780         if (cCap->device != -1 && cCap->device != device)
00781                 disconnect();
00782 
00783         if (setDevice(device))
00784                 return VETRET_PARAM_ERR;
00785 
00786         if (initCaptureGraphBuilder(cCap))
00787          {
00788                 SafeRelease(cCap->grabber_filter);
00789                 SafeRelease(cCap->filter_builder);
00790                 SafeRelease(cCap->capture_graph_builder);
00791                 SafeRelease(cCap->null_filter);
00792                 free(cCap);
00793                 return VETRET_INTERNAL_ERR;
00794          }
00795 
00796         cCap->capture_filter = vetGetDevice(device);
00797         if (!cCap->capture_filter)
00798                 return VETRET_INTERNAL_ERR;
00799 
00800         cCap->filter_builder->AddFilter(cCap->capture_filter, L"VETLibCaptureSource");
00801 
00802         vetCheckVideoPort(cCap);
00803 
00804 //      if (vetCheckVideoPort(cCap))
00805 //              return VETRET_INTERNAL_ERR;
00806 
00807         if (vetConnectFilters(cCap->filter_builder, cCap->capture_filter, cCap->grabber_filter, 0))
00808          {
00809                 cCap->filter_builder->RemoveFilter(cCap->capture_filter);
00810 
00811                 SafeRelease(cCap->capture_filter);
00812                 SafeRelease(cCap->video_prop);
00813                 SafeRelease(cCap->camera_prop);
00814                 SafeRelease(cCap->videoctrl_prop);
00815 
00816                 cCap->live = 0;
00817                 cCap->device = -1;
00818 
00819                 return VETRET_INTERNAL_ERR;
00820          }
00821 
00822         vetConnectFilters(cCap->filter_builder, cCap->grabber_filter, cCap->null_filter, 1);
00823 
00824         vetUpdateFormatList(cCap);
00825 
00826         getImageSize(&width, &height);
00827         cCap->sample_callback->SetImageSize(width, height);
00828 
00829         cCap->sample_grabber->SetCallback(cCap->sample_callback, 0);
00830 
00831 //CHECK !!      cCap->sample_grabber->SetBufferSamples(TRUE);
00832 
00833 
00834 
00835 
00836         return VETRET_OK;
00837  }
00838 
00844 VETRESULT vetDirectXInput::disconnect()
00845  {
00846         if (cCap->device == -1)
00847                 return VETRET_ILLEGAL_USE;
00848 
00849         doStopLive();
00850 
00851         cCap->sample_grabber->SetCallback(NULL, 0);
00852 
00853         if (cCap->overlay_mixer)
00854                 doReleaseMixer(cCap);
00855 
00856         vetDisconnectFilters(cCap->filter_builder, cCap->grabber_filter, cCap->null_filter);
00857 
00858         // Disconnect the grabber to preserve it
00859         if (vetDisconnectFilterPin(cCap->filter_builder, cCap->grabber_filter, PINDIR_INPUT))
00860                 return VETRET_INTERNAL_ERR;
00861 
00862         // Remove everything downstream the capture filter, except the null renderer
00863         vetNukeDownstream(cCap->filter_builder, cCap->capture_filter);
00864 
00865         cCap->filter_builder->RemoveFilter(cCap->capture_filter);
00866 
00867         SafeRelease(cCap->capture_filter);
00868         SafeRelease(cCap->video_prop);
00869         SafeRelease(cCap->camera_prop);
00870         SafeRelease(cCap->videoctrl_prop);
00871 
00872         cCap->live = 0;
00873         cCap->device = -1;
00874 
00875         height = 0;
00876         width = 0;
00877 
00878         return VETRET_OK;
00879  }
00880 
00881 
00882 
00883 
00889 bool vetDirectXInput::EoF()
00890  {
00891          if ( getCurrentDevice() == -1 )
00892                 return true;
00893 
00894          return isLive();
00895  }
00896 
00897 
00903 VETRESULT vetDirectXInput::reset()
00904  {
00905          return disconnect();
00906 
00907  }
00908 
00909 
00912 
00913 VETRESULT vetDirectXInput::openPropertyPage(void* ghwndApp)
00914  {
00915 
00916 
00917     CAUUID cauuid;
00918 
00919     // 1. the video capture filter itself
00920         HRESULT hr;
00921 
00922 
00923         hr = cCap->capture_filter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&cCap->pSpec);
00924 
00925         if(hr == S_OK)
00926         {
00927                 hr = cCap->pSpec->GetPages(&cauuid);
00928 
00929                 hr = OleCreatePropertyFrame(static_cast<HWND>(ghwndApp), 30, 30, NULL, 1,
00930                         (IUnknown **)&cCap->capture_filter, cauuid.cElems,
00931                         (GUID *)cauuid.pElems, 0, 0, NULL);
00932 
00933                 CoTaskMemFree(cauuid.pElems);
00934                 cCap->pSpec->Release();
00935         }
00936         else
00937                 return VETRET_INTERNAL_ERR;
00938 
00939         return VETRET_OK;
00940 
00941  }
00942 
00943 
00944 
00953 VETRESULT vetDirectXInput::setDevice(int device)
00954  {
00955         if (device == -1)
00956                 return VETRET_PARAM_ERR;
00957 
00958         if (cCap->live)
00959                 return VETRET_ILLEGAL_USE;
00960 
00961         if (device == cCap->device)
00962                 return VETRET_OK;
00963 
00964         if (deviceCount == 0)
00965          {
00966                 enumerateDevices();
00967                 if (deviceCount == 0)
00968                         return 1;
00969          }
00970 
00971         if (device >= deviceCount)
00972                 return VETRET_PARAM_ERR;
00973 
00974         cCap->device = device;
00975         return VETRET_OK;
00976  }
00977 
00984 void vetDirectXInput::getImageSize(int *width, int *height)
00985  {
00986 //  assert(cCap);
00988 
00989   AM_MEDIA_TYPE mt;
00990   ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
00991   HRESULT hr = cCap->sample_grabber->GetConnectedMediaType(&mt);
00992 
00993   if ( SUCCEEDED(hr) &&
00994       (mt.majortype == MEDIATYPE_Video) &&
00995       (mt.formattype == FORMAT_VideoInfo) &&
00996       (mt.cbFormat >= sizeof (VIDEOINFOHEADER)) &&
00997       (mt.pbFormat != NULL))
00998   {
00999     VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)mt.pbFormat;
01000     *width = pVih->bmiHeader.biWidth;
01001     *height = abs(pVih->bmiHeader.biHeight);
01002     CoTaskMemFree((PVOID)mt.pbFormat);
01003   }
01004   else
01005   {
01006     *width = 0;
01007     *height = 0;
01008   }
01009  }
01010 
01011 
01017 VETRESULT vetDirectXInput::setImageSize(int width, int height)
01018  {
01019         //  assert(vc);
01020         //  assert(vc->device != -1);
01021         int state = cCap->live;
01022 
01023         doStopLive();
01024 
01025         // must be disconnected to change size or format
01026         disconnect();
01027 
01028         IIPDVDec* pDV = vetGetDVDecoder(cCap);
01029         if (pDV)
01030          {
01031                 int size = 0;
01032 
01033                 switch(width)
01034                 {
01035                         case 720:
01036                                           size = DVRESOLUTION_FULL;
01037                                           break;
01038                         case 360:
01039                                           size = DVRESOLUTION_HALF;
01040                                           break;
01041                         case 180:
01042                                           size = DVRESOLUTION_QUARTER;
01043                                           break;
01044                         case 88:
01045                                   size = DVRESOLUTION_DC;
01046                                   break;
01047                  }
01048 
01049                 if (!size)
01050                         return 0;
01051 
01052                 int ret = SUCCEEDED(pDV->put_IPDisplay(size));
01053                 if (ret)
01054                   cCap->sample_callback->SetImageSize(width, height);
01055 
01056                 return ret;
01057          }
01058 
01059         IAMStreamConfig *pSC = vetGetStreamConfig(cCap);
01060         if (!pSC)
01061                 return VETRET_INTERNAL_ERR;
01062 
01063         AM_MEDIA_TYPE *pmt;
01064         HRESULT hr = pSC->GetFormat(&pmt);
01065         if (FAILED(hr))
01066                 return VETRET_INTERNAL_ERR;
01067 
01068         VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)pmt->pbFormat;
01069         BITMAPINFOHEADER* bih = &vih->bmiHeader;
01070 
01071         /* dibs are DWORD aligned */
01072         int data_size = height * ((width * bih->biBitCount + 31) / 32) * 4;   /* 4 bytes boundary */
01073 
01074         bih->biSize = sizeof(BITMAPINFOHEADER);
01075         bih->biHeight = height;
01076         bih->biWidth = width;
01077         bih->biSizeImage = data_size;
01078 
01079         int fps = 30;  // desired frame rate
01080         vih->dwBitRate = fps * data_size;
01081         vih->AvgTimePerFrame = 10000000 / fps;
01082 
01083         pmt->cbFormat = sizeof(VIDEOINFOHEADER);
01084         pmt->lSampleSize = data_size;
01085 
01086         hr = pSC->SetFormat(pmt);
01087         pSC->Release();
01088 
01089         vetDeleteMediaType(pmt);
01090 
01091         int ret = SUCCEEDED(hr);
01092 
01093         if (ret)
01094          {
01095                 cCap->sample_callback->SetImageSize(width, height);
01096 
01097                 if (state)
01098                         if (connect() || doStartLive())
01099                                 return VETRET_INTERNAL_ERR;
01100                         else
01101                                 return VETRET_OK;
01102 
01103                 return VETRET_OK;
01104          }
01105         else
01106                 return VETRET_INTERNAL_ERR;
01107  }
01108 
01109 
01121 int vetDirectXInput::getFormat(int format, int *width, int *height, char* desc)
01122  {
01123 //  assert(vc);
01124 //  assert(vc->device != -1);
01125 //  assert(vc->format_count);
01126 
01127   if (format >= cCap->format_count)
01128     return VETRET_PARAM_ERR;
01129 
01130   IAMStreamConfig *pSC = vetGetStreamConfig(cCap);
01131   if (!pSC)
01132         return VETRET_INTERNAL_ERR;
01133 
01134   VIDEO_STREAM_CONFIG_CAPS scc;
01135   AM_MEDIA_TYPE *pmt;
01136   if (SUCCEEDED(pSC->GetStreamCaps(cCap->format_map[format], &pmt, (BYTE*)&scc)))
01137   {
01138     *width = scc.InputSize.cx;
01139     *height = scc.InputSize.cy;
01140     vetGetFormatName(pmt->subtype, desc);
01141 
01142     pSC->Release();
01143     vetDeleteMediaType(pmt);
01144     return VETRET_OK;
01145   }
01146 
01147   pSC->Release();
01148   return VETRET_INTERNAL_ERR;
01149  }
01150 
01159 VETRESULT vetDirectXInput::setFormat(int format)
01160  {
01161 //  assert(cCap);
01162 //  assert(cCap->device != -1);
01163 
01164   if (format == -1)
01165     return VETRET_PARAM_ERR;
01166 
01167   if (format >= cCap->format_count)
01168     return VETRET_PARAM_ERR;
01169 
01170   doStopLive();
01171 
01172   // must be disconnected to change size or format
01173   disconnect();
01174 
01175   IAMStreamConfig *pSC = vetGetStreamConfig(cCap);
01176   if (!pSC)
01177     return VETRET_INTERNAL_ERR;
01178 
01179   VIDEO_STREAM_CONFIG_CAPS scc;
01180   AM_MEDIA_TYPE *pmt;
01181   if (FAILED(pSC->GetStreamCaps(cCap->format_map[format], &pmt, (BYTE*)&scc)))
01182    {
01183     pSC->Release();
01184     return VETRET_INTERNAL_ERR;
01185    }
01186 
01187   pSC->SetFormat(pmt);
01188   pSC->Release();
01189 
01190   cCap->sample_callback->SetImageSize(scc.InputSize.cx, scc.InputSize.cy);
01191 
01192   vetDeleteMediaType(pmt);
01193 
01194   cCap->format_current = format;
01195 
01196 //  doStartLive();
01197 
01198   return VETRET_OK;
01199  }
01200 
01201 
01202 
01203 
01206 
01212 bool vetDirectXInput::isLive()
01213  {
01214         if ( cCap->live == 0)
01215                 return false;
01216 
01217         return true;
01218  }
01219 
01226 int vetDirectXInput::getCurrentDevice()
01227  {
01228         return cCap->device;
01229  }
01230 
01236 int vetDirectXInput::getFormatCount()
01237  {
01238   return cCap->format_count;
01239  }
01240 
01246 int vetDirectXInput::getFormat()
01247  {
01248   return cCap->format_current;
01249  }
01250 
01251 
01254 
01261 VETRESULT vetDirectXInput::doStartLive()
01262  {
01263         if (cCap->live)
01264                 return VETRET_ILLEGAL_USE;
01265 
01266         HRESULT hr = cCap->media_control->Run();
01267 
01268         if (FAILED(hr)) //  if (HARDFAILED(hr))
01269          {
01270                 cCap->live = 0;
01271                 return VETRET_INTERNAL_ERR;
01272          }
01273 
01274         cCap->live = 1;
01275 
01276         Sleep(200);
01277 
01278         return VETRET_OK;
01279  }
01280 
01286 VETRESULT vetDirectXInput::doStopLive()
01287  {
01288         if (!cCap->live)
01289                 return VETRET_ILLEGAL_USE;
01290 
01291         cCap->media_control->Stop();
01292         cCap->live = 0;
01293 //    Sleep(200);
01294 
01295         return VETRET_OK;
01296  }
01297 
01298 
01299 
01300 
01301 
01302 
01303 
01304 
01306 // frame extraction functions
01307 
01308 
01321 VETRESULT vetDirectXInput::extractTo(vetFrameYUV420& img)
01322  {
01323 
01324         INFO("VETRESULT vetDirectXInput::extractTo(vetFrameYUV420& img) [pushing data]")
01325 
01326         return VETRET_NOT_IMPLEMENTED;
01327  }
01328 
01329 
01342 VETRESULT vetDirectXInput::extractTo(vetFrameRGB24& img)
01343  {
01344 
01345         INFO("VETRESULT vetDirectXInput::extractTo(vetFrameRGB24& img) [pushing data]")
01346 
01347         if ( &img == NULL )
01348                 return VETRET_PARAM_ERR;
01349 
01350         if ((unsigned int)width != img.width || (unsigned int)height != img.height)
01351          {
01352                 delete [] img.data;
01353                 img.data = new PixelRGB24[width*height];
01354          }
01355 
01356         img.height = (unsigned int)height;
01357         img.width = (unsigned int)width;
01358 
01359 
01360         doStopLive();
01361 
01362         cCap->sample_grabber->SetOneShot(TRUE);
01363 
01364         if (doStartLive())
01365          {
01366                 cCap->sample_grabber->SetOneShot(FALSE);
01367                 return VETRET_INTERNAL_ERR;
01368          }
01369 
01370         return cCap->sample_callback->GetImage((unsigned char*)img.data[0], 0, 0);
01371 
01372  }
01373 
01374 
01375 
01388 VETRESULT vetDirectXInput::extractTo(vetFrameT<unsigned char>& img)
01389  {
01390         INFO("VETRESULT vetDirectXInput::extractTo(vetFrameT& img) [pushing data]")
01391 
01392         if ( &img == NULL )
01393                 return VETRET_PARAM_ERR;
01394 
01395 
01396         return VETRET_NOT_IMPLEMENTED;
01397  }
01398 
01399 
01400 
01401 
01403 
01404 // dx utilities functions
01405 
01406 
01407 
01408 /*
01409   If the video capture card supports the video port pin without a video preview pin this will not work.
01410   The DirectShow architecture requires that the video port pin be connected to the Overlay Mixer Filter.
01411   If this pin is not connected, data cannot be captured in DirectShow.
01412 */
01413 VETRESULT vetDirectXInput::vetCheckVideoPort(vetDXCapture* vdx)
01414  {
01415         HRESULT hr;
01416 
01417         IPin *pPreviewPin = NULL;
01418         hr = vdx->capture_graph_builder->FindPin(
01419                         vdx->capture_filter,      // Pointer to the capture filter.
01420                         PINDIR_OUTPUT,           // Look for an output pin.
01421                         &PIN_CATEGORY_PREVIEW,   // Look for a preview pin.
01422                         NULL,                    // Any media type.
01423                         FALSE,                   // Pin can be connected.
01424                         0,                       // Retrieve the first matching pin.
01425                         &pPreviewPin             // Receives a pointer to the pin.
01426                         );
01427 
01428         if (hr == S_OK)
01429          {
01430                 pPreviewPin->Release();
01431                 return VETRET_INTERNAL_ERR;
01432          }
01433 
01434         IPin *pVideoPortPin = NULL;
01435         hr = vdx->capture_graph_builder->FindPin(
01436                         vdx->capture_filter,      // Pointer to the capture filter.
01437                         PINDIR_OUTPUT,           // Look for an output pin.
01438                         &PIN_CATEGORY_VIDEOPORT, // Look for a video port pin.
01439                         NULL,                    // Any media type.
01440                         FALSE,                   // Pin can be connected.
01441                         0,                       // Retrieve the first matching pin.
01442                         &pVideoPortPin           // Receives a pointer to the pin.
01443                         );
01444 
01445         if (FAILED(hr))
01446                 return VETRET_INTERNAL_ERR;
01447 
01448         // Create the overlay mixer.
01449         CoCreateInstance(CLSID_OverlayMixer, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void **)&vdx->overlay_mixer);
01450 
01451         // Add it to the filter graph.
01452         vdx->filter_builder->AddFilter(vdx->overlay_mixer, L"Overlay Mixer");
01453 
01454         IPin *pOverlayPin = NULL;
01455         vdx->capture_graph_builder->FindPin(vdx->overlay_mixer, PINDIR_INPUT, NULL, NULL, TRUE, 0, &pOverlayPin);
01456 
01457         vdx->filter_builder->Connect(pVideoPortPin, pOverlayPin);
01458         if (FAILED(hr))// ??
01459                 return VETRET_INTERNAL_ERR;
01460 
01461         SafeRelease(pVideoPortPin);
01462         SafeRelease(pOverlayPin);
01463 
01464         CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER,
01465                                    IID_IBaseFilter, reinterpret_cast<void**>(&vdx->overlay_renderer));
01466         vdx->filter_builder->AddFilter(vdx->overlay_renderer, L"Overlay Renderer");
01467 
01468         vetConnectFilters(vdx->filter_builder, vdx->overlay_mixer, vdx->overlay_renderer, 1);
01469 
01470         IVideoWindow* pVideoWindow = NULL;
01471         vdx->overlay_renderer->QueryInterface(IID_IVideoWindow,(void**)&pVideoWindow);
01472         pVideoWindow->put_AutoShow(OAFALSE);
01473         pVideoWindow->Release();
01474 
01475     return VETRET_OK;
01476  }
01477 
01483 void vetDirectXInput::doReleaseMixer(vetDXCapture* vc)
01484  {
01485   IPin *pOverlayPin = vetGetPin(vc->overlay_mixer, PINDIR_INPUT);
01486   IPin *pVideoPortPin = NULL;
01487   pOverlayPin->ConnectedTo(&pVideoPortPin);
01488   vc->filter_builder->Disconnect(pOverlayPin);
01489   vc->filter_builder->Disconnect(pVideoPortPin);
01490   SafeRelease(pVideoPortPin);
01491   SafeRelease(pOverlayPin);
01492 
01493   vetDisconnectFilters(vc->filter_builder, vc->overlay_mixer, vc->overlay_renderer);
01494 
01495   vc->filter_builder->RemoveFilter(vc->overlay_renderer);
01496   vc->filter_builder->RemoveFilter(vc->overlay_mixer);
01497   SafeRelease(vc->overlay_renderer);
01498   SafeRelease(vc->overlay_mixer);
01499  }
01500 
01501 
01502 
01503 //used in: VETRESULT vetDirectXInput::connectTo(int device)
01504 VETRESULT vetDirectXInput::vetUpdateFormatList(vetDXCapture* vdx)
01505  {
01506         vdx->format_count = 0;
01507         vdx->format_current = -1;
01508 
01509         IAMStreamConfig *pSC = vetGetStreamConfig(vdx);
01510         if ( !pSC )
01511                 return VETRET_INTERNAL_ERR;
01512 
01513         int iCount = 0, iSize = 0;
01514         if ( FAILED(pSC->GetNumberOfCapabilities(&iCount, &iSize)) )
01515          {
01516                 pSC->Release();
01517                 return VETRET_INTERNAL_ERR;
01518          }
01519 
01520         AM_MEDIA_TYPE *curr_pmt;
01521         HRESULT hr = pSC->GetFormat(&curr_pmt);
01522         if ( FAILED(hr) )
01523          {
01524                 pSC->Release();
01525                 return VETRET_INTERNAL_ERR;
01526          }
01527 
01528         for (int iFormat = 0; iFormat < iCount; iFormat++)
01529          {
01530                 VIDEO_STREAM_CONFIG_CAPS scc;
01531                 AM_MEDIA_TYPE *pmt;
01532                 if ( SUCCEEDED(pSC->GetStreamCaps(iFormat, &pmt, (BYTE*)&scc)) )
01533                  {
01534                         if (scc.guid == FORMAT_VideoInfo)
01535                          {
01536                                 VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)curr_pmt->pbFormat;
01537                                 BITMAPINFOHEADER* bih = &vih->bmiHeader;
01538                                 int width = bih->biWidth;
01539                                 int height = abs(bih->biHeight);
01540 
01541                                 if ( curr_pmt->subtype == pmt->subtype &&
01542                                          width == scc.InputSize.cx &&
01543                                          height == scc.InputSize.cy                             )
01544                                  {
01545                                         vdx->format_current = vdx->format_count;
01546                                  }
01547 
01548                                 vdx->format_map[vdx->format_count] = iFormat;
01549                                 vdx->format_count++;
01550                          }
01551 
01552                         vetDeleteMediaType(pmt);
01553                  }
01554          }
01555 
01556         vetDeleteMediaType(curr_pmt);
01557         pSC->Release();
01558 
01559         return VETRET_OK;
01560  }
01561 
01562 
01564 
01565 // devices enumeration functions
01566 
01567 
01568 
01569 static char* Wide2Char(WCHAR* wstr)
01570  {
01571   if (wstr)
01572   {
01573     int n = wcslen(wstr)+1;
01574     char* str = (char*)malloc(n);
01575     WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, n, NULL, NULL);
01576     return str;
01577   }
01578 
01579   return NULL;
01580  }
01581 
01582 
01589 void vetDirectXInput::enumerateDevices(void)
01590  {
01591   // Selecting a Capture Device
01592   ICreateDevEnum *pDevEnum = NULL;
01593   IEnumMoniker *pEnum = NULL;
01594   deviceCount = 0;
01595 
01596   CoInitialize(NULL);
01597 
01598   // Create the System Device Enumerator.
01599   HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
01600                                 CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
01601                                 reinterpret_cast<void**>(&pDevEnum));
01602   if (FAILED(hr)) return;
01603 
01604   // Create an enumerator for the video capture category.
01605   hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, CATEGORY_FLAG);
01606   if (FAILED(hr) || !pEnum)
01607   {
01608     pDevEnum->Release();
01609     return;
01610   }
01611 
01612   IMoniker *pMoniker = NULL;
01613   while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
01614   {
01615     IPropertyBag *pPropBag;
01616     hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
01617     if (FAILED(hr))
01618     {
01619       pMoniker->Release();
01620       continue;  // Skip this one, maybe the next one will work.
01621     }
01622 
01623     // Find the friendly name.
01624     VARIANT varName;
01625     VariantInit(&varName);
01626 
01627     hr = pPropBag->Read(L"FriendlyName", &varName, 0);
01628     if (SUCCEEDED(hr))
01629     {
01630       char* str = Wide2Char(varName.bstrVal);
01631       sprintf(deviceDesc[deviceCount], "%d - %s", deviceCount, str);
01632       free(str);
01633       VariantClear(&varName);
01634       deviceCount++;
01635     }
01636 
01637     pPropBag->Release();
01638     pMoniker->Release();
01639   }
01640 
01641   pEnum->Release();
01642   pDevEnum->Release();
01643  }
01644 
01651 const char* vetDirectXInput::getDeviceDescription(int device)
01652  {
01653   // List available Devices once
01654   if (deviceCount == 0)
01655   {
01656     enumerateDevices();
01657 
01658     if (deviceCount == 0)
01659       return NULL;
01660   }
01661 
01662   if (device >= deviceCount)
01663     return NULL;
01664 
01665   return deviceDesc[device];
01666  }
01667 
01668 

Generated on Tue Jan 24 11:59:00 2006 for VETLib by  doxygen 1.4.4