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/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 Loading... |
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 std::string GetDeviceModelId(const std::string& device_id) { |
126 DCHECK(device_names); | 130 const size_t vid_prefix_size = sizeof(kVidPrefix) - 1; |
127 DVLOG(1) << " GetDeviceNamesDirectShow"; | 131 const size_t pid_prefix_size = sizeof(kPidPrefix) - 1; |
| 132 const size_t vid_location = device_id.find(kVidPrefix); |
| 133 if (vid_location == std::string::npos || |
| 134 vid_location + vid_prefix_size + kVidPidSize > device_id.size()) { |
| 135 return std::string(); |
| 136 } |
| 137 const size_t pid_location = device_id.find(kPidPrefix); |
| 138 if (pid_location == std::string::npos || |
| 139 pid_location + pid_prefix_size + kVidPidSize > device_id.size()) { |
| 140 return std::string(); |
| 141 } |
| 142 const std::string id_vendor = |
| 143 device_id.substr(vid_location + vid_prefix_size, kVidPidSize); |
| 144 const std::string id_product = |
| 145 device_id.substr(pid_location + pid_prefix_size, kVidPidSize); |
| 146 return id_vendor + ":" + id_product; |
| 147 } |
| 148 |
| 149 static void GetDeviceDescriptorsDirectShow(Descriptors* device_descriptors) { |
| 150 DCHECK(device_descriptors); |
| 151 DVLOG(1) << __FUNCTION__; |
128 | 152 |
129 ScopedComPtr<ICreateDevEnum> dev_enum; | 153 ScopedComPtr<ICreateDevEnum> dev_enum; |
130 HRESULT hr = | 154 HRESULT hr = |
131 dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC); | 155 dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC); |
132 if (FAILED(hr)) | 156 if (FAILED(hr)) |
133 return; | 157 return; |
134 | 158 |
135 ScopedComPtr<IEnumMoniker> enum_moniker; | 159 ScopedComPtr<IEnumMoniker> enum_moniker; |
136 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, | 160 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, |
137 enum_moniker.Receive(), 0); | 161 enum_moniker.Receive(), 0); |
(...skipping 26 matching lines...) Expand all Loading... |
164 | 188 |
165 name.Reset(); | 189 name.Reset(); |
166 hr = prop_bag->Read(L"DevicePath", name.Receive(), 0); | 190 hr = prop_bag->Read(L"DevicePath", name.Receive(), 0); |
167 std::string id; | 191 std::string id; |
168 if (FAILED(hr) || name.type() != VT_BSTR) { | 192 if (FAILED(hr) || name.type() != VT_BSTR) { |
169 id = device_name; | 193 id = device_name; |
170 } else { | 194 } else { |
171 DCHECK_EQ(name.type(), VT_BSTR); | 195 DCHECK_EQ(name.type(), VT_BSTR); |
172 id = base::SysWideToUTF8(V_BSTR(name.ptr())); | 196 id = base::SysWideToUTF8(V_BSTR(name.ptr())); |
173 } | 197 } |
174 device_names->push_back(Name(device_name, id, Name::DIRECT_SHOW)); | 198 |
| 199 const std::string model_id = GetDeviceModelId(id); |
| 200 |
| 201 device_descriptors->emplace_back(device_name, id, model_id, |
| 202 VideoCaptureApi::WIN_DIRECT_SHOW); |
175 } | 203 } |
176 } | 204 } |
177 | 205 |
178 static void GetDeviceNamesMediaFoundation(Names* device_names) { | 206 static void GetDeviceDescriptorsMediaFoundation( |
179 DVLOG(1) << " GetDeviceNamesMediaFoundation"; | 207 Descriptors* device_descriptors) { |
| 208 DVLOG(1) << " GetDeviceDescriptorsMediaFoundation"; |
180 ScopedCoMem<IMFActivate*> devices; | 209 ScopedCoMem<IMFActivate*> devices; |
181 UINT32 count; | 210 UINT32 count; |
182 if (!EnumerateVideoDevicesMediaFoundation(&devices, &count)) | 211 if (!EnumerateVideoDevicesMediaFoundation(&devices, &count)) |
183 return; | 212 return; |
184 | 213 |
185 for (UINT32 i = 0; i < count; ++i) { | 214 for (UINT32 i = 0; i < count; ++i) { |
186 ScopedCoMem<wchar_t> name; | 215 ScopedCoMem<wchar_t> name; |
187 UINT32 name_size; | 216 UINT32 name_size; |
188 HRESULT hr = devices[i]->GetAllocatedString( | 217 HRESULT hr = devices[i]->GetAllocatedString( |
189 MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &name, &name_size); | 218 MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &name, &name_size); |
190 if (SUCCEEDED(hr)) { | 219 if (SUCCEEDED(hr)) { |
191 ScopedCoMem<wchar_t> id; | 220 ScopedCoMem<wchar_t> id; |
192 UINT32 id_size; | 221 UINT32 id_size; |
193 hr = devices[i]->GetAllocatedString( | 222 hr = devices[i]->GetAllocatedString( |
194 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &id, | 223 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &id, |
195 &id_size); | 224 &id_size); |
196 if (SUCCEEDED(hr)) { | 225 if (SUCCEEDED(hr)) { |
197 device_names->push_back( | 226 const std::string device_id = |
198 Name(base::SysWideToUTF8(std::wstring(name, name_size)), | 227 base::SysWideToUTF8(std::wstring(id, id_size)); |
199 base::SysWideToUTF8(std::wstring(id, id_size)), | 228 const std::string model_id = GetDeviceModelId(device_id); |
200 Name::MEDIA_FOUNDATION)); | 229 device_descriptors->emplace_back( |
| 230 base::SysWideToUTF8(std::wstring(name, name_size)), device_id, |
| 231 model_id, VideoCaptureApi::WIN_MEDIA_FOUNDATION); |
201 } | 232 } |
202 } | 233 } |
203 DLOG_IF(ERROR, FAILED(hr)) << "GetAllocatedString failed: " | 234 DLOG_IF(ERROR, FAILED(hr)) << "GetAllocatedString failed: " |
204 << logging::SystemErrorCodeToString(hr); | 235 << logging::SystemErrorCodeToString(hr); |
205 devices[i]->Release(); | 236 devices[i]->Release(); |
206 } | 237 } |
207 } | 238 } |
208 | 239 |
209 static void GetDeviceSupportedFormatsDirectShow(const Name& device, | 240 static void GetDeviceSupportedFormatsDirectShow(const Descriptor& descriptor, |
210 VideoCaptureFormats* formats) { | 241 VideoCaptureFormats* formats) { |
211 DVLOG(1) << "GetDeviceSupportedFormatsDirectShow for " << device.name(); | 242 DVLOG(1) << "GetDeviceSupportedFormatsDirectShow for " |
| 243 << descriptor.display_name; |
212 ScopedComPtr<ICreateDevEnum> dev_enum; | 244 ScopedComPtr<ICreateDevEnum> dev_enum; |
213 HRESULT hr = | 245 HRESULT hr = |
214 dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC); | 246 dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC); |
215 if (FAILED(hr)) | 247 if (FAILED(hr)) |
216 return; | 248 return; |
217 | 249 |
218 ScopedComPtr<IEnumMoniker> enum_moniker; | 250 ScopedComPtr<IEnumMoniker> enum_moniker; |
219 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, | 251 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, |
220 enum_moniker.Receive(), 0); | 252 enum_moniker.Receive(), 0); |
221 // CreateClassEnumerator returns S_FALSE on some Windows OS when no camera | 253 // CreateClassEnumerator returns S_FALSE on some Windows OS when no camera |
222 // exists. Therefore the FAILED macro can't be used. | 254 // exists. Therefore the FAILED macro can't be used. |
223 if (hr != S_OK) | 255 if (hr != S_OK) |
224 return; | 256 return; |
225 | 257 |
226 // Walk the capture devices. No need to check for device presence again since | 258 // 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 | 259 // that is anyway needed in GetDeviceFilter(). "google camera adapter" and old |
228 // VFW devices are already skipped previously in GetDeviceNames() enumeration. | 260 // VFW devices are already skipped previously in GetDeviceNames() enumeration. |
229 base::win::ScopedComPtr<IBaseFilter> capture_filter; | 261 base::win::ScopedComPtr<IBaseFilter> capture_filter; |
230 hr = VideoCaptureDeviceWin::GetDeviceFilter(device.capabilities_id(), | 262 hr = VideoCaptureDeviceWin::GetDeviceFilter(descriptor.device_id, |
231 capture_filter.Receive()); | 263 capture_filter.Receive()); |
232 if (!capture_filter.get()) { | 264 if (!capture_filter.get()) { |
233 DLOG(ERROR) << "Failed to create capture filter: " | 265 DLOG(ERROR) << "Failed to create capture filter: " |
234 << logging::SystemErrorCodeToString(hr); | 266 << logging::SystemErrorCodeToString(hr); |
235 return; | 267 return; |
236 } | 268 } |
237 | 269 |
238 base::win::ScopedComPtr<IPin> output_capture_pin( | 270 base::win::ScopedComPtr<IPin> output_capture_pin( |
239 VideoCaptureDeviceWin::GetPin(capture_filter.get(), PINDIR_OUTPUT, | 271 VideoCaptureDeviceWin::GetPin(capture_filter.get(), PINDIR_OUTPUT, |
240 PIN_CATEGORY_CAPTURE, GUID_NULL)); | 272 PIN_CATEGORY_CAPTURE, GUID_NULL)); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 continue; | 313 continue; |
282 VIDEOINFOHEADER* h = | 314 VIDEOINFOHEADER* h = |
283 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); | 315 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); |
284 format.frame_size.SetSize(h->bmiHeader.biWidth, h->bmiHeader.biHeight); | 316 format.frame_size.SetSize(h->bmiHeader.biWidth, h->bmiHeader.biHeight); |
285 // Trust the frame rate from the VIDEOINFOHEADER. | 317 // Trust the frame rate from the VIDEOINFOHEADER. |
286 format.frame_rate = | 318 format.frame_rate = |
287 (h->AvgTimePerFrame > 0) | 319 (h->AvgTimePerFrame > 0) |
288 ? kSecondsToReferenceTime / static_cast<float>(h->AvgTimePerFrame) | 320 ? kSecondsToReferenceTime / static_cast<float>(h->AvgTimePerFrame) |
289 : 0.0f; | 321 : 0.0f; |
290 formats->push_back(format); | 322 formats->push_back(format); |
291 DVLOG(1) << device.name() << " " << VideoCaptureFormat::ToString(format); | 323 DVLOG(1) << descriptor.display_name << " " |
| 324 << VideoCaptureFormat::ToString(format); |
292 } | 325 } |
293 } | 326 } |
294 } | 327 } |
295 | 328 |
296 static void GetDeviceSupportedFormatsMediaFoundation( | 329 static void GetDeviceSupportedFormatsMediaFoundation( |
297 const Name& device, | 330 const Descriptor& descriptor, |
298 VideoCaptureFormats* formats) { | 331 VideoCaptureFormats* formats) { |
299 DVLOG(1) << "GetDeviceSupportedFormatsMediaFoundation for " << device.name(); | 332 DVLOG(1) << "GetDeviceSupportedFormatsMediaFoundation for " |
| 333 << descriptor.display_name; |
300 ScopedComPtr<IMFMediaSource> source; | 334 ScopedComPtr<IMFMediaSource> source; |
301 if (!CreateVideoCaptureDeviceMediaFoundation(device.id().c_str(), | 335 if (!CreateVideoCaptureDeviceMediaFoundation(descriptor.device_id.c_str(), |
302 source.Receive())) { | 336 source.Receive())) { |
303 return; | 337 return; |
304 } | 338 } |
305 | 339 |
306 base::win::ScopedComPtr<IMFSourceReader> reader; | 340 base::win::ScopedComPtr<IMFSourceReader> reader; |
307 HRESULT hr = | 341 HRESULT hr = |
308 MFCreateSourceReaderFromMediaSource(source.get(), NULL, reader.Receive()); | 342 MFCreateSourceReaderFromMediaSource(source.get(), NULL, reader.Receive()); |
309 if (FAILED(hr)) { | 343 if (FAILED(hr)) { |
310 DLOG(ERROR) << "MFCreateSourceReaderFromMediaSource failed: " | 344 DLOG(ERROR) << "MFCreateSourceReaderFromMediaSource failed: " |
311 << logging::SystemErrorCodeToString(hr); | 345 << logging::SystemErrorCodeToString(hr); |
(...skipping 30 matching lines...) Expand all Loading... |
342 if (FAILED(hr)) { | 376 if (FAILED(hr)) { |
343 DLOG(ERROR) << "GetGUID failed: " << logging::SystemErrorCodeToString(hr); | 377 DLOG(ERROR) << "GetGUID failed: " << logging::SystemErrorCodeToString(hr); |
344 return; | 378 return; |
345 } | 379 } |
346 VideoCaptureDeviceMFWin::FormatFromGuid(type_guid, | 380 VideoCaptureDeviceMFWin::FormatFromGuid(type_guid, |
347 &capture_format.pixel_format); | 381 &capture_format.pixel_format); |
348 type.Release(); | 382 type.Release(); |
349 formats->push_back(capture_format); | 383 formats->push_back(capture_format); |
350 ++stream_index; | 384 ++stream_index; |
351 | 385 |
352 DVLOG(1) << device.name() << " " | 386 DVLOG(1) << descriptor.display_name << " " |
353 << VideoCaptureFormat::ToString(capture_format); | 387 << VideoCaptureFormat::ToString(capture_format); |
354 } | 388 } |
355 } | 389 } |
356 | 390 |
357 // Returns true iff the current platform supports the Media Foundation API | 391 // 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 | 392 // 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, | 393 // 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 | 394 // we've seen that the required DLLs are not available in some Win7 |
361 // distributions such as Windows 7 N and Windows 7 KN. | 395 // distributions such as Windows 7 N and Windows 7 KN. |
362 // static | 396 // static |
363 bool VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation() { | 397 bool VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation() { |
364 // Even though the DLLs might be available on Vista, we get crashes | 398 // Even though the DLLs might be available on Vista, we get crashes |
365 // when running our tests on the build bots. | 399 // when running our tests on the build bots. |
366 if (base::win::GetVersion() < base::win::VERSION_WIN7) | 400 if (base::win::GetVersion() < base::win::VERSION_WIN7) |
367 return false; | 401 return false; |
368 | 402 |
369 static bool g_dlls_available = LoadMediaFoundationDlls(); | 403 static bool g_dlls_available = LoadMediaFoundationDlls(); |
370 return g_dlls_available; | 404 return g_dlls_available; |
371 } | 405 } |
372 | 406 |
373 VideoCaptureDeviceFactoryWin::VideoCaptureDeviceFactoryWin() | 407 VideoCaptureDeviceFactoryWin::VideoCaptureDeviceFactoryWin() |
374 : use_media_foundation_(base::win::GetVersion() >= | 408 : use_media_foundation_(base::win::GetVersion() >= |
375 base::win::VERSION_WIN7 && | 409 base::win::VERSION_WIN7 && |
376 base::CommandLine::ForCurrentProcess()->HasSwitch( | 410 base::CommandLine::ForCurrentProcess()->HasSwitch( |
377 switches::kForceMediaFoundationVideoCapture)) {} | 411 switches::kForceMediaFoundationVideoCapture)) {} |
378 | 412 |
379 std::unique_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryWin::Create( | 413 std::unique_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryWin::CreateDevice( |
380 const Name& device_name) { | 414 const Descriptor& device_descriptor) { |
381 DCHECK(thread_checker_.CalledOnValidThread()); | 415 DCHECK(thread_checker_.CalledOnValidThread()); |
382 std::unique_ptr<VideoCaptureDevice> device; | 416 std::unique_ptr<VideoCaptureDevice> device; |
383 if (device_name.capture_api_type() == Name::MEDIA_FOUNDATION) { | 417 if (device_descriptor.capture_api == VideoCaptureApi::WIN_MEDIA_FOUNDATION) { |
384 DCHECK(PlatformSupportsMediaFoundation()); | 418 DCHECK(PlatformSupportsMediaFoundation()); |
385 device.reset(new VideoCaptureDeviceMFWin(device_name)); | 419 device.reset(new VideoCaptureDeviceMFWin(device_descriptor)); |
386 DVLOG(1) << " MediaFoundation Device: " << device_name.name(); | 420 DVLOG(1) << " MediaFoundation Device: " << device_descriptor.display_name; |
387 ScopedComPtr<IMFMediaSource> source; | 421 ScopedComPtr<IMFMediaSource> source; |
388 if (!CreateVideoCaptureDeviceMediaFoundation(device_name.id().c_str(), | 422 if (!CreateVideoCaptureDeviceMediaFoundation( |
389 source.Receive())) { | 423 device_descriptor.device_id.c_str(), source.Receive())) { |
390 return std::unique_ptr<VideoCaptureDevice>(); | 424 return std::unique_ptr<VideoCaptureDevice>(); |
391 } | 425 } |
392 if (!static_cast<VideoCaptureDeviceMFWin*>(device.get())->Init(source)) | 426 if (!static_cast<VideoCaptureDeviceMFWin*>(device.get())->Init(source)) |
393 device.reset(); | 427 device.reset(); |
394 } else { | 428 } else if (device_descriptor.capture_api == |
395 DCHECK(device_name.capture_api_type() == Name::DIRECT_SHOW); | 429 VideoCaptureApi::WIN_DIRECT_SHOW) { |
396 device.reset(new VideoCaptureDeviceWin(device_name)); | 430 device.reset(new VideoCaptureDeviceWin(device_descriptor)); |
397 DVLOG(1) << " DirectShow Device: " << device_name.name(); | 431 DVLOG(1) << " DirectShow Device: " << device_descriptor.display_name; |
398 if (!static_cast<VideoCaptureDeviceWin*>(device.get())->Init()) | 432 if (!static_cast<VideoCaptureDeviceWin*>(device.get())->Init()) |
399 device.reset(); | 433 device.reset(); |
| 434 } else { |
| 435 NOTREACHED(); |
400 } | 436 } |
401 return device; | 437 return device; |
402 } | 438 } |
403 | 439 |
404 void VideoCaptureDeviceFactoryWin::GetDeviceNames(Names* device_names) { | 440 void VideoCaptureDeviceFactoryWin::GetDeviceDescriptors( |
| 441 VideoCaptureDeviceDescriptors* device_descriptors) { |
405 DCHECK(thread_checker_.CalledOnValidThread()); | 442 DCHECK(thread_checker_.CalledOnValidThread()); |
406 if (use_media_foundation_) | 443 if (use_media_foundation_) |
407 GetDeviceNamesMediaFoundation(device_names); | 444 GetDeviceDescriptorsMediaFoundation(device_descriptors); |
408 else | 445 else |
409 GetDeviceNamesDirectShow(device_names); | 446 GetDeviceDescriptorsDirectShow(device_descriptors); |
410 } | 447 } |
411 | 448 |
412 void VideoCaptureDeviceFactoryWin::GetDeviceSupportedFormats( | 449 void VideoCaptureDeviceFactoryWin::GetSupportedFormats( |
413 const Name& device, | 450 const Descriptor& device, |
414 VideoCaptureFormats* formats) { | 451 VideoCaptureFormats* formats) { |
415 DCHECK(thread_checker_.CalledOnValidThread()); | 452 DCHECK(thread_checker_.CalledOnValidThread()); |
416 if (use_media_foundation_) | 453 if (use_media_foundation_) |
417 GetDeviceSupportedFormatsMediaFoundation(device, formats); | 454 GetDeviceSupportedFormatsMediaFoundation(device, formats); |
418 else | 455 else |
419 GetDeviceSupportedFormatsDirectShow(device, formats); | 456 GetDeviceSupportedFormatsDirectShow(device, formats); |
420 } | 457 } |
421 | 458 |
422 // static | 459 // static |
423 VideoCaptureDeviceFactory* | 460 VideoCaptureDeviceFactory* |
424 VideoCaptureDeviceFactory::CreateVideoCaptureDeviceFactory( | 461 VideoCaptureDeviceFactory::CreateVideoCaptureDeviceFactory( |
425 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 462 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
426 return new VideoCaptureDeviceFactoryWin(); | 463 return new VideoCaptureDeviceFactoryWin(); |
427 } | 464 } |
428 | 465 |
429 } // namespace media | 466 } // namespace media |
OLD | NEW |