2010-12-05 45 views
2

因此,要获得相机列表,让用户选择一个(C++,升压,DSHOW,窗户)我用这样的代码:Windows:如何获得相机支持的分辨率?

#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; 
} 

我需要以某种方式获得相机的列表支持选定的摄像头分辨率。如何做这样的事情?

回答

4

假设你已经添加了捕捉源过滤器到图形: 一种方法是让捕获过滤器的输出引脚的IAMStreamConfig接口,然后调用IAMStreamConfig :: GetNumberOfCapabilities获得由支持的格式的功能数量装置。您可以通过使用适当的索引调用IAMStreamConfig :: GetStreamCaps来遍历所有格式。

+0

不,我实际上只是用它来获取相机列表 - 我使用OpenCV进行拍摄。所以如果我不创建一个图表如何做这样的事情?或者如何为这样的porpus创建图表? – Rella 2010-12-05 21:00:30

+0

我不知道有没有其他的方式来做到这一点,而不需要添加捕获源到图表来查询IAMStreamConfig接口的输出引脚等等。只要将它添加到图表中,查询它等等,然后一旦你得到所需的信息,发布图表和资源? – Ralf 2011-03-01 11:32:45

3

无需将捕获源添加到过滤器图即可获得支持的分辨率。您需要

  • 绑定的设备moniker到基地filter
  • 从过滤器得到的输出pin
  • 枚举该输出引脚

这里是如何枚举媒体media types给定的类型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); 
} 
相关问题