22static constexpr GUID KSCATEGORY_SENSOR_CAMERA = {
23 0x24e552d7, 0x6523, 0x47f7, { 0xa6, 0x47, 0xd3, 0x46, 0x5b, 0xf1, 0xf5, 0xca }
31LRESULT QT_WIN_CALLBACK deviceNotificationWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
33 if (message == WM_DEVICECHANGE) {
34 auto b = (PDEV_BROADCAST_HDR)lParam;
35 if (b && b->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
36 auto wmd =
reinterpret_cast<QWindowsVideoDevices *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
38 if (wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE) {
39 wmd->onVideoInputsChanged();
64 wx.cbSize =
sizeof(WNDCLASSEX);
65 wx.lpfnWndProc = deviceNotificationWndProc;
66 wx.hInstance = GetModuleHandle(
nullptr);
67 wx.lpszClassName = getWindowsClassName();
69 if (!RegisterClassEx(&wx))
72 auto hwnd = CreateWindowEx(0, getWindowsClassName(), TEXT(
"Message"), 0, 0, 0, 0, 0,
73 HWND_MESSAGE,
nullptr,
nullptr,
nullptr);
75 UnregisterClass(getWindowsClassName(), GetModuleHandle(
nullptr));
85 : QPlatformVideoDevices(integration)
87 m_videoDeviceMsgWindow = createMessageOnlyWindow();
88 if (m_videoDeviceMsgWindow) {
89 SetWindowLongPtr(m_videoDeviceMsgWindow, GWLP_USERDATA, (LONG_PTR)
this);
91 DEV_BROADCAST_DEVICEINTERFACE di = {};
92 di.dbcc_size =
sizeof(di);
93 di.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
94 di.dbcc_classguid = KSCATEGORY_VIDEO_CAMERA;
96 m_videoDeviceNotification =
97 RegisterDeviceNotification(m_videoDeviceMsgWindow, &di, DEVICE_NOTIFY_WINDOW_HANDLE);
98 if (!m_videoDeviceNotification) {
99 DestroyWindow(m_videoDeviceMsgWindow);
100 m_videoDeviceMsgWindow =
nullptr;
102 UnregisterClass(getWindowsClassName(), GetModuleHandle(
nullptr));
106 if (!m_videoDeviceNotification) {
107 qWarning() <<
"Video device change notification disabled";
125 GUID subtype = GUID_NULL;
126 if (FAILED(mediaFormat->GetGUID(MF_MT_SUBTYPE, &subtype)))
129 auto pixelFormat = QWindowsMultimediaUtils::pixelFormatFromMediaSubtype(subtype);
130 if (pixelFormat == QVideoFrameFormat::Format_Invalid)
133 UINT32 nominalRange = 0;
134 auto colorRange = QVideoFrameFormat::ColorRange_Unknown;
136 if (SUCCEEDED(mediaFormat->GetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, &nominalRange)))
137 colorRange = QWindowsMultimediaUtils::colorRangeFromNominalRange(nominalRange);
139 UINT32 yuvMatrix = 0;
140 auto colorSpace = QVideoFrameFormat::ColorSpace_Undefined;
142 if (SUCCEEDED(mediaFormat->GetUINT32(MF_MT_YUV_MATRIX , &yuvMatrix)))
143 colorSpace = QWindowsMultimediaUtils::colorSpaceFromMatrix(yuvMatrix);
147 if (FAILED(MFGetAttributeSize(mediaFormat, MF_MT_FRAME_SIZE, &width, &height)))
149 QSize resolution{
int(width),
int(height) };
156 if (SUCCEEDED(MFGetAttributeRatio(mediaFormat, MF_MT_FRAME_RATE_RANGE_MIN, &num, &den)))
157 minFr =
float(num) /
float(den);
159 if (SUCCEEDED(MFGetAttributeRatio(mediaFormat, MF_MT_FRAME_RATE_RANGE_MAX, &num, &den)))
160 maxFr =
float(num) /
float(den);
162 auto *f =
new QCameraFormatPrivate{ QSharedData(), pixelFormat, resolution, minFr, maxFr , colorRange, colorSpace };
181 auto info = std::make_unique<QCameraDevicePrivate>();
182 info->description = getString(device, MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME);
183 info->id = getString(device, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK).toUtf8();
185 IMFMediaSource *source = NULL;
186 HRESULT hr = device->ActivateObject(IID_PPV_ARGS(&source));
190 ComPtr<IMFSourceReader> reader;
191 hr = wmf.mfCreateSourceReaderFromMediaSource(source, NULL, reader.GetAddressOf());
195 QList<QSize> photoResolutions;
196 QList<QCameraFormat> videoFormats;
197 for (DWORD i = 0;; ++i) {
199 ComPtr<IMFMediaType> mediaFormat;
200 hr = reader->GetNativeMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, i,
201 mediaFormat.GetAddressOf());
205 auto maybeCamera = createCameraFormat(mediaFormat.Get());
207 videoFormats << *maybeCamera;
208 photoResolutions << maybeCamera->resolution();
212 info->videoFormats = videoFormats;
213 info->photoResolutions = photoResolutions;
214 return info.release()->create();
220 QList<QCameraDevice> cameras;
222 IMFActivate **devicesRaw =
nullptr;
223 HRESULT hr = wmf.mfEnumDeviceSources(attr, &devicesRaw, &count);
225 QComTaskResource<IMFActivate *[], QComDeleter> devices(devicesRaw, count);
227 for (UINT32 i = 0; i < count; i++) {
228 IMFActivate *device = devices[i];
230 auto maybeCamera = createCameraDevice(wmf, device);
232 cameras << *maybeCamera;
244 QList<QCameraDevice> cameras;
246 ComPtr<IMFAttributes> attr;
247 HRESULT hr = m_wmf->mfCreateAttributes(attr.GetAddressOf(), 2);
251 hr = attr->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
252 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
254 cameras << readCameraDevices(*m_wmf, attr.Get());
256 hr = attr->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_CATEGORY,
257 KSCATEGORY_SENSOR_CAMERA);
259 cameras << readCameraDevices(*m_wmf, attr.Get());