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; | |
mcasas
2016/07/26 23:52:04
Maybe we can use arraysize() here? (It might
need
chfremer
2016/07/27 23:10:18
By "here" do you mean on the right hand sight of l
mcasas
2016/07/28 00:05:42
Oh I see :)
What about calling l.36 |kVidPidFieldS
| |
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) << __FUNCTION__; |
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 device_descriptors->emplace_back(device_name, id, |
179 VideoCaptureApiType::WINDOWS_DIRECT_SHOW); | |
175 } | 180 } |
176 } | 181 } |
177 | 182 |
178 static void GetDeviceNamesMediaFoundation(Names* device_names) { | 183 static void GetDeviceDescriptorsMediaFoundation( |
179 DVLOG(1) << " GetDeviceNamesMediaFoundation"; | 184 Descriptors* device_descriptors) { |
185 DVLOG(1) << " GetDeviceDescriptorsMediaFoundation"; | |
180 ScopedCoMem<IMFActivate*> devices; | 186 ScopedCoMem<IMFActivate*> devices; |
181 UINT32 count; | 187 UINT32 count; |
182 if (!EnumerateVideoDevicesMediaFoundation(&devices, &count)) | 188 if (!EnumerateVideoDevicesMediaFoundation(&devices, &count)) |
183 return; | 189 return; |
184 | 190 |
185 for (UINT32 i = 0; i < count; ++i) { | 191 for (UINT32 i = 0; i < count; ++i) { |
186 ScopedCoMem<wchar_t> name; | 192 ScopedCoMem<wchar_t> name; |
187 UINT32 name_size; | 193 UINT32 name_size; |
188 HRESULT hr = devices[i]->GetAllocatedString( | 194 HRESULT hr = devices[i]->GetAllocatedString( |
189 MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &name, &name_size); | 195 MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &name, &name_size); |
190 if (SUCCEEDED(hr)) { | 196 if (SUCCEEDED(hr)) { |
191 ScopedCoMem<wchar_t> id; | 197 ScopedCoMem<wchar_t> id; |
192 UINT32 id_size; | 198 UINT32 id_size; |
193 hr = devices[i]->GetAllocatedString( | 199 hr = devices[i]->GetAllocatedString( |
194 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &id, | 200 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &id, |
195 &id_size); | 201 &id_size); |
196 if (SUCCEEDED(hr)) { | 202 if (SUCCEEDED(hr)) { |
197 device_names->push_back( | 203 device_descriptors->emplace_back( |
198 Name(base::SysWideToUTF8(std::wstring(name, name_size)), | 204 base::SysWideToUTF8(std::wstring(name, name_size)), |
199 base::SysWideToUTF8(std::wstring(id, id_size)), | 205 base::SysWideToUTF8(std::wstring(id, id_size)), |
200 Name::MEDIA_FOUNDATION)); | 206 VideoCaptureApiType::WINDOWS_MEDIA_FOUNDATION); |
201 } | 207 } |
202 } | 208 } |
203 DLOG_IF(ERROR, FAILED(hr)) << "GetAllocatedString failed: " | 209 DLOG_IF(ERROR, FAILED(hr)) << "GetAllocatedString failed: " |
204 << logging::SystemErrorCodeToString(hr); | 210 << logging::SystemErrorCodeToString(hr); |
205 devices[i]->Release(); | 211 devices[i]->Release(); |
206 } | 212 } |
207 } | 213 } |
208 | 214 |
209 static void GetDeviceSupportedFormatsDirectShow(const Name& device, | 215 static void GetDeviceSupportedFormatsDirectShow(const Descriptor& descriptor, |
210 VideoCaptureFormats* formats) { | 216 VideoCaptureFormats* formats) { |
211 DVLOG(1) << "GetDeviceSupportedFormatsDirectShow for " << device.name(); | 217 DVLOG(1) << "GetDeviceSupportedFormatsDirectShow for " |
218 << descriptor.friendly_name; | |
212 ScopedComPtr<ICreateDevEnum> dev_enum; | 219 ScopedComPtr<ICreateDevEnum> dev_enum; |
213 HRESULT hr = | 220 HRESULT hr = |
214 dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC); | 221 dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC); |
215 if (FAILED(hr)) | 222 if (FAILED(hr)) |
216 return; | 223 return; |
217 | 224 |
218 ScopedComPtr<IEnumMoniker> enum_moniker; | 225 ScopedComPtr<IEnumMoniker> enum_moniker; |
219 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, | 226 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, |
220 enum_moniker.Receive(), 0); | 227 enum_moniker.Receive(), 0); |
221 // CreateClassEnumerator returns S_FALSE on some Windows OS when no camera | 228 // CreateClassEnumerator returns S_FALSE on some Windows OS when no camera |
222 // exists. Therefore the FAILED macro can't be used. | 229 // exists. Therefore the FAILED macro can't be used. |
223 if (hr != S_OK) | 230 if (hr != S_OK) |
224 return; | 231 return; |
225 | 232 |
226 // Walk the capture devices. No need to check for device presence again since | 233 // 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 | 234 // that is anyway needed in GetDeviceFilter(). "google camera adapter" and old |
228 // VFW devices are already skipped previously in GetDeviceNames() enumeration. | 235 // VFW devices are already skipped previously in GetDeviceNames() enumeration. |
229 base::win::ScopedComPtr<IBaseFilter> capture_filter; | 236 base::win::ScopedComPtr<IBaseFilter> capture_filter; |
230 hr = VideoCaptureDeviceWin::GetDeviceFilter(device.capabilities_id(), | 237 hr = VideoCaptureDeviceWin::GetDeviceFilter(descriptor.device_id, |
231 capture_filter.Receive()); | 238 capture_filter.Receive()); |
232 if (!capture_filter.get()) { | 239 if (!capture_filter.get()) { |
233 DLOG(ERROR) << "Failed to create capture filter: " | 240 DLOG(ERROR) << "Failed to create capture filter: " |
234 << logging::SystemErrorCodeToString(hr); | 241 << logging::SystemErrorCodeToString(hr); |
235 return; | 242 return; |
236 } | 243 } |
237 | 244 |
238 base::win::ScopedComPtr<IPin> output_capture_pin( | 245 base::win::ScopedComPtr<IPin> output_capture_pin( |
239 VideoCaptureDeviceWin::GetPin(capture_filter.get(), PINDIR_OUTPUT, | 246 VideoCaptureDeviceWin::GetPin(capture_filter.get(), PINDIR_OUTPUT, |
240 PIN_CATEGORY_CAPTURE, GUID_NULL)); | 247 PIN_CATEGORY_CAPTURE, GUID_NULL)); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
281 continue; | 288 continue; |
282 VIDEOINFOHEADER* h = | 289 VIDEOINFOHEADER* h = |
283 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); | 290 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); |
284 format.frame_size.SetSize(h->bmiHeader.biWidth, h->bmiHeader.biHeight); | 291 format.frame_size.SetSize(h->bmiHeader.biWidth, h->bmiHeader.biHeight); |
285 // Trust the frame rate from the VIDEOINFOHEADER. | 292 // Trust the frame rate from the VIDEOINFOHEADER. |
286 format.frame_rate = | 293 format.frame_rate = |
287 (h->AvgTimePerFrame > 0) | 294 (h->AvgTimePerFrame > 0) |
288 ? kSecondsToReferenceTime / static_cast<float>(h->AvgTimePerFrame) | 295 ? kSecondsToReferenceTime / static_cast<float>(h->AvgTimePerFrame) |
289 : 0.0f; | 296 : 0.0f; |
290 formats->push_back(format); | 297 formats->push_back(format); |
291 DVLOG(1) << device.name() << " " << VideoCaptureFormat::ToString(format); | 298 DVLOG(1) << descriptor.friendly_name << " " |
299 << VideoCaptureFormat::ToString(format); | |
292 } | 300 } |
293 } | 301 } |
294 } | 302 } |
295 | 303 |
296 static void GetDeviceSupportedFormatsMediaFoundation( | 304 static void GetDeviceSupportedFormatsMediaFoundation( |
297 const Name& device, | 305 const Descriptor& descriptor, |
298 VideoCaptureFormats* formats) { | 306 VideoCaptureFormats* formats) { |
299 DVLOG(1) << "GetDeviceSupportedFormatsMediaFoundation for " << device.name(); | 307 DVLOG(1) << "GetDeviceSupportedFormatsMediaFoundation for " |
308 << descriptor.friendly_name; | |
300 ScopedComPtr<IMFMediaSource> source; | 309 ScopedComPtr<IMFMediaSource> source; |
301 if (!CreateVideoCaptureDeviceMediaFoundation(device.id().c_str(), | 310 if (!CreateVideoCaptureDeviceMediaFoundation(descriptor.device_id.c_str(), |
302 source.Receive())) { | 311 source.Receive())) { |
303 return; | 312 return; |
304 } | 313 } |
305 | 314 |
306 base::win::ScopedComPtr<IMFSourceReader> reader; | 315 base::win::ScopedComPtr<IMFSourceReader> reader; |
307 HRESULT hr = | 316 HRESULT hr = |
308 MFCreateSourceReaderFromMediaSource(source.get(), NULL, reader.Receive()); | 317 MFCreateSourceReaderFromMediaSource(source.get(), NULL, reader.Receive()); |
309 if (FAILED(hr)) { | 318 if (FAILED(hr)) { |
310 DLOG(ERROR) << "MFCreateSourceReaderFromMediaSource failed: " | 319 DLOG(ERROR) << "MFCreateSourceReaderFromMediaSource failed: " |
311 << logging::SystemErrorCodeToString(hr); | 320 << logging::SystemErrorCodeToString(hr); |
(...skipping 30 matching lines...) Expand all Loading... | |
342 if (FAILED(hr)) { | 351 if (FAILED(hr)) { |
343 DLOG(ERROR) << "GetGUID failed: " << logging::SystemErrorCodeToString(hr); | 352 DLOG(ERROR) << "GetGUID failed: " << logging::SystemErrorCodeToString(hr); |
344 return; | 353 return; |
345 } | 354 } |
346 VideoCaptureDeviceMFWin::FormatFromGuid(type_guid, | 355 VideoCaptureDeviceMFWin::FormatFromGuid(type_guid, |
347 &capture_format.pixel_format); | 356 &capture_format.pixel_format); |
348 type.Release(); | 357 type.Release(); |
349 formats->push_back(capture_format); | 358 formats->push_back(capture_format); |
350 ++stream_index; | 359 ++stream_index; |
351 | 360 |
352 DVLOG(1) << device.name() << " " | 361 DVLOG(1) << descriptor.friendly_name << " " |
353 << VideoCaptureFormat::ToString(capture_format); | 362 << VideoCaptureFormat::ToString(capture_format); |
354 } | 363 } |
355 } | 364 } |
356 | 365 |
357 // Returns true iff the current platform supports the Media Foundation API | 366 // 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 | 367 // 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, | 368 // 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 | 369 // we've seen that the required DLLs are not available in some Win7 |
361 // distributions such as Windows 7 N and Windows 7 KN. | 370 // distributions such as Windows 7 N and Windows 7 KN. |
362 // static | 371 // static |
363 bool VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation() { | 372 bool VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation() { |
364 // Even though the DLLs might be available on Vista, we get crashes | 373 // Even though the DLLs might be available on Vista, we get crashes |
365 // when running our tests on the build bots. | 374 // when running our tests on the build bots. |
366 if (base::win::GetVersion() < base::win::VERSION_WIN7) | 375 if (base::win::GetVersion() < base::win::VERSION_WIN7) |
367 return false; | 376 return false; |
368 | 377 |
369 static bool g_dlls_available = LoadMediaFoundationDlls(); | 378 static bool g_dlls_available = LoadMediaFoundationDlls(); |
370 return g_dlls_available; | 379 return g_dlls_available; |
371 } | 380 } |
372 | 381 |
373 VideoCaptureDeviceFactoryWin::VideoCaptureDeviceFactoryWin() | 382 VideoCaptureDeviceFactoryWin::VideoCaptureDeviceFactoryWin() |
374 : use_media_foundation_(base::win::GetVersion() >= | 383 : use_media_foundation_(base::win::GetVersion() >= |
375 base::win::VERSION_WIN7 && | 384 base::win::VERSION_WIN7 && |
376 base::CommandLine::ForCurrentProcess()->HasSwitch( | 385 base::CommandLine::ForCurrentProcess()->HasSwitch( |
377 switches::kForceMediaFoundationVideoCapture)) {} | 386 switches::kForceMediaFoundationVideoCapture)) {} |
378 | 387 |
379 std::unique_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryWin::Create( | 388 std::unique_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryWin::Create( |
380 const Name& device_name) { | 389 const Descriptor& device_descriptor) { |
381 DCHECK(thread_checker_.CalledOnValidThread()); | 390 DCHECK(thread_checker_.CalledOnValidThread()); |
382 std::unique_ptr<VideoCaptureDevice> device; | 391 std::unique_ptr<VideoCaptureDevice> device; |
383 if (device_name.capture_api_type() == Name::MEDIA_FOUNDATION) { | 392 if (device_descriptor.capture_api == |
393 VideoCaptureApiType::WINDOWS_MEDIA_FOUNDATION) { | |
384 DCHECK(PlatformSupportsMediaFoundation()); | 394 DCHECK(PlatformSupportsMediaFoundation()); |
385 device.reset(new VideoCaptureDeviceMFWin(device_name)); | 395 device.reset(new VideoCaptureDeviceMFWin(device_descriptor)); |
386 DVLOG(1) << " MediaFoundation Device: " << device_name.name(); | 396 DVLOG(1) << " MediaFoundation Device: " << device_descriptor.friendly_name; |
387 ScopedComPtr<IMFMediaSource> source; | 397 ScopedComPtr<IMFMediaSource> source; |
388 if (!CreateVideoCaptureDeviceMediaFoundation(device_name.id().c_str(), | 398 if (!CreateVideoCaptureDeviceMediaFoundation( |
389 source.Receive())) { | 399 device_descriptor.device_id.c_str(), source.Receive())) { |
390 return std::unique_ptr<VideoCaptureDevice>(); | 400 return std::unique_ptr<VideoCaptureDevice>(); |
391 } | 401 } |
392 if (!static_cast<VideoCaptureDeviceMFWin*>(device.get())->Init(source)) | 402 if (!static_cast<VideoCaptureDeviceMFWin*>(device.get())->Init(source)) |
393 device.reset(); | 403 device.reset(); |
394 } else { | 404 } else if (device_descriptor.capture_api == |
395 DCHECK(device_name.capture_api_type() == Name::DIRECT_SHOW); | 405 VideoCaptureApiType::WINDOWS_DIRECT_SHOW) { |
396 device.reset(new VideoCaptureDeviceWin(device_name)); | 406 device.reset(new VideoCaptureDeviceWin(device_descriptor)); |
397 DVLOG(1) << " DirectShow Device: " << device_name.name(); | 407 DVLOG(1) << " DirectShow Device: " << device_descriptor.friendly_name; |
398 if (!static_cast<VideoCaptureDeviceWin*>(device.get())->Init()) | 408 if (!static_cast<VideoCaptureDeviceWin*>(device.get())->Init()) |
399 device.reset(); | 409 device.reset(); |
410 } else { | |
411 NOTREACHED(); | |
400 } | 412 } |
401 return device; | 413 return device; |
402 } | 414 } |
403 | 415 |
404 void VideoCaptureDeviceFactoryWin::GetDeviceNames(Names* device_names) { | 416 void VideoCaptureDeviceFactoryWin::GetDeviceDescriptors( |
417 VideoCaptureDeviceDescriptors* device_descriptors) { | |
405 DCHECK(thread_checker_.CalledOnValidThread()); | 418 DCHECK(thread_checker_.CalledOnValidThread()); |
406 if (use_media_foundation_) | 419 if (use_media_foundation_) |
407 GetDeviceNamesMediaFoundation(device_names); | 420 GetDeviceDescriptorsMediaFoundation(device_descriptors); |
408 else | 421 else |
409 GetDeviceNamesDirectShow(device_names); | 422 GetDeviceDescriptorsDirectShow(device_descriptors); |
423 } | |
424 | |
425 void VideoCaptureDeviceFactoryWin::GetDeviceInfo( | |
426 const VideoCaptureDeviceDescriptor& device_descriptor, | |
427 VideoCaptureDeviceInfo* device_info) { | |
428 DCHECK(device_info); | |
429 device_info->descriptor = device_descriptor; | |
430 GetDeviceSupportedFormats(device_descriptor, | |
431 &(device_info->supported_formats)); | |
432 device_info->model_id = GetDeviceModelId(device_descriptor); | |
410 } | 433 } |
411 | 434 |
412 void VideoCaptureDeviceFactoryWin::GetDeviceSupportedFormats( | 435 void VideoCaptureDeviceFactoryWin::GetDeviceSupportedFormats( |
413 const Name& device, | 436 const Descriptor& device, |
414 VideoCaptureFormats* formats) { | 437 VideoCaptureFormats* formats) { |
415 DCHECK(thread_checker_.CalledOnValidThread()); | 438 DCHECK(thread_checker_.CalledOnValidThread()); |
416 if (use_media_foundation_) | 439 if (use_media_foundation_) { |
417 GetDeviceSupportedFormatsMediaFoundation(device, formats); | 440 GetDeviceSupportedFormatsMediaFoundation(device, formats); |
418 else | 441 } else { |
419 GetDeviceSupportedFormatsDirectShow(device, formats); | 442 GetDeviceSupportedFormatsDirectShow(device, formats); |
443 } | |
444 } | |
445 | |
446 std::string VideoCaptureDeviceFactoryWin::GetDeviceModelId( | |
447 const Descriptor& device_descriptor) { | |
448 const size_t vid_prefix_size = sizeof(kVidPrefix) - 1; | |
mcasas
2016/07/26 23:52:04
I thought sizeof(kVidPrefix) - 1 was called
|kVidP
chfremer
2016/07/27 23:10:18
That also confused me at first. It is because ther
mcasas
2016/07/28 00:05:42
Acknowledged.
| |
449 const size_t pid_prefix_size = sizeof(kPidPrefix) - 1; | |
450 const size_t vid_location = device_descriptor.device_id.find(kVidPrefix); | |
451 if (vid_location == std::string::npos || | |
452 vid_location + vid_prefix_size + kVidPidSize > | |
453 device_descriptor.device_id.size()) { | |
454 return std::string(); | |
455 } | |
456 const size_t pid_location = device_descriptor.device_id.find(kPidPrefix); | |
457 if (pid_location == std::string::npos || | |
458 pid_location + pid_prefix_size + kVidPidSize > | |
459 device_descriptor.device_id.size()) { | |
460 return std::string(); | |
461 } | |
462 const std::string id_vendor = device_descriptor.device_id.substr( | |
463 vid_location + vid_prefix_size, kVidPidSize); | |
464 const std::string id_product = device_descriptor.device_id.substr( | |
465 pid_location + pid_prefix_size, kVidPidSize); | |
466 return id_vendor + ":" + id_product; | |
420 } | 467 } |
421 | 468 |
422 // static | 469 // static |
423 VideoCaptureDeviceFactory* | 470 VideoCaptureDeviceFactory* |
424 VideoCaptureDeviceFactory::CreateVideoCaptureDeviceFactory( | 471 VideoCaptureDeviceFactory::CreateVideoCaptureDeviceFactory( |
425 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 472 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
426 return new VideoCaptureDeviceFactoryWin(); | 473 return new VideoCaptureDeviceFactoryWin(); |
427 } | 474 } |
428 | 475 |
429 } // namespace media | 476 } // namespace media |
OLD | NEW |