| 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 |