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/video/capture/win/video_capture_device_factory_win.h" | 5 #include "media/video/capture/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 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/lazy_instance.h" |
11 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
12 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
13 #include "base/strings/sys_string_conversions.h" | 14 #include "base/strings/sys_string_conversions.h" |
14 #include "base/win/metro.h" | 15 #include "base/win/metro.h" |
15 #include "base/win/scoped_co_mem.h" | 16 #include "base/win/scoped_co_mem.h" |
16 #include "base/win/scoped_variant.h" | 17 #include "base/win/scoped_variant.h" |
17 #include "base/win/windows_version.h" | 18 #include "base/win/windows_version.h" |
18 #include "media/base/media_switches.h" | 19 #include "media/base/media_switches.h" |
19 #include "media/base/win/mf_initializer.h" | |
20 #include "media/video/capture/win/video_capture_device_mf_win.h" | 20 #include "media/video/capture/win/video_capture_device_mf_win.h" |
21 #include "media/video/capture/win/video_capture_device_win.h" | 21 #include "media/video/capture/win/video_capture_device_win.h" |
22 | 22 |
23 using base::win::ScopedCoMem; | 23 using base::win::ScopedCoMem; |
24 using base::win::ScopedComPtr; | 24 using base::win::ScopedComPtr; |
25 using base::win::ScopedVariant; | 25 using base::win::ScopedVariant; |
26 using Name = media::VideoCaptureDevice::Name; | 26 using Name = media::VideoCaptureDevice::Name; |
27 using Names = media::VideoCaptureDevice::Names; | 27 using Names = media::VideoCaptureDevice::Names; |
28 | 28 |
29 namespace media { | 29 namespace media { |
30 | 30 |
31 // We would like to avoid enumerating and/or using certain devices due to they | 31 // We would like to avoid enumerating and/or using certain devices due to they |
32 // provoking crashes or any other reason. This enum is defined for the purposes | 32 // provoking crashes or any other reason. This enum is defined for the purposes |
33 // of UMA collection. Existing entries cannot be removed. | 33 // of UMA collection. Existing entries cannot be removed. |
34 enum BlacklistedCameraNames { | 34 enum BlacklistedCameraNames { |
35 BLACKLISTED_CAMERA_GOOGLE_CAMERA_ADAPTER, | 35 BLACKLISTED_CAMERA_GOOGLE_CAMERA_ADAPTER, |
36 BLACKLISTED_CAMERA_IP_CAMERA, | 36 BLACKLISTED_CAMERA_IP_CAMERA, |
37 BLACKLISTED_CAMERA_CYBERLINK_WEBCAM_SPLITTER, | 37 BLACKLISTED_CAMERA_CYBERLINK_WEBCAM_SPLITTER, |
38 // This one must be last, and equal to the previous enumerated value. | 38 // This one must be last, and equal to the previous enumerated value. |
39 BLACKLISTED_CAMERA_MAX = BLACKLISTED_CAMERA_CYBERLINK_WEBCAM_SPLITTER | 39 BLACKLISTED_CAMERA_MAX = BLACKLISTED_CAMERA_CYBERLINK_WEBCAM_SPLITTER |
40 }; | 40 }; |
41 | 41 |
| 42 // Lazy Instance to initialize the MediaFoundation Library. |
| 43 class MFInitializerSingleton { |
| 44 public: |
| 45 MFInitializerSingleton() { MFStartup(MF_VERSION, MFSTARTUP_LITE); } |
| 46 ~MFInitializerSingleton() { MFShutdown(); } |
| 47 }; |
| 48 |
| 49 static base::LazyInstance<MFInitializerSingleton> g_mf_initialize = |
| 50 LAZY_INSTANCE_INITIALIZER; |
| 51 |
42 // Blacklisted devices are identified by a characteristic prefix of the name. | 52 // Blacklisted devices are identified by a characteristic prefix of the name. |
43 // This prefix is used case-insensitively. This list must be kept in sync with | 53 // This prefix is used case-insensitively. This list must be kept in sync with |
44 // |BlacklistedCameraNames|. | 54 // |BlacklistedCameraNames|. |
45 static const char* const kBlacklistedCameraNames[] = { | 55 static const char* const kBlacklistedCameraNames[] = { |
46 // Name of a fake DirectShow filter on computers with GTalk installed. | 56 // Name of a fake DirectShow filter on computers with GTalk installed. |
47 "Google Camera Adapter", | 57 "Google Camera Adapter", |
48 // The following two software WebCams cause crashes. | 58 // The following two software WebCams cause crashes. |
49 "IP Camera [JPEG/MJPEG]", | 59 "IP Camera [JPEG/MJPEG]", |
50 "CyberLink Webcam Splitter", | 60 "CyberLink Webcam Splitter", |
51 }; | 61 }; |
52 | 62 |
| 63 static void EnsureMediaFoundationInit() { |
| 64 g_mf_initialize.Get(); |
| 65 } |
| 66 |
53 static bool LoadMediaFoundationDlls() { | 67 static bool LoadMediaFoundationDlls() { |
54 static const wchar_t* const kMfDLLs[] = { | 68 static const wchar_t* const kMfDLLs[] = { |
55 L"%WINDIR%\\system32\\mf.dll", | 69 L"%WINDIR%\\system32\\mf.dll", |
56 L"%WINDIR%\\system32\\mfplat.dll", | 70 L"%WINDIR%\\system32\\mfplat.dll", |
57 L"%WINDIR%\\system32\\mfreadwrite.dll", | 71 L"%WINDIR%\\system32\\mfreadwrite.dll", |
58 }; | 72 }; |
59 | 73 |
60 for (int i = 0; i < arraysize(kMfDLLs); ++i) { | 74 for (int i = 0; i < arraysize(kMfDLLs); ++i) { |
61 wchar_t path[MAX_PATH] = {0}; | 75 wchar_t path[MAX_PATH] = {0}; |
62 ExpandEnvironmentStringsW(kMfDLLs[i], path, arraysize(path)); | 76 ExpandEnvironmentStringsW(kMfDLLs[i], path, arraysize(path)); |
63 if (!LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) | 77 if (!LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) |
64 return false; | 78 return false; |
65 } | 79 } |
66 return true; | 80 return true; |
67 } | 81 } |
68 | 82 |
69 static bool PrepareVideoCaptureAttributesMediaFoundation( | 83 static bool PrepareVideoCaptureAttributesMediaFoundation( |
70 IMFAttributes** attributes, | 84 IMFAttributes** attributes, |
71 int count) { | 85 int count) { |
72 InitializeMediaFoundation(); | 86 EnsureMediaFoundationInit(); |
73 | 87 |
74 if (FAILED(MFCreateAttributes(attributes, count))) | 88 if (FAILED(MFCreateAttributes(attributes, count))) |
75 return false; | 89 return false; |
76 | 90 |
77 return SUCCEEDED((*attributes)->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, | 91 return SUCCEEDED((*attributes)->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, |
78 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID)); | 92 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID)); |
79 } | 93 } |
80 | 94 |
81 static bool CreateVideoCaptureDeviceMediaFoundation(const char* sym_link, | 95 static bool CreateVideoCaptureDeviceMediaFoundation(const char* sym_link, |
82 IMFMediaSource** source) { | 96 IMFMediaSource** source) { |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 } | 433 } |
420 | 434 |
421 // static | 435 // static |
422 VideoCaptureDeviceFactory* | 436 VideoCaptureDeviceFactory* |
423 VideoCaptureDeviceFactory::CreateVideoCaptureDeviceFactory( | 437 VideoCaptureDeviceFactory::CreateVideoCaptureDeviceFactory( |
424 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 438 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
425 return new VideoCaptureDeviceFactoryWin(); | 439 return new VideoCaptureDeviceFactoryWin(); |
426 } | 440 } |
427 | 441 |
428 } // namespace media | 442 } // namespace media |
OLD | NEW |