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" |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
91 static void GetDeviceNamesDirectShow(VideoCaptureDevice::Names* device_names) { | 91 static void GetDeviceNamesDirectShow(VideoCaptureDevice::Names* device_names) { |
92 DCHECK(device_names); | 92 DCHECK(device_names); |
93 DVLOG(1) << " GetDeviceNamesDirectShow"; | 93 DVLOG(1) << " GetDeviceNamesDirectShow"; |
94 | 94 |
95 ScopedComPtr<ICreateDevEnum> dev_enum; | 95 ScopedComPtr<ICreateDevEnum> dev_enum; |
96 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, | 96 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, |
97 CLSCTX_INPROC); | 97 CLSCTX_INPROC); |
98 if (FAILED(hr)) | 98 if (FAILED(hr)) |
99 return; | 99 return; |
100 | 100 |
101 ScopedComPtr<IEnumMoniker> enum_moniker; | 101 static const struct{ |
102 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, | 102 CLSID class_id; |
103 enum_moniker.Receive(), 0); | 103 VideoCaptureDevice::Name::CaptureApiType capture_api_type; |
104 // CreateClassEnumerator returns S_FALSE on some Windows OS | 104 } kDirectShowFilterClasses[] = { |
105 // when no camera exist. Therefore the FAILED macro can't be used. | 105 { CLSID_VideoInputDeviceCategory, VideoCaptureDevice::Name::DIRECT_SHOW }, |
106 if (hr != S_OK) | 106 { AM_KSCATEGORY_CROSSBAR, VideoCaptureDevice::Name::DIRECT_SHOW_WDM} |
107 return; | 107 }; |
108 | |
108 | 109 |
109 device_names->clear(); | 110 device_names->clear(); |
111 for (int class_index = 0; class_index < arraysize(kDirectShowFilterClasses); | |
112 ++class_index) { | |
113 ScopedComPtr<IEnumMoniker> enum_moniker; | |
114 hr = dev_enum->CreateClassEnumerator( | |
115 kDirectShowFilterClasses[class_index].class_id, | |
116 enum_moniker.Receive(), | |
117 0); | |
118 // CreateClassEnumerator returns S_FALSE on some Windows OS | |
119 // when no camera exist. Therefore the FAILED macro can't be used. | |
120 if (hr != S_OK) | |
121 continue; | |
110 | 122 |
111 // Name of a fake DirectShow filter that exist on computers with | 123 // Name of a fake DirectShow filter that exist on computers with |
112 // GTalk installed. | 124 // GTalk installed. |
113 static const char kGoogleCameraAdapter[] = "google camera adapter"; | 125 static const char kGoogleCameraAdapter[] = "google camera adapter"; |
114 | 126 |
115 // Enumerate all video capture devices. | 127 // Enumerate all video capture devices. |
116 ScopedComPtr<IMoniker> moniker; | 128 ScopedComPtr<IMoniker> moniker; |
117 int index = 0; | 129 int index = 0; |
118 while (enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK) { | 130 while (enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK) { |
119 ScopedComPtr<IPropertyBag> prop_bag; | 131 ScopedComPtr<IPropertyBag> prop_bag; |
120 hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid()); | 132 hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, |
121 if (FAILED(hr)) { | 133 prop_bag.ReceiveVoid()); |
134 if (FAILED(hr)) { | |
135 moniker.Release(); | |
136 continue; | |
137 } | |
138 | |
139 // Find the description or friendly name. | |
140 ScopedVariant name; | |
141 hr = prop_bag->Read(L"Description", name.Receive(), 0); | |
142 if (FAILED(hr)) | |
143 hr = prop_bag->Read(L"FriendlyName", name.Receive(), 0); | |
144 | |
145 if (SUCCEEDED(hr) && name.type() == VT_BSTR) { | |
146 // Ignore all VFW drivers and the special Google Camera Adapter. | |
147 // Google Camera Adapter is not a real DirectShow camera device. | |
148 // VFW are very old Video for Windows drivers that can not be used. | |
149 const wchar_t* str_ptr = V_BSTR(&name); | |
150 const int name_length = arraysize(kGoogleCameraAdapter) - 1; | |
151 | |
152 if ((wcsstr(str_ptr, L"(VFW)") == NULL) && | |
153 lstrlenW(str_ptr) < name_length || | |
154 (!(LowerCaseEqualsASCII(str_ptr, str_ptr + name_length, | |
155 kGoogleCameraAdapter)))) { | |
156 std::string id; | |
157 std::string device_name(base::SysWideToUTF8(str_ptr)); | |
158 name.Reset(); | |
159 hr = prop_bag->Read(L"DevicePath", name.Receive(), 0); | |
160 if (FAILED(hr) || name.type() != VT_BSTR) { | |
161 id = device_name; | |
162 } else { | |
163 DCHECK_EQ(name.type(), VT_BSTR); | |
164 id = base::SysWideToUTF8(V_BSTR(&name)); | |
165 } | |
166 device_names->push_back(VideoCaptureDevice::Name(device_name, id, | |
167 kDirectShowFilterClasses[class_index].capture_api_type)); | |
168 } | |
169 } | |
122 moniker.Release(); | 170 moniker.Release(); |
123 continue; | |
124 } | 171 } |
125 | |
126 // Find the description or friendly name. | |
127 ScopedVariant name; | |
128 hr = prop_bag->Read(L"Description", name.Receive(), 0); | |
129 if (FAILED(hr)) | |
130 hr = prop_bag->Read(L"FriendlyName", name.Receive(), 0); | |
131 | |
132 if (SUCCEEDED(hr) && name.type() == VT_BSTR) { | |
133 // Ignore all VFW drivers and the special Google Camera Adapter. | |
134 // Google Camera Adapter is not a real DirectShow camera device. | |
135 // VFW are very old Video for Windows drivers that can not be used. | |
136 const wchar_t* str_ptr = V_BSTR(&name); | |
137 const int name_length = arraysize(kGoogleCameraAdapter) - 1; | |
138 | |
139 if ((wcsstr(str_ptr, L"(VFW)") == NULL) && | |
140 lstrlenW(str_ptr) < name_length || | |
141 (!(LowerCaseEqualsASCII(str_ptr, str_ptr + name_length, | |
142 kGoogleCameraAdapter)))) { | |
143 std::string id; | |
144 std::string device_name(base::SysWideToUTF8(str_ptr)); | |
145 name.Reset(); | |
146 hr = prop_bag->Read(L"DevicePath", name.Receive(), 0); | |
147 if (FAILED(hr) || name.type() != VT_BSTR) { | |
148 id = device_name; | |
149 } else { | |
150 DCHECK_EQ(name.type(), VT_BSTR); | |
151 id = base::SysWideToUTF8(V_BSTR(&name)); | |
152 } | |
153 | |
154 device_names->push_back(VideoCaptureDevice::Name(device_name, id, | |
155 VideoCaptureDevice::Name::DIRECT_SHOW)); | |
156 } | |
157 } | |
158 moniker.Release(); | |
159 } | 172 } |
160 } | 173 } |
161 | 174 |
162 static void GetDeviceNamesMediaFoundation( | 175 static void GetDeviceNamesMediaFoundation( |
163 VideoCaptureDevice::Names* device_names) { | 176 VideoCaptureDevice::Names* device_names) { |
164 DVLOG(1) << " GetDeviceNamesMediaFoundation"; | 177 DVLOG(1) << " GetDeviceNamesMediaFoundation"; |
165 ScopedCoMem<IMFActivate*> devices; | 178 ScopedCoMem<IMFActivate*> devices; |
166 UINT32 count; | 179 UINT32 count; |
167 if (!EnumerateVideoDevicesMediaFoundation(&devices, &count)) | 180 if (!EnumerateVideoDevicesMediaFoundation(&devices, &count)) |
168 return; | 181 return; |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
380 device.reset(new VideoCaptureDeviceMFWin(device_name)); | 393 device.reset(new VideoCaptureDeviceMFWin(device_name)); |
381 DVLOG(1) << " MediaFoundation Device: " << device_name.name(); | 394 DVLOG(1) << " MediaFoundation Device: " << device_name.name(); |
382 ScopedComPtr<IMFMediaSource> source; | 395 ScopedComPtr<IMFMediaSource> source; |
383 if (!CreateVideoCaptureDeviceMediaFoundation(device_name.id().c_str(), | 396 if (!CreateVideoCaptureDeviceMediaFoundation(device_name.id().c_str(), |
384 source.Receive())) { | 397 source.Receive())) { |
385 return scoped_ptr<VideoCaptureDevice>(); | 398 return scoped_ptr<VideoCaptureDevice>(); |
386 } | 399 } |
387 if (!static_cast<VideoCaptureDeviceMFWin*>(device.get())->Init(source)) | 400 if (!static_cast<VideoCaptureDeviceMFWin*>(device.get())->Init(source)) |
388 device.reset(); | 401 device.reset(); |
389 } else { | 402 } else { |
390 DCHECK_EQ(device_name.capture_api_type(), | 403 DCHECK(device_name.capture_api_type() == |
391 VideoCaptureDevice::Name::DIRECT_SHOW); | 404 VideoCaptureDevice::Name::DIRECT_SHOW || |
perkj_chrome
2014/08/28 09:47:02
nit indentation
| |
405 device_name.capture_api_type() == | |
406 VideoCaptureDevice::Name::DIRECT_SHOW_WDM); | |
392 device.reset(new VideoCaptureDeviceWin(device_name)); | 407 device.reset(new VideoCaptureDeviceWin(device_name)); |
393 DVLOG(1) << " DirectShow Device: " << device_name.name(); | 408 DVLOG(1) << " DirectShow Device: " << device_name.name(); |
394 if (!static_cast<VideoCaptureDeviceWin*>(device.get())->Init()) | 409 if (!static_cast<VideoCaptureDeviceWin*>(device.get())->Init()) |
395 device.reset(); | 410 device.reset(); |
396 } | 411 } |
397 return device.Pass(); | 412 return device.Pass(); |
398 } | 413 } |
399 | 414 |
400 void VideoCaptureDeviceFactoryWin::GetDeviceNames( | 415 void VideoCaptureDeviceFactoryWin::GetDeviceNames( |
401 VideoCaptureDevice::Names* device_names) { | 416 VideoCaptureDevice::Names* device_names) { |
402 DCHECK(thread_checker_.CalledOnValidThread()); | 417 DCHECK(thread_checker_.CalledOnValidThread()); |
403 if (use_media_foundation_) | 418 if (use_media_foundation_) |
404 GetDeviceNamesMediaFoundation(device_names); | 419 GetDeviceNamesMediaFoundation(device_names); |
405 else | 420 else |
406 GetDeviceNamesDirectShow(device_names); | 421 GetDeviceNamesDirectShow(device_names); |
407 } | 422 } |
408 | 423 |
409 void VideoCaptureDeviceFactoryWin::GetDeviceSupportedFormats( | 424 void VideoCaptureDeviceFactoryWin::GetDeviceSupportedFormats( |
410 const VideoCaptureDevice::Name& device, | 425 const VideoCaptureDevice::Name& device, |
411 VideoCaptureFormats* formats) { | 426 VideoCaptureFormats* formats) { |
412 DCHECK(thread_checker_.CalledOnValidThread()); | 427 DCHECK(thread_checker_.CalledOnValidThread()); |
413 if (use_media_foundation_) | 428 if (use_media_foundation_) |
414 GetDeviceSupportedFormatsMediaFoundation(device, formats); | 429 GetDeviceSupportedFormatsMediaFoundation(device, formats); |
415 else | 430 else |
416 GetDeviceSupportedFormatsDirectShow(device, formats); | 431 GetDeviceSupportedFormatsDirectShow(device, formats); |
417 } | 432 } |
418 | 433 |
419 } // namespace media | 434 } // namespace media |
OLD | NEW |