Windows:如何获取相机支持的分辨率?

发布于 2024-10-06 07:07:30 字数 3299 浏览 6 评论 0原文

因此,为了获取相机列表并让用户选择一个(C++、Boost、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;
}

我需要以某种方式获取所选相机支持的相机分辨率列表。这样的事该怎么办呢?

So to get cameras list and let user select one (C++, Boost, dshow, windows) I use such code:

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

I need to somehow get list of camera supported resolutions for selected camera. How to do such thing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清风挽心 2024-10-13 07:07:30

假设您已将捕获源过滤器添加到图表中:
一种方法是获取 的 IAMStreamConfig 接口捕获过滤器的输出引脚,然后调用 IAMStreamConfig::GetNumberOfCapability 来获取设备支持的格式功能的数量。您可以通过使用适当的索引调用 IAMStreamConfig::GetStreamCaps 来迭代所有格式。

Assuming that you've added the capture source filter to the graph:
One method is to get the IAMStreamConfig interface of the capture filter's output pin and then call the IAMStreamConfig::GetNumberOfCapabilities to get the number of format capabilities supported by the device. You can iterate over all formats by calling the IAMStreamConfig::GetStreamCaps with the appropriate indices.

陌上芳菲 2024-10-13 07:07:30

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

以下是如何枚举给定 媒体类型枚举器

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

You can get supported resolutions without adding the capture source to a filter graph. You need to:

Here is how to enumerate the media types given a 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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文