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" | |
12 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
13 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
14 #include "base/strings/sys_string_conversions.h" | 13 #include "base/strings/sys_string_conversions.h" |
15 #include "base/win/metro.h" | 14 #include "base/win/metro.h" |
16 #include "base/win/scoped_co_mem.h" | 15 #include "base/win/scoped_co_mem.h" |
17 #include "base/win/scoped_variant.h" | 16 #include "base/win/scoped_variant.h" |
18 #include "base/win/windows_version.h" | 17 #include "base/win/windows_version.h" |
19 #include "media/base/media_switches.h" | 18 #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 | |
52 // Blacklisted devices are identified by a characteristic prefix of the name. | 42 // Blacklisted devices are identified by a characteristic prefix of the name. |
53 // This prefix is used case-insensitively. This list must be kept in sync with | 43 // This prefix is used case-insensitively. This list must be kept in sync with |
54 // |BlacklistedCameraNames|. | 44 // |BlacklistedCameraNames|. |
55 static const char* const kBlacklistedCameraNames[] = { | 45 static const char* const kBlacklistedCameraNames[] = { |
56 // Name of a fake DirectShow filter on computers with GTalk installed. | 46 // Name of a fake DirectShow filter on computers with GTalk installed. |
57 "Google Camera Adapter", | 47 "Google Camera Adapter", |
58 // The following two software WebCams cause crashes. | 48 // The following two software WebCams cause crashes. |
59 "IP Camera [JPEG/MJPEG]", | 49 "IP Camera [JPEG/MJPEG]", |
60 "CyberLink Webcam Splitter", | 50 "CyberLink Webcam Splitter", |
61 }; | 51 }; |
62 | 52 |
63 static void EnsureMediaFoundationInit() { | |
64 g_mf_initialize.Get(); | |
65 } | |
66 | |
67 static bool LoadMediaFoundationDlls() { | 53 static bool LoadMediaFoundationDlls() { |
68 static const wchar_t* const kMfDLLs[] = { | 54 static const wchar_t* const kMfDLLs[] = { |
69 L"%WINDIR%\\system32\\mf.dll", | 55 L"%WINDIR%\\system32\\mf.dll", |
70 L"%WINDIR%\\system32\\mfplat.dll", | 56 L"%WINDIR%\\system32\\mfplat.dll", |
71 L"%WINDIR%\\system32\\mfreadwrite.dll", | 57 L"%WINDIR%\\system32\\mfreadwrite.dll", |
72 }; | 58 }; |
73 | 59 |
74 for (int i = 0; i < arraysize(kMfDLLs); ++i) { | 60 for (int i = 0; i < arraysize(kMfDLLs); ++i) { |
75 wchar_t path[MAX_PATH] = {0}; | 61 wchar_t path[MAX_PATH] = {0}; |
76 ExpandEnvironmentStringsW(kMfDLLs[i], path, arraysize(path)); | 62 ExpandEnvironmentStringsW(kMfDLLs[i], path, arraysize(path)); |
77 if (!LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) | 63 if (!LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) |
78 return false; | 64 return false; |
79 } | 65 } |
80 return true; | 66 return true; |
81 } | 67 } |
82 | 68 |
83 static bool PrepareVideoCaptureAttributesMediaFoundation( | 69 static bool PrepareVideoCaptureAttributesMediaFoundation( |
84 IMFAttributes** attributes, | 70 IMFAttributes** attributes, |
85 int count) { | 71 int count) { |
86 EnsureMediaFoundationInit(); | 72 InitializeMediaFoundation(); |
87 | 73 |
88 if (FAILED(MFCreateAttributes(attributes, count))) | 74 if (FAILED(MFCreateAttributes(attributes, count))) |
89 return false; | 75 return false; |
90 | 76 |
91 return SUCCEEDED((*attributes)->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, | 77 return SUCCEEDED((*attributes)->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, |
92 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID)); | 78 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID)); |
93 } | 79 } |
94 | 80 |
95 static bool CreateVideoCaptureDeviceMediaFoundation(const char* sym_link, | 81 static bool CreateVideoCaptureDeviceMediaFoundation(const char* sym_link, |
96 IMFMediaSource** source) { | 82 IMFMediaSource** source) { |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 } | 419 } |
434 | 420 |
435 // static | 421 // static |
436 VideoCaptureDeviceFactory* | 422 VideoCaptureDeviceFactory* |
437 VideoCaptureDeviceFactory::CreateVideoCaptureDeviceFactory( | 423 VideoCaptureDeviceFactory::CreateVideoCaptureDeviceFactory( |
438 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 424 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
439 return new VideoCaptureDeviceFactoryWin(); | 425 return new VideoCaptureDeviceFactoryWin(); |
440 } | 426 } |
441 | 427 |
442 } // namespace media | 428 } // namespace media |
OLD | NEW |