OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/capture/video/win/video_capture_device_factory_win.h" | 5 #include "media/capture/video/win/video_capture_device_factory_win.h" |
6 | 6 |
7 #include <mfapi.h> | 7 #include <mfapi.h> |
8 #include <mferror.h> | 8 #include <mferror.h> |
9 #include <objbase.h> | 9 #include <objbase.h> |
10 #include <stddef.h> | 10 #include <stddef.h> |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 | 88 |
89 return SUCCEEDED( | 89 return SUCCEEDED( |
90 (*attributes) | 90 (*attributes) |
91 ->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, | 91 ->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, |
92 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID)); | 92 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID)); |
93 } | 93 } |
94 | 94 |
95 static bool CreateVideoCaptureDeviceMediaFoundation(const char* sym_link, | 95 static bool CreateVideoCaptureDeviceMediaFoundation(const char* sym_link, |
96 IMFMediaSource** source) { | 96 IMFMediaSource** source) { |
97 ScopedComPtr<IMFAttributes> attributes; | 97 ScopedComPtr<IMFAttributes> attributes; |
98 if (!PrepareVideoCaptureAttributesMediaFoundation(attributes.Receive(), 2)) | 98 if (!PrepareVideoCaptureAttributesMediaFoundation(attributes.GetAddressOf(), |
| 99 2)) |
99 return false; | 100 return false; |
100 | 101 |
101 attributes->SetString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, | 102 attributes->SetString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, |
102 base::SysUTF8ToWide(sym_link).c_str()); | 103 base::SysUTF8ToWide(sym_link).c_str()); |
103 | 104 |
104 return SUCCEEDED(MFCreateDeviceSource(attributes.Get(), source)); | 105 return SUCCEEDED(MFCreateDeviceSource(attributes.Get(), source)); |
105 } | 106 } |
106 | 107 |
107 static bool EnumerateVideoDevicesMediaFoundation(IMFActivate*** devices, | 108 static bool EnumerateVideoDevicesMediaFoundation(IMFActivate*** devices, |
108 UINT32* count) { | 109 UINT32* count) { |
109 ScopedComPtr<IMFAttributes> attributes; | 110 ScopedComPtr<IMFAttributes> attributes; |
110 if (!PrepareVideoCaptureAttributesMediaFoundation(attributes.Receive(), 1)) | 111 if (!PrepareVideoCaptureAttributesMediaFoundation(attributes.GetAddressOf(), |
| 112 1)) |
111 return false; | 113 return false; |
112 | 114 |
113 return SUCCEEDED(MFEnumDeviceSources(attributes.Get(), devices, count)); | 115 return SUCCEEDED(MFEnumDeviceSources(attributes.Get(), devices, count)); |
114 } | 116 } |
115 | 117 |
116 static bool IsDeviceBlackListed(const std::string& name) { | 118 static bool IsDeviceBlackListed(const std::string& name) { |
117 DCHECK_EQ(BLACKLISTED_CAMERA_MAX + 1, | 119 DCHECK_EQ(BLACKLISTED_CAMERA_MAX + 1, |
118 static_cast<int>(arraysize(kBlacklistedCameraNames))); | 120 static_cast<int>(arraysize(kBlacklistedCameraNames))); |
119 for (size_t i = 0; i < arraysize(kBlacklistedCameraNames); ++i) { | 121 for (size_t i = 0; i < arraysize(kBlacklistedCameraNames); ++i) { |
120 if (base::StartsWith(name, kBlacklistedCameraNames[i], | 122 if (base::StartsWith(name, kBlacklistedCameraNames[i], |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 DVLOG(1) << __func__; | 155 DVLOG(1) << __func__; |
154 | 156 |
155 ScopedComPtr<ICreateDevEnum> dev_enum; | 157 ScopedComPtr<ICreateDevEnum> dev_enum; |
156 HRESULT hr = | 158 HRESULT hr = |
157 dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC); | 159 dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC); |
158 if (FAILED(hr)) | 160 if (FAILED(hr)) |
159 return; | 161 return; |
160 | 162 |
161 ScopedComPtr<IEnumMoniker> enum_moniker; | 163 ScopedComPtr<IEnumMoniker> enum_moniker; |
162 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, | 164 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, |
163 enum_moniker.Receive(), 0); | 165 enum_moniker.GetAddressOf(), 0); |
164 // CreateClassEnumerator returns S_FALSE on some Windows OS | 166 // CreateClassEnumerator returns S_FALSE on some Windows OS |
165 // when no camera exist. Therefore the FAILED macro can't be used. | 167 // when no camera exist. Therefore the FAILED macro can't be used. |
166 if (hr != S_OK) | 168 if (hr != S_OK) |
167 return; | 169 return; |
168 | 170 |
169 // Enumerate all video capture devices. | 171 // Enumerate all video capture devices. |
170 for (ScopedComPtr<IMoniker> moniker; | 172 for (ScopedComPtr<IMoniker> moniker; |
171 enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK; | 173 enum_moniker->Next(1, moniker.GetAddressOf(), NULL) == S_OK; |
172 moniker.Reset()) { | 174 moniker.Reset()) { |
173 ScopedComPtr<IPropertyBag> prop_bag; | 175 ScopedComPtr<IPropertyBag> prop_bag; |
174 hr = moniker->BindToStorage(0, 0, IID_PPV_ARGS(&prop_bag)); | 176 hr = moniker->BindToStorage(0, 0, IID_PPV_ARGS(&prop_bag)); |
175 if (FAILED(hr)) | 177 if (FAILED(hr)) |
176 continue; | 178 continue; |
177 | 179 |
178 // Find the description or friendly name. | 180 // Find the description or friendly name. |
179 ScopedVariant name; | 181 ScopedVariant name; |
180 hr = prop_bag->Read(L"Description", name.Receive(), 0); | 182 hr = prop_bag->Read(L"Description", name.Receive(), 0); |
181 if (FAILED(hr)) | 183 if (FAILED(hr)) |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 DVLOG(1) << "GetDeviceSupportedFormatsDirectShow for " | 246 DVLOG(1) << "GetDeviceSupportedFormatsDirectShow for " |
245 << descriptor.display_name; | 247 << descriptor.display_name; |
246 ScopedComPtr<ICreateDevEnum> dev_enum; | 248 ScopedComPtr<ICreateDevEnum> dev_enum; |
247 HRESULT hr = | 249 HRESULT hr = |
248 dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC); | 250 dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC); |
249 if (FAILED(hr)) | 251 if (FAILED(hr)) |
250 return; | 252 return; |
251 | 253 |
252 ScopedComPtr<IEnumMoniker> enum_moniker; | 254 ScopedComPtr<IEnumMoniker> enum_moniker; |
253 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, | 255 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, |
254 enum_moniker.Receive(), 0); | 256 enum_moniker.GetAddressOf(), 0); |
255 // CreateClassEnumerator returns S_FALSE on some Windows OS when no camera | 257 // CreateClassEnumerator returns S_FALSE on some Windows OS when no camera |
256 // exists. Therefore the FAILED macro can't be used. | 258 // exists. Therefore the FAILED macro can't be used. |
257 if (hr != S_OK) | 259 if (hr != S_OK) |
258 return; | 260 return; |
259 | 261 |
260 // Walk the capture devices. No need to check for device presence again since | 262 // Walk the capture devices. No need to check for device presence again since |
261 // that is anyway needed in GetDeviceFilter(). "google camera adapter" and old | 263 // that is anyway needed in GetDeviceFilter(). "google camera adapter" and old |
262 // VFW devices are already skipped previously in GetDeviceNames() enumeration. | 264 // VFW devices are already skipped previously in GetDeviceNames() enumeration. |
263 base::win::ScopedComPtr<IBaseFilter> capture_filter; | 265 base::win::ScopedComPtr<IBaseFilter> capture_filter; |
264 hr = VideoCaptureDeviceWin::GetDeviceFilter(descriptor.device_id, | 266 hr = VideoCaptureDeviceWin::GetDeviceFilter(descriptor.device_id, |
265 capture_filter.Receive()); | 267 capture_filter.GetAddressOf()); |
266 if (!capture_filter.Get()) { | 268 if (!capture_filter.Get()) { |
267 DLOG(ERROR) << "Failed to create capture filter: " | 269 DLOG(ERROR) << "Failed to create capture filter: " |
268 << logging::SystemErrorCodeToString(hr); | 270 << logging::SystemErrorCodeToString(hr); |
269 return; | 271 return; |
270 } | 272 } |
271 | 273 |
272 base::win::ScopedComPtr<IPin> output_capture_pin( | 274 base::win::ScopedComPtr<IPin> output_capture_pin( |
273 VideoCaptureDeviceWin::GetPin(capture_filter.Get(), PINDIR_OUTPUT, | 275 VideoCaptureDeviceWin::GetPin(capture_filter.Get(), PINDIR_OUTPUT, |
274 PIN_CATEGORY_CAPTURE, GUID_NULL)); | 276 PIN_CATEGORY_CAPTURE, GUID_NULL)); |
275 if (!output_capture_pin.Get()) { | 277 if (!output_capture_pin.Get()) { |
276 DLOG(ERROR) << "Failed to get capture output pin"; | 278 DLOG(ERROR) << "Failed to get capture output pin"; |
277 return; | 279 return; |
278 } | 280 } |
279 | 281 |
280 ScopedComPtr<IAMStreamConfig> stream_config; | 282 ScopedComPtr<IAMStreamConfig> stream_config; |
281 hr = output_capture_pin.CopyTo(stream_config.Receive()); | 283 hr = output_capture_pin.CopyTo(stream_config.GetAddressOf()); |
282 if (FAILED(hr)) { | 284 if (FAILED(hr)) { |
283 DLOG(ERROR) << "Failed to get IAMStreamConfig interface from " | 285 DLOG(ERROR) << "Failed to get IAMStreamConfig interface from " |
284 "capture device: " << logging::SystemErrorCodeToString(hr); | 286 "capture device: " << logging::SystemErrorCodeToString(hr); |
285 return; | 287 return; |
286 } | 288 } |
287 | 289 |
288 int count = 0, size = 0; | 290 int count = 0, size = 0; |
289 hr = stream_config->GetNumberOfCapabilities(&count, &size); | 291 hr = stream_config->GetNumberOfCapabilities(&count, &size); |
290 if (FAILED(hr)) { | 292 if (FAILED(hr)) { |
291 DLOG(ERROR) << "GetNumberOfCapabilities failed: " | 293 DLOG(ERROR) << "GetNumberOfCapabilities failed: " |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 } | 330 } |
329 } | 331 } |
330 | 332 |
331 static void GetDeviceSupportedFormatsMediaFoundation( | 333 static void GetDeviceSupportedFormatsMediaFoundation( |
332 const Descriptor& descriptor, | 334 const Descriptor& descriptor, |
333 VideoCaptureFormats* formats) { | 335 VideoCaptureFormats* formats) { |
334 DVLOG(1) << "GetDeviceSupportedFormatsMediaFoundation for " | 336 DVLOG(1) << "GetDeviceSupportedFormatsMediaFoundation for " |
335 << descriptor.display_name; | 337 << descriptor.display_name; |
336 ScopedComPtr<IMFMediaSource> source; | 338 ScopedComPtr<IMFMediaSource> source; |
337 if (!CreateVideoCaptureDeviceMediaFoundation(descriptor.device_id.c_str(), | 339 if (!CreateVideoCaptureDeviceMediaFoundation(descriptor.device_id.c_str(), |
338 source.Receive())) { | 340 source.GetAddressOf())) { |
339 return; | 341 return; |
340 } | 342 } |
341 | 343 |
342 base::win::ScopedComPtr<IMFSourceReader> reader; | 344 base::win::ScopedComPtr<IMFSourceReader> reader; |
343 HRESULT hr = | 345 HRESULT hr = MFCreateSourceReaderFromMediaSource(source.Get(), NULL, |
344 MFCreateSourceReaderFromMediaSource(source.Get(), NULL, reader.Receive()); | 346 reader.GetAddressOf()); |
345 if (FAILED(hr)) { | 347 if (FAILED(hr)) { |
346 DLOG(ERROR) << "MFCreateSourceReaderFromMediaSource failed: " | 348 DLOG(ERROR) << "MFCreateSourceReaderFromMediaSource failed: " |
347 << logging::SystemErrorCodeToString(hr); | 349 << logging::SystemErrorCodeToString(hr); |
348 return; | 350 return; |
349 } | 351 } |
350 | 352 |
351 DWORD stream_index = 0; | 353 DWORD stream_index = 0; |
352 ScopedComPtr<IMFMediaType> type; | 354 ScopedComPtr<IMFMediaType> type; |
353 while (SUCCEEDED(reader->GetNativeMediaType(kFirstVideoStream, stream_index, | 355 while (SUCCEEDED(reader->GetNativeMediaType(kFirstVideoStream, stream_index, |
354 type.Receive()))) { | 356 type.GetAddressOf()))) { |
355 UINT32 width, height; | 357 UINT32 width, height; |
356 hr = MFGetAttributeSize(type.Get(), MF_MT_FRAME_SIZE, &width, &height); | 358 hr = MFGetAttributeSize(type.Get(), MF_MT_FRAME_SIZE, &width, &height); |
357 if (FAILED(hr)) { | 359 if (FAILED(hr)) { |
358 DLOG(ERROR) << "MFGetAttributeSize failed: " | 360 DLOG(ERROR) << "MFGetAttributeSize failed: " |
359 << logging::SystemErrorCodeToString(hr); | 361 << logging::SystemErrorCodeToString(hr); |
360 return; | 362 return; |
361 } | 363 } |
362 VideoCaptureFormat capture_format; | 364 VideoCaptureFormat capture_format; |
363 capture_format.frame_size.SetSize(width, height); | 365 capture_format.frame_size.SetSize(width, height); |
364 | 366 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 std::unique_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryWin::CreateDevice( | 419 std::unique_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryWin::CreateDevice( |
418 const Descriptor& device_descriptor) { | 420 const Descriptor& device_descriptor) { |
419 DCHECK(thread_checker_.CalledOnValidThread()); | 421 DCHECK(thread_checker_.CalledOnValidThread()); |
420 std::unique_ptr<VideoCaptureDevice> device; | 422 std::unique_ptr<VideoCaptureDevice> device; |
421 if (device_descriptor.capture_api == VideoCaptureApi::WIN_MEDIA_FOUNDATION) { | 423 if (device_descriptor.capture_api == VideoCaptureApi::WIN_MEDIA_FOUNDATION) { |
422 DCHECK(PlatformSupportsMediaFoundation()); | 424 DCHECK(PlatformSupportsMediaFoundation()); |
423 device.reset(new VideoCaptureDeviceMFWin(device_descriptor)); | 425 device.reset(new VideoCaptureDeviceMFWin(device_descriptor)); |
424 DVLOG(1) << " MediaFoundation Device: " << device_descriptor.display_name; | 426 DVLOG(1) << " MediaFoundation Device: " << device_descriptor.display_name; |
425 ScopedComPtr<IMFMediaSource> source; | 427 ScopedComPtr<IMFMediaSource> source; |
426 if (!CreateVideoCaptureDeviceMediaFoundation( | 428 if (!CreateVideoCaptureDeviceMediaFoundation( |
427 device_descriptor.device_id.c_str(), source.Receive())) { | 429 device_descriptor.device_id.c_str(), source.GetAddressOf())) { |
428 return std::unique_ptr<VideoCaptureDevice>(); | 430 return std::unique_ptr<VideoCaptureDevice>(); |
429 } | 431 } |
430 if (!static_cast<VideoCaptureDeviceMFWin*>(device.get())->Init(source)) | 432 if (!static_cast<VideoCaptureDeviceMFWin*>(device.get())->Init(source)) |
431 device.reset(); | 433 device.reset(); |
432 } else if (device_descriptor.capture_api == | 434 } else if (device_descriptor.capture_api == |
433 VideoCaptureApi::WIN_DIRECT_SHOW) { | 435 VideoCaptureApi::WIN_DIRECT_SHOW) { |
434 device.reset(new VideoCaptureDeviceWin(device_descriptor)); | 436 device.reset(new VideoCaptureDeviceWin(device_descriptor)); |
435 DVLOG(1) << " DirectShow Device: " << device_descriptor.display_name; | 437 DVLOG(1) << " DirectShow Device: " << device_descriptor.display_name; |
436 if (!static_cast<VideoCaptureDeviceWin*>(device.get())->Init()) | 438 if (!static_cast<VideoCaptureDeviceWin*>(device.get())->Init()) |
437 device.reset(); | 439 device.reset(); |
(...skipping 23 matching lines...) Expand all Loading... |
461 } | 463 } |
462 | 464 |
463 // static | 465 // static |
464 VideoCaptureDeviceFactory* | 466 VideoCaptureDeviceFactory* |
465 VideoCaptureDeviceFactory::CreateVideoCaptureDeviceFactory( | 467 VideoCaptureDeviceFactory::CreateVideoCaptureDeviceFactory( |
466 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 468 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
467 return new VideoCaptureDeviceFactoryWin(); | 469 return new VideoCaptureDeviceFactoryWin(); |
468 } | 470 } |
469 | 471 |
470 } // namespace media | 472 } // namespace media |
OLD | NEW |