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 <stddef.h> | 9 #include <stddef.h> |
10 | 10 |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
15 #include "base/strings/sys_string_conversions.h" | 15 #include "base/strings/sys_string_conversions.h" |
16 #include "base/win/scoped_co_mem.h" | 16 #include "base/win/scoped_co_mem.h" |
17 #include "base/win/scoped_variant.h" | 17 #include "base/win/scoped_variant.h" |
18 #include "base/win/windows_version.h" | 18 #include "base/win/windows_version.h" |
19 #include "media/base/media_switches.h" | 19 #include "media/base/media_switches.h" |
20 #include "media/base/win/mf_initializer.h" | 20 #include "media/base/win/mf_initializer.h" |
21 #include "media/capture/video/win/video_capture_device_mf_win.h" | 21 #include "media/capture/video/win/video_capture_device_mf_win.h" |
22 #include "media/capture/video/win/video_capture_device_win.h" | 22 #include "media/capture/video/win/video_capture_device_win.h" |
23 | 23 |
24 using base::win::ScopedCoMem; | 24 using base::win::ScopedCoMem; |
25 using base::win::ScopedComPtr; | 25 using base::win::ScopedComPtr; |
26 using base::win::ScopedVariant; | 26 using base::win::ScopedVariant; |
27 using Name = media::VideoCaptureDevice::Name; | 27 using Descriptor = media::VideoCaptureDeviceDescriptor; |
28 using Names = media::VideoCaptureDevice::Names; | 28 using Descriptors = media::VideoCaptureDeviceDescriptors; |
29 | 29 |
30 namespace media { | 30 namespace media { |
31 | 31 |
32 // In Windows device identifiers, the USB VID and PID are preceded by the string | |
33 // "vid_" or "pid_". The identifiers are each 4 bytes long. | |
34 const char kVidPrefix[] = "vid_"; // Also contains '\0'. | |
35 const char kPidPrefix[] = "pid_"; // Also contains '\0'. | |
36 const size_t kVidPidSize = 4; | |
37 | |
32 // Avoid enumerating and/or using certain devices due to they provoking crashes | 38 // Avoid enumerating and/or using certain devices due to they provoking crashes |
33 // or any other reason (http://crbug.com/378494). This enum is defined for the | 39 // or any other reason (http://crbug.com/378494). This enum is defined for the |
34 // purposes of UMA collection. Existing entries cannot be removed. | 40 // purposes of UMA collection. Existing entries cannot be removed. |
35 enum BlacklistedCameraNames { | 41 enum BlacklistedCameraNames { |
36 BLACKLISTED_CAMERA_GOOGLE_CAMERA_ADAPTER = 0, | 42 BLACKLISTED_CAMERA_GOOGLE_CAMERA_ADAPTER = 0, |
37 BLACKLISTED_CAMERA_IP_CAMERA = 1, | 43 BLACKLISTED_CAMERA_IP_CAMERA = 1, |
38 BLACKLISTED_CAMERA_CYBERLINK_WEBCAM_SPLITTER = 2, | 44 BLACKLISTED_CAMERA_CYBERLINK_WEBCAM_SPLITTER = 2, |
39 BLACKLISTED_CAMERA_EPOCCAM = 3, | 45 BLACKLISTED_CAMERA_EPOCCAM = 3, |
40 // This one must be last, and equal to the previous enumerated value. | 46 // This one must be last, and equal to the previous enumerated value. |
41 BLACKLISTED_CAMERA_MAX = BLACKLISTED_CAMERA_EPOCCAM, | 47 BLACKLISTED_CAMERA_MAX = BLACKLISTED_CAMERA_EPOCCAM, |
42 }; | 48 }; |
43 | 49 |
44 // Blacklisted devices are identified by a characteristic prefix of the name. | 50 // Blacklisted devices are identified by a characteristic prefix of the name. |
45 // This prefix is used case-insensitively. This list must be kept in sync with | 51 // This prefix is used case-insensitively. This list must be kept in sync with |
46 // |BlacklistedCameraNames|. | 52 // |BlacklistedCameraNames|. |
47 static const char* const kBlacklistedCameraNames[] = { | 53 static const char* const kBlacklistedCameraNames[] = { |
48 // Name of a fake DirectShow filter on computers with GTalk installed. | 54 // Name of a fake DirectShow filter on computers with GTalk installed. |
49 "Google Camera Adapter", | 55 "Google Camera Adapter", |
50 // The following software WebCams cause crashes. | 56 // The following software WebCams cause crashes. |
51 "IP Camera [JPEG/MJPEG]", | 57 "IP Camera [JPEG/MJPEG]", "CyberLink Webcam Splitter", "EpocCam", |
52 "CyberLink Webcam Splitter", | |
53 "EpocCam", | |
54 }; | 58 }; |
55 static_assert(arraysize(kBlacklistedCameraNames) == BLACKLISTED_CAMERA_MAX + 1, | 59 static_assert(arraysize(kBlacklistedCameraNames) == BLACKLISTED_CAMERA_MAX + 1, |
56 "kBlacklistedCameraNames should be same size as " | 60 "kBlacklistedCameraNames should be same size as " |
57 "BlacklistedCameraNames enum"); | 61 "BlacklistedCameraNames enum"); |
58 | 62 |
59 static bool LoadMediaFoundationDlls() { | 63 static bool LoadMediaFoundationDlls() { |
60 static const wchar_t* const kMfDLLs[] = { | 64 static const wchar_t* const kMfDLLs[] = { |
61 L"%WINDIR%\\system32\\mf.dll", | 65 L"%WINDIR%\\system32\\mf.dll", |
62 L"%WINDIR%\\system32\\mfplat.dll", | 66 L"%WINDIR%\\system32\\mfplat.dll", |
63 L"%WINDIR%\\system32\\mfreadwrite.dll", | 67 L"%WINDIR%\\system32\\mfreadwrite.dll", |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
115 base::CompareCase::INSENSITIVE_ASCII)) { | 119 base::CompareCase::INSENSITIVE_ASCII)) { |
116 DVLOG(1) << "Enumerated blacklisted device: " << name; | 120 DVLOG(1) << "Enumerated blacklisted device: " << name; |
117 UMA_HISTOGRAM_ENUMERATION("Media.VideoCapture.BlacklistedDevice", i, | 121 UMA_HISTOGRAM_ENUMERATION("Media.VideoCapture.BlacklistedDevice", i, |
118 BLACKLISTED_CAMERA_MAX + 1); | 122 BLACKLISTED_CAMERA_MAX + 1); |
119 return true; | 123 return true; |
120 } | 124 } |
121 } | 125 } |
122 return false; | 126 return false; |
123 } | 127 } |
124 | 128 |
125 static void GetDeviceNamesDirectShow(Names* device_names) { | 129 static void GetDeviceDescriptorsDirectShow(Descriptors* device_descriptors) { |
126 DCHECK(device_names); | 130 DCHECK(device_descriptors); |
127 DVLOG(1) << " GetDeviceNamesDirectShow"; | 131 DVLOG(1) << " GetDeviceDescriptorsDirectShow"; |
emircan
2016/07/25 22:56:40
Replace hard coded function names with __FUNCTION_
chfremer
2016/07/26 16:56:35
Done.
| |
128 | 132 |
129 ScopedComPtr<ICreateDevEnum> dev_enum; | 133 ScopedComPtr<ICreateDevEnum> dev_enum; |
130 HRESULT hr = | 134 HRESULT hr = |
131 dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC); | 135 dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC); |
132 if (FAILED(hr)) | 136 if (FAILED(hr)) |
133 return; | 137 return; |
134 | 138 |
135 ScopedComPtr<IEnumMoniker> enum_moniker; | 139 ScopedComPtr<IEnumMoniker> enum_moniker; |
136 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, | 140 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, |
137 enum_moniker.Receive(), 0); | 141 enum_moniker.Receive(), 0); |
(...skipping 26 matching lines...) Expand all Loading... | |
164 | 168 |
165 name.Reset(); | 169 name.Reset(); |
166 hr = prop_bag->Read(L"DevicePath", name.Receive(), 0); | 170 hr = prop_bag->Read(L"DevicePath", name.Receive(), 0); |
167 std::string id; | 171 std::string id; |
168 if (FAILED(hr) || name.type() != VT_BSTR) { | 172 if (FAILED(hr) || name.type() != VT_BSTR) { |
169 id = device_name; | 173 id = device_name; |
170 } else { | 174 } else { |
171 DCHECK_EQ(name.type(), VT_BSTR); | 175 DCHECK_EQ(name.type(), VT_BSTR); |
172 id = base::SysWideToUTF8(V_BSTR(name.ptr())); | 176 id = base::SysWideToUTF8(V_BSTR(name.ptr())); |
173 } | 177 } |
174 device_names->push_back(Name(device_name, id, Name::DIRECT_SHOW)); | 178 Descriptor descriptor; |
179 descriptor.device_id = id; | |
180 descriptor.friendly_name = device_name; | |
181 descriptor.capture_api = VideoCaptureApiType::WINDOWS_DIRECT_SHOW; | |
182 device_descriptors->push_back(descriptor); | |
emircan
2016/07/25 22:56:40
Use std::list::emplace_back to avoid extra copy.
chfremer
2016/07/26 16:56:35
Done.
| |
175 } | 183 } |
176 } | 184 } |
177 | 185 |
178 static void GetDeviceNamesMediaFoundation(Names* device_names) { | 186 static void GetDeviceDescriptorsMediaFoundation( |
179 DVLOG(1) << " GetDeviceNamesMediaFoundation"; | 187 Descriptors* device_descriptors) { |
188 DVLOG(1) << " GetDeviceDescriptorsMediaFoundation"; | |
180 ScopedCoMem<IMFActivate*> devices; | 189 ScopedCoMem<IMFActivate*> devices; |
181 UINT32 count; | 190 UINT32 count; |
182 if (!EnumerateVideoDevicesMediaFoundation(&devices, &count)) | 191 if (!EnumerateVideoDevicesMediaFoundation(&devices, &count)) |
183 return; | 192 return; |
184 | 193 |
185 for (UINT32 i = 0; i < count; ++i) { | 194 for (UINT32 i = 0; i < count; ++i) { |
186 ScopedCoMem<wchar_t> name; | 195 ScopedCoMem<wchar_t> name; |
187 UINT32 name_size; | 196 UINT32 name_size; |
188 HRESULT hr = devices[i]->GetAllocatedString( | 197 HRESULT hr = devices[i]->GetAllocatedString( |
189 MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &name, &name_size); | 198 MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &name, &name_size); |
190 if (SUCCEEDED(hr)) { | 199 if (SUCCEEDED(hr)) { |
191 ScopedCoMem<wchar_t> id; | 200 ScopedCoMem<wchar_t> id; |
192 UINT32 id_size; | 201 UINT32 id_size; |
193 hr = devices[i]->GetAllocatedString( | 202 hr = devices[i]->GetAllocatedString( |
194 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &id, | 203 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &id, |
195 &id_size); | 204 &id_size); |
196 if (SUCCEEDED(hr)) { | 205 if (SUCCEEDED(hr)) { |
197 device_names->push_back( | 206 Descriptor descriptor; |
198 Name(base::SysWideToUTF8(std::wstring(name, name_size)), | 207 descriptor.friendly_name = |
199 base::SysWideToUTF8(std::wstring(id, id_size)), | 208 base::SysWideToUTF8(std::wstring(name, name_size)); |
200 Name::MEDIA_FOUNDATION)); | 209 descriptor.device_id = base::SysWideToUTF8(std::wstring(id, id_size)); |
210 descriptor.capture_api = VideoCaptureApiType::WINDOWS_MEDIA_FOUNDATION; | |
211 device_descriptors->push_back(descriptor); | |
201 } | 212 } |
202 } | 213 } |
203 DLOG_IF(ERROR, FAILED(hr)) << "GetAllocatedString failed: " | 214 DLOG_IF(ERROR, FAILED(hr)) << "GetAllocatedString failed: " |
204 << logging::SystemErrorCodeToString(hr); | 215 << logging::SystemErrorCodeToString(hr); |
205 devices[i]->Release(); | 216 devices[i]->Release(); |
206 } | 217 } |
207 } | 218 } |
208 | 219 |
209 static void GetDeviceSupportedFormatsDirectShow(const Name& device, | 220 static void GetDeviceSupportedFormatsDirectShow(const Descriptor& descriptor, |
210 VideoCaptureFormats* formats) { | 221 VideoCaptureFormats* formats) { |
211 DVLOG(1) << "GetDeviceSupportedFormatsDirectShow for " << device.name(); | 222 DVLOG(1) << "GetDeviceSupportedFormatsDirectShow for " |
223 << descriptor.friendly_name; | |
212 ScopedComPtr<ICreateDevEnum> dev_enum; | 224 ScopedComPtr<ICreateDevEnum> dev_enum; |
213 HRESULT hr = | 225 HRESULT hr = |
214 dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC); | 226 dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC); |
215 if (FAILED(hr)) | 227 if (FAILED(hr)) |
216 return; | 228 return; |
217 | 229 |
218 ScopedComPtr<IEnumMoniker> enum_moniker; | 230 ScopedComPtr<IEnumMoniker> enum_moniker; |
219 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, | 231 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, |
220 enum_moniker.Receive(), 0); | 232 enum_moniker.Receive(), 0); |
221 // CreateClassEnumerator returns S_FALSE on some Windows OS when no camera | 233 // CreateClassEnumerator returns S_FALSE on some Windows OS when no camera |
222 // exists. Therefore the FAILED macro can't be used. | 234 // exists. Therefore the FAILED macro can't be used. |
223 if (hr != S_OK) | 235 if (hr != S_OK) |
224 return; | 236 return; |
225 | 237 |
226 // Walk the capture devices. No need to check for device presence again since | 238 // Walk the capture devices. No need to check for device presence again since |
227 // that is anyway needed in GetDeviceFilter(). "google camera adapter" and old | 239 // that is anyway needed in GetDeviceFilter(). "google camera adapter" and old |
228 // VFW devices are already skipped previously in GetDeviceNames() enumeration. | 240 // VFW devices are already skipped previously in GetDeviceNames() enumeration. |
229 base::win::ScopedComPtr<IBaseFilter> capture_filter; | 241 base::win::ScopedComPtr<IBaseFilter> capture_filter; |
230 hr = VideoCaptureDeviceWin::GetDeviceFilter(device.capabilities_id(), | 242 hr = VideoCaptureDeviceWin::GetDeviceFilter(descriptor.device_id, |
231 capture_filter.Receive()); | 243 capture_filter.Receive()); |
232 if (!capture_filter.get()) { | 244 if (!capture_filter.get()) { |
233 DLOG(ERROR) << "Failed to create capture filter: " | 245 DLOG(ERROR) << "Failed to create capture filter: " |
234 << logging::SystemErrorCodeToString(hr); | 246 << logging::SystemErrorCodeToString(hr); |
235 return; | 247 return; |
236 } | 248 } |
237 | 249 |
238 base::win::ScopedComPtr<IPin> output_capture_pin( | 250 base::win::ScopedComPtr<IPin> output_capture_pin( |
239 VideoCaptureDeviceWin::GetPin(capture_filter.get(), PINDIR_OUTPUT, | 251 VideoCaptureDeviceWin::GetPin(capture_filter.get(), PINDIR_OUTPUT, |
240 PIN_CATEGORY_CAPTURE, GUID_NULL)); | 252 PIN_CATEGORY_CAPTURE, GUID_NULL)); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
281 continue; | 293 continue; |
282 VIDEOINFOHEADER* h = | 294 VIDEOINFOHEADER* h = |
283 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); | 295 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); |
284 format.frame_size.SetSize(h->bmiHeader.biWidth, h->bmiHeader.biHeight); | 296 format.frame_size.SetSize(h->bmiHeader.biWidth, h->bmiHeader.biHeight); |
285 // Trust the frame rate from the VIDEOINFOHEADER. | 297 // Trust the frame rate from the VIDEOINFOHEADER. |
286 format.frame_rate = | 298 format.frame_rate = |
287 (h->AvgTimePerFrame > 0) | 299 (h->AvgTimePerFrame > 0) |
288 ? kSecondsToReferenceTime / static_cast<float>(h->AvgTimePerFrame) | 300 ? kSecondsToReferenceTime / static_cast<float>(h->AvgTimePerFrame) |
289 : 0.0f; | 301 : 0.0f; |
290 formats->push_back(format); | 302 formats->push_back(format); |
291 DVLOG(1) << device.name() << " " << VideoCaptureFormat::ToString(format); | 303 DVLOG(1) << descriptor.friendly_name << " " |
304 << VideoCaptureFormat::ToString(format); | |
292 } | 305 } |
293 } | 306 } |
294 } | 307 } |
295 | 308 |
296 static void GetDeviceSupportedFormatsMediaFoundation( | 309 static void GetDeviceSupportedFormatsMediaFoundation( |
297 const Name& device, | 310 const Descriptor& descriptor, |
298 VideoCaptureFormats* formats) { | 311 VideoCaptureFormats* formats) { |
299 DVLOG(1) << "GetDeviceSupportedFormatsMediaFoundation for " << device.name(); | 312 DVLOG(1) << "GetDeviceSupportedFormatsMediaFoundation for " |
313 << descriptor.friendly_name; | |
300 ScopedComPtr<IMFMediaSource> source; | 314 ScopedComPtr<IMFMediaSource> source; |
301 if (!CreateVideoCaptureDeviceMediaFoundation(device.id().c_str(), | 315 if (!CreateVideoCaptureDeviceMediaFoundation(descriptor.device_id.c_str(), |
302 source.Receive())) { | 316 source.Receive())) { |
303 return; | 317 return; |
304 } | 318 } |
305 | 319 |
306 base::win::ScopedComPtr<IMFSourceReader> reader; | 320 base::win::ScopedComPtr<IMFSourceReader> reader; |
307 HRESULT hr = | 321 HRESULT hr = |
308 MFCreateSourceReaderFromMediaSource(source.get(), NULL, reader.Receive()); | 322 MFCreateSourceReaderFromMediaSource(source.get(), NULL, reader.Receive()); |
309 if (FAILED(hr)) { | 323 if (FAILED(hr)) { |
310 DLOG(ERROR) << "MFCreateSourceReaderFromMediaSource failed: " | 324 DLOG(ERROR) << "MFCreateSourceReaderFromMediaSource failed: " |
311 << logging::SystemErrorCodeToString(hr); | 325 << logging::SystemErrorCodeToString(hr); |
(...skipping 30 matching lines...) Expand all Loading... | |
342 if (FAILED(hr)) { | 356 if (FAILED(hr)) { |
343 DLOG(ERROR) << "GetGUID failed: " << logging::SystemErrorCodeToString(hr); | 357 DLOG(ERROR) << "GetGUID failed: " << logging::SystemErrorCodeToString(hr); |
344 return; | 358 return; |
345 } | 359 } |
346 VideoCaptureDeviceMFWin::FormatFromGuid(type_guid, | 360 VideoCaptureDeviceMFWin::FormatFromGuid(type_guid, |
347 &capture_format.pixel_format); | 361 &capture_format.pixel_format); |
348 type.Release(); | 362 type.Release(); |
349 formats->push_back(capture_format); | 363 formats->push_back(capture_format); |
350 ++stream_index; | 364 ++stream_index; |
351 | 365 |
352 DVLOG(1) << device.name() << " " | 366 DVLOG(1) << descriptor.friendly_name << " " |
353 << VideoCaptureFormat::ToString(capture_format); | 367 << VideoCaptureFormat::ToString(capture_format); |
354 } | 368 } |
355 } | 369 } |
356 | 370 |
357 // Returns true iff the current platform supports the Media Foundation API | 371 // Returns true iff the current platform supports the Media Foundation API |
358 // and that the DLLs are available. On Vista this API is an optional download | 372 // and that the DLLs are available. On Vista this API is an optional download |
359 // but the API is advertised as a part of Windows 7 and onwards. However, | 373 // but the API is advertised as a part of Windows 7 and onwards. However, |
360 // we've seen that the required DLLs are not available in some Win7 | 374 // we've seen that the required DLLs are not available in some Win7 |
361 // distributions such as Windows 7 N and Windows 7 KN. | 375 // distributions such as Windows 7 N and Windows 7 KN. |
362 // static | 376 // static |
363 bool VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation() { | 377 bool VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation() { |
364 // Even though the DLLs might be available on Vista, we get crashes | 378 // Even though the DLLs might be available on Vista, we get crashes |
365 // when running our tests on the build bots. | 379 // when running our tests on the build bots. |
366 if (base::win::GetVersion() < base::win::VERSION_WIN7) | 380 if (base::win::GetVersion() < base::win::VERSION_WIN7) |
367 return false; | 381 return false; |
368 | 382 |
369 static bool g_dlls_available = LoadMediaFoundationDlls(); | 383 static bool g_dlls_available = LoadMediaFoundationDlls(); |
370 return g_dlls_available; | 384 return g_dlls_available; |
371 } | 385 } |
372 | 386 |
373 VideoCaptureDeviceFactoryWin::VideoCaptureDeviceFactoryWin() | 387 VideoCaptureDeviceFactoryWin::VideoCaptureDeviceFactoryWin() |
374 : use_media_foundation_(base::win::GetVersion() >= | 388 : use_media_foundation_(base::win::GetVersion() >= |
375 base::win::VERSION_WIN7 && | 389 base::win::VERSION_WIN7 && |
376 base::CommandLine::ForCurrentProcess()->HasSwitch( | 390 base::CommandLine::ForCurrentProcess()->HasSwitch( |
377 switches::kForceMediaFoundationVideoCapture)) {} | 391 switches::kForceMediaFoundationVideoCapture)) {} |
378 | 392 |
379 std::unique_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryWin::Create( | 393 std::unique_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryWin::Create( |
380 const Name& device_name) { | 394 const Descriptor& device_descriptor) { |
381 DCHECK(thread_checker_.CalledOnValidThread()); | 395 DCHECK(thread_checker_.CalledOnValidThread()); |
382 std::unique_ptr<VideoCaptureDevice> device; | 396 std::unique_ptr<VideoCaptureDevice> device; |
383 if (device_name.capture_api_type() == Name::MEDIA_FOUNDATION) { | 397 if (device_descriptor.capture_api == |
398 VideoCaptureApiType::WINDOWS_MEDIA_FOUNDATION) { | |
384 DCHECK(PlatformSupportsMediaFoundation()); | 399 DCHECK(PlatformSupportsMediaFoundation()); |
385 device.reset(new VideoCaptureDeviceMFWin(device_name)); | 400 device.reset(new VideoCaptureDeviceMFWin(device_descriptor)); |
386 DVLOG(1) << " MediaFoundation Device: " << device_name.name(); | 401 DVLOG(1) << " MediaFoundation Device: " << device_descriptor.friendly_name; |
387 ScopedComPtr<IMFMediaSource> source; | 402 ScopedComPtr<IMFMediaSource> source; |
388 if (!CreateVideoCaptureDeviceMediaFoundation(device_name.id().c_str(), | 403 if (!CreateVideoCaptureDeviceMediaFoundation( |
389 source.Receive())) { | 404 device_descriptor.device_id.c_str(), source.Receive())) { |
390 return std::unique_ptr<VideoCaptureDevice>(); | 405 return std::unique_ptr<VideoCaptureDevice>(); |
391 } | 406 } |
392 if (!static_cast<VideoCaptureDeviceMFWin*>(device.get())->Init(source)) | 407 if (!static_cast<VideoCaptureDeviceMFWin*>(device.get())->Init(source)) |
393 device.reset(); | 408 device.reset(); |
394 } else { | 409 } else if (device_descriptor.capture_api == |
395 DCHECK(device_name.capture_api_type() == Name::DIRECT_SHOW); | 410 VideoCaptureApiType::WINDOWS_DIRECT_SHOW) { |
396 device.reset(new VideoCaptureDeviceWin(device_name)); | 411 device.reset(new VideoCaptureDeviceWin(device_descriptor)); |
397 DVLOG(1) << " DirectShow Device: " << device_name.name(); | 412 DVLOG(1) << " DirectShow Device: " << device_descriptor.friendly_name; |
398 if (!static_cast<VideoCaptureDeviceWin*>(device.get())->Init()) | 413 if (!static_cast<VideoCaptureDeviceWin*>(device.get())->Init()) |
399 device.reset(); | 414 device.reset(); |
415 } else { | |
416 NOTREACHED(); | |
400 } | 417 } |
401 return device; | 418 return device; |
402 } | 419 } |
403 | 420 |
404 void VideoCaptureDeviceFactoryWin::GetDeviceNames(Names* device_names) { | 421 void VideoCaptureDeviceFactoryWin::GetDeviceDescriptors( |
422 VideoCaptureDeviceDescriptors* device_descriptors) { | |
405 DCHECK(thread_checker_.CalledOnValidThread()); | 423 DCHECK(thread_checker_.CalledOnValidThread()); |
406 if (use_media_foundation_) | 424 if (use_media_foundation_) |
407 GetDeviceNamesMediaFoundation(device_names); | 425 GetDeviceDescriptorsMediaFoundation(device_descriptors); |
408 else | 426 else |
409 GetDeviceNamesDirectShow(device_names); | 427 GetDeviceDescriptorsDirectShow(device_descriptors); |
428 } | |
429 | |
430 void VideoCaptureDeviceFactoryWin::GetDeviceInfo( | |
431 const VideoCaptureDeviceDescriptor& device_descriptor, | |
432 VideoCaptureDeviceInfo* device_info) { | |
433 DCHECK(device_info); | |
434 device_info->descriptor = device_descriptor; | |
435 GetDeviceSupportedFormats(device_descriptor, | |
436 &(device_info->supported_formats)); | |
437 device_info->model_id = GetDeviceModelId(device_descriptor); | |
410 } | 438 } |
411 | 439 |
412 void VideoCaptureDeviceFactoryWin::GetDeviceSupportedFormats( | 440 void VideoCaptureDeviceFactoryWin::GetDeviceSupportedFormats( |
413 const Name& device, | 441 const Descriptor& device, |
414 VideoCaptureFormats* formats) { | 442 VideoCaptureFormats* formats) { |
415 DCHECK(thread_checker_.CalledOnValidThread()); | 443 DCHECK(thread_checker_.CalledOnValidThread()); |
416 if (use_media_foundation_) | 444 if (use_media_foundation_) { |
417 GetDeviceSupportedFormatsMediaFoundation(device, formats); | 445 GetDeviceSupportedFormatsMediaFoundation(device, formats); |
418 else | 446 } else { |
419 GetDeviceSupportedFormatsDirectShow(device, formats); | 447 GetDeviceSupportedFormatsDirectShow(device, formats); |
448 } | |
449 } | |
450 | |
451 std::string VideoCaptureDeviceFactoryWin::GetDeviceModelId( | |
452 const Descriptor& device_descriptor) { | |
453 const size_t vid_prefix_size = sizeof(kVidPrefix) - 1; | |
454 const size_t pid_prefix_size = sizeof(kPidPrefix) - 1; | |
455 const size_t vid_location = device_descriptor.device_id.find(kVidPrefix); | |
456 if (vid_location == std::string::npos || | |
457 vid_location + vid_prefix_size + kVidPidSize > | |
458 device_descriptor.device_id.size()) { | |
459 return std::string(); | |
460 } | |
461 const size_t pid_location = device_descriptor.device_id.find(kPidPrefix); | |
462 if (pid_location == std::string::npos || | |
463 pid_location + pid_prefix_size + kVidPidSize > | |
464 device_descriptor.device_id.size()) { | |
465 return std::string(); | |
466 } | |
467 std::string id_vendor = device_descriptor.device_id.substr( | |
emircan
2016/07/25 22:56:40
const
chfremer
2016/07/26 16:56:35
Done.
| |
468 vid_location + vid_prefix_size, kVidPidSize); | |
469 std::string id_product = device_descriptor.device_id.substr( | |
emircan
2016/07/25 22:56:40
const
chfremer
2016/07/26 16:56:35
Done.
| |
470 pid_location + pid_prefix_size, kVidPidSize); | |
471 return id_vendor + ":" + id_product; | |
420 } | 472 } |
421 | 473 |
422 // static | 474 // static |
423 VideoCaptureDeviceFactory* | 475 VideoCaptureDeviceFactory* |
424 VideoCaptureDeviceFactory::CreateVideoCaptureDeviceFactory( | 476 VideoCaptureDeviceFactory::CreateVideoCaptureDeviceFactory( |
425 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 477 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
426 return new VideoCaptureDeviceFactoryWin(); | 478 return new VideoCaptureDeviceFactoryWin(); |
427 } | 479 } |
428 | 480 |
429 } // namespace media | 481 } // namespace media |
OLD | NEW |