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