Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: media/capture/video/win/video_capture_device_factory_win.cc

Issue 2169013002: Change class VideoCaptureDevice::Name to struct VideoCaptureDeviceDescriptor (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed emircan's comments Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698