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

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: Refactoring of VideoCaptureDeviceFactory interface 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;
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) << " 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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698