Windows下 QT 使用directdshow对UVC摄像头控制

QT使用QCamera配合QCameraViewfinder就可以显示UVC摄像头图像
(详细看QT示例,搜索camera)
如果需要UVC原始数据就使用QVideoProbe

但是QT没有做对UVC设备控制的接口。
比如:LINUX的V4L2的VIDIOC_S_CTRL 对UVC的property进行设置
在WINDOWS下可以通过directdshow来控制UVC的property

首先要添加一些头文件和库

#ifdef Q_CC_MSVC
#include "Windows.h"
#include "dshow.h"
#include "strmif.h"
#include "ks.h"
#include "ksproxy.h"
#include "ksmedia.h"
#  pragma comment(lib, "strmiids.lib")
#  pragma comment(lib, "ole32.lib")
#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
#endif // Q_CC_MSVC

定义一个IBaseFilter

#ifdef Q_CC_MSVC
    IBaseFilter* srcFilter;
#endif

IBaseFilter对应某个UVC设备
通过打开的UVC设备名,获取相应IBaseFilter

bool deviceFilter(const QString &device)
{
#ifdef Q_CC_MSVC
    srcFilter = nullptr;
    ICreateDevEnum* pDevEnum = nullptr;
    IEnumMoniker* pEnum = nullptr;
    // Create the System device enumerator
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr,
                                  CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
                                  reinterpret_cast<void**>(&pDevEnum));
    if (SUCCEEDED(hr)) {
        // Create the enumerator for the video capture category
        hr = pDevEnum->CreateClassEnumerator(
            CLSID_VideoInputDeviceCategory, &pEnum, 0);
        if (S_OK == hr) {
            pEnum->Reset();
            // go through and find all video capture devices
            IMoniker* pMoniker = nullptr;
            IMalloc *mallocInterface = 0;
            CoGetMalloc(1, (LPMALLOC*)&mallocInterface);
            while (pEnum->Next(1, &pMoniker, nullptr) == S_OK) {
                BSTR strName = 0;
                hr = pMoniker->GetDisplayName(nullptr, nullptr, &strName);
                if (SUCCEEDED(hr)) {
                    QString output(QString::fromWCharArray(strName));
                    mallocInterface->Free(strName);

                    IPropertyBag *pPropBag;
                    hr = pMoniker->BindToStorage(nullptr, nullptr, IID_IPropertyBag,
                                                 reinterpret_cast<void**>(&pPropBag));
                    if (SUCCEEDED(hr)) {
                        // Find the description
                        VARIANT varName;
                        varName.vt = VT_BSTR;
                        hr = pPropBag->Read(L"FriendlyName", &varName, 0);
                        if (SUCCEEDED(hr)) {
                            output = QString::fromWCharArray(varName.bstrVal);
                        }
                        pPropBag->Release();

//                        qDebug() << output << device;
                        if( output == device ) {
                            hr = pMoniker->BindToObject(0,
                                                        0,
                                                        IID_IBaseFilter,
                                                        reinterpret_cast<void**>(&srcFilter));
                            qDebug() << "get device control:" << output;
                        }
                    }
                }
                pMoniker->Release();
            }
            mallocInterface->Release();
            pEnum->Release();
        }
        pDevEnum->Release();
    }

    if( srcFilter == nullptr ) {
        return false;
    }
#endif
    return true;
}

获取了IBaseFilter, 就可以对UVC的property进行写入

bool UVControl(const LONG &value)
{
#ifdef Q_CC_MSVC
    if( srcFilter == nullptr ) {
        return false;
    }

    IKsControl *pCtl = nullptr;
    HRESULT hr;
    hr = srcFilter->QueryInterface(IID_IKsControl, reinterpret_cast<void **>(&pCtl));
    if( FAILED(hr) ) {
        return false;
    }

    KSPROPERTY property;
    ZeroMemory(&property, sizeof(property));
    property.Set = PROPSETID_VIDCAP_CAMERACONTROL;
    property.Id = KSPROPERTY_CAMERACONTROL_ZOOM;
    property.Flags = KSPROPERTY_TYPE_SET;

    ULONG valueSize = 0;
    ULONG ksLength = 0;
    ULONG dataLength = 0;

    KSPROPERTY_CAMERACONTROL_S devCtl;
    ZeroMemory(&devCtl, sizeof(devCtl));
    ksLength = sizeof(devCtl);
    dataLength = sizeof(devCtl);

    devCtl.Property = property;
    devCtl.Flags = KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL;
    devCtl.Capabilities = KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL;
    devCtl.Value = value;
    hr = pCtl->KsProperty((PKSPROPERTY)&devCtl, ksLength, &devCtl, dataLength, &valueSize);

    SAFE_RELEASE(pCtl);
#endif
    return true;
}

这里我对UVC的KSPROPERTY_CAMERACONTROL_ZOOM通道进行了设置

参考文章
https://blog.csdn.net/chinabinlang/article/details/18561313

你可能感兴趣的:(qt)