23static constexpr GUID KSCATEGORY_SENSOR_CAMERA = {
24 0x24e552d7, 0x6523, 0x47f7, { 0xa6, 0x47, 0xd3, 0x46, 0x5b, 0xf1, 0xf5, 0xca }
32LRESULT QT_WIN_CALLBACK deviceNotificationWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
34 if (message == WM_DEVICECHANGE) {
35 auto b = (PDEV_BROADCAST_HDR)lParam;
36 if (b && b->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
37 auto wmd =
reinterpret_cast<QWindowsVideoDevices *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
39 if (wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE) {
40 wmd->onVideoInputsChanged();
65 wx.cbSize =
sizeof(WNDCLASSEX);
66 wx.lpfnWndProc = deviceNotificationWndProc;
67 wx.hInstance = GetModuleHandle(
nullptr);
68 wx.lpszClassName = getWindowsClassName();
70 if (!RegisterClassEx(&wx))
73 auto hwnd = CreateWindowEx(0, getWindowsClassName(), TEXT(
"Message"), 0, 0, 0, 0, 0,
74 HWND_MESSAGE,
nullptr,
nullptr,
nullptr);
76 UnregisterClass(getWindowsClassName(), GetModuleHandle(
nullptr));
86 : QPlatformVideoDevices(integration)
88 qt_win_ensureComInitializedOnThisThread();
90 m_videoDeviceMsgWindow = createMessageOnlyWindow();
91 if (m_videoDeviceMsgWindow) {
92 SetWindowLongPtr(m_videoDeviceMsgWindow, GWLP_USERDATA, (LONG_PTR)
this);
94 DEV_BROADCAST_DEVICEINTERFACE di = {};
95 di.dbcc_size =
sizeof(di);
96 di.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
97 di.dbcc_classguid = KSCATEGORY_VIDEO_CAMERA;
99 m_videoDeviceNotification =
100 RegisterDeviceNotification(m_videoDeviceMsgWindow, &di, DEVICE_NOTIFY_WINDOW_HANDLE);
101 if (!m_videoDeviceNotification) {
102 DestroyWindow(m_videoDeviceMsgWindow);
103 m_videoDeviceMsgWindow =
nullptr;
105 UnregisterClass(getWindowsClassName(), GetModuleHandle(
nullptr));
109 if (!m_videoDeviceNotification) {
110 qWarning() <<
"Video device change notification disabled";
141 auto info = std::make_unique<QCameraDevicePrivate>();
142 info->description = getString(device, MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME);
143 info->id = getString(device, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK).toUtf8();
145 ComPtr<IMFMediaSource> source;
146 HRESULT hr = device->ActivateObject(IID_PPV_ARGS(source.GetAddressOf()));
150 ComPtr<IMFSourceReader> reader;
151 hr = wmf.mfCreateSourceReaderFromMediaSource(source.Get(), NULL, reader.GetAddressOf());
155 QList<QSize> photoResolutions;
156 QList<QCameraFormat> videoFormats;
157 for (DWORD i = 0;; ++i) {
159 ComPtr<IMFMediaType> mediaFormat;
160 hr = reader->GetNativeMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, i,
161 mediaFormat.GetAddressOf());
165 auto maybeCamera = QWMF::cameraFormatFromMediaType(mediaFormat.Get());
167 videoFormats << *maybeCamera;
168 photoResolutions << maybeCamera->resolution();
172 info->videoFormats = videoFormats;
173 info->photoResolutions = photoResolutions;
174 return info.release()->create();
180 QList<QCameraDevice> cameras;
182 IMFActivate **devicesRaw =
nullptr;
183 HRESULT hr = wmf.mfEnumDeviceSources(attr, &devicesRaw, &count);
185 QComTaskResource<IMFActivate *[], QComDeleter> devices(devicesRaw, count);
187 for (UINT32 i = 0; i < count; i++) {
188 IMFActivate *device = devices[i];
190 auto maybeCamera = createCameraDevice(wmf, device);
192 cameras << *maybeCamera;
204 QList<QCameraDevice> cameras;
206 ComPtr<IMFAttributes> attr;
207 HRESULT hr = m_wmf->mfCreateAttributes(attr.GetAddressOf(), 2);
211 hr = attr->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
212 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
214 cameras << readCameraDevices(*m_wmf, attr.Get());
216 hr = attr->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_CATEGORY,
217 KSCATEGORY_SENSOR_CAMERA);
219 cameras << readCameraDevices(*m_wmf, attr.Get());