2010-12-05 3 views
2

So Kameras Liste zu bekommen und lassen Sie Benutzer eine auswählen (C++, Boost, dshow, Fenster) ich einen solchen Code verwenden:Windows: Wie bekomme ich die Unterstützung für Kameras?

#include "StdAfx.h" 
#include "list.h" 
#include <windows.h> 
#include <dshow.h> 
#include <boost/lexical_cast.hpp> 

HRESULT CamerasList::EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum) 
{ 
    // Create the System Device Enumerator. 
    ICreateDevEnum *pDevEnum; 
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, 
     CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum)); 

    if (SUCCEEDED(hr)) 
    { 
     // Create an enumerator for the category. 
     hr = pDevEnum->CreateClassEnumerator(category, ppEnum, 0); 
     if (hr == S_FALSE) 
     { 
      hr = VFW_E_NOT_FOUND; // The category is empty. Treat as an error. 
     } 
     pDevEnum->Release(); 
    } 
    return hr; 
} 

int CamerasList::SelectFromList() 
{ int i = 0; 
    int SelectedIndex; 
    IEnumMoniker *pEnum; 
    printf("\nLet us select video device\n"); 
    printf("Available Capture Devices are:\n"); 
    HRESULT hr; 
    hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnum); 
    if (SUCCEEDED(hr)) 
    { 
     IMoniker *pMoniker = NULL; 

     while (pEnum->Next(1, &pMoniker, NULL) == S_OK) 
     { 
      IPropertyBag *pPropBag; 
      HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag)); 
      if (FAILED(hr)) 
      { 
       pMoniker->Release(); 
       continue; 
      } 

      VARIANT var; 
      VariantInit(&var); 

      // Get description or friendly name. 
      hr = pPropBag->Read(L"Description", &var, 0); 
      if (FAILED(hr)) 
      { 
       hr = pPropBag->Read(L"FriendlyName", &var, 0); 
      } 
      if (SUCCEEDED(hr)) 
      { 
       std::cout << i; 
       printf(") %S\n", var.bstrVal); 
       i++; 
       VariantClear(&var); 
      } 

      hr = pPropBag->Write(L"FriendlyName", &var); 

      pPropBag->Release(); 
      pMoniker->Release(); 

     } 
     SelectedIndex = 999; 
    if (i <= 0) 
    { 
     cout <<"No devices found. \n " << endl; 
     //cout <<"Please restart application." << endl; 
     //cin.get(); 
     //Sleep(999999); 
    return 999; 

    }else if(i == 1){ 
      cout <<"Default device will be used\n" << std::endl; 
      SelectedIndex = 0; 
     }else{ 
     while(SelectedIndex > i-1 || SelectedIndex < 0) 
     { 
      try{   
      std::string s; 
      std::getline(cin, s, '\n'); 
      SelectedIndex = boost::lexical_cast<int>(s); 
      } 
      catch(std::exception& e){ 
       std::cout <<"please input index from 0 to " << i-1 << std::endl; 
       SelectedIndex = 999; 
      } 
     }} 
     pEnum->Release(); 
    }else 
    { 
     printf("no Video Devices found. \n") ; 
     //cout <<"Please restart application." << endl; 
     //cin.get(); 
     //Sleep(999999); 
     return 999; 
    } 
    return SelectedIndex; 
} 

Ich brauche irgendwie Liste der Kamera für die ausgewählte Kamera unterstützten Auflösungen erhalten. Wie macht man so etwas?

Antwort

4

Unter der Annahme, dass Sie die Capture-Quelle-Filter zum Graphen hinzugefügt haben: Eine Methode ist die IAMStreamConfig Schnittstelle des Capture-Filters Ausgangsstift zu bekommen und dann rufen Sie die IAMStreamConfig :: GetNumberOfCapabilities die Anzahl der Format-Funktionen unterstützt von bekommen das Gerät. Sie können über alle Formate iterieren, indem Sie die IAMStreamConfig :: GetStreamCaps mit den entsprechenden Indizes aufrufen.

+0

Nein, ich benutze es nur, um eine Kameraliste zu bekommen - ich benutze OpenCV zum Capturen. Also, wenn ich kein Diagramm mache, wie man so etwas macht? Oder wie erstellt man ein Diagramm nur für diesen Porpus? – Rella

+0

Ich kenne keine andere Möglichkeit, dies zu tun, ohne die Erfassungsquelle zu einem Graphen hinzuzufügen, um den Ausgangspin für die IAMStreamConfig-Schnittstelle usw. abzufragen. Was ist mit dem Hinzufügen zu einem Graphen, Abfragen, usw. und dann? Freigabe der Grafik und der Ressourcen, sobald Sie die gewünschten Informationen haben? – Ralf

3

Sie können unterstützte Auflösungen abrufen, ohne die Erfassungsquelle einem Filtergraphen hinzuzufügen. Sie müssen

Hier bekommen, wie die Medien aufzuzählen Typen gegeben media type enumerator

AM_MEDIA_TYPE* mediaType = NULL; 
VIDEOINFOHEADER* videoInfoHeader = NULL; 
while (S_OK == mediaTypesEnumerator->Next(1, &mediaType, NULL)) 
{ 
    if ((mediaType->formattype == FORMAT_VideoInfo) && 
     (mediaType->cbFormat >= sizeof(VIDEOINFOHEADER)) && 
     (mediaType->pbFormat != NULL)) 
    { 
     videoInfoHeader = (VIDEOINFOHEADER*)mediaType->pbFormat; 
     videoInfoHeader->bmiHeader.biWidth; // Supported width 
     videoInfoHeader->bmiHeader.biHeight; // Supported height 
    } 
    FreeMediaType(*mediaType); 
} 
+0

Danke, genau was ich brauchte. Offensichtlich sollten wir in diesem Zusammenhang 'DeleteMediaType' verwenden ([link] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd376602 (v = vs.85) .aspx))). Auch (egal wie) kann "pbFormat" danach nicht mehr verwendet werden. – entheh

Verwandte Themen