Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_win.h" | 5 #include "media/video/capture/win/video_capture_device_win.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <list> | 8 #include <list> |
| 9 | 9 |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 11 #include "base/strings/sys_string_conversions.h" | 11 #include "base/strings/sys_string_conversions.h" |
| 12 #include "base/win/scoped_variant.h" | 12 #include "base/win/scoped_variant.h" |
| 13 #include "media/video/capture/win/video_capture_device_mf_win.h" | 13 #include "media/video/capture/win/video_capture_device_mf_win.h" |
| 14 | 14 |
| 15 using base::win::ScopedComPtr; | 15 using base::win::ScopedComPtr; |
| 16 using base::win::ScopedVariant; | 16 using base::win::ScopedVariant; |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 enum DeviceDriverType { | |
| 21 kDirectShow, // DirectShow driver type | |
|
tommi (sloooow) - chröme
2013/06/24 11:09:27
Some style issues but since we're switching on the
mcasas
2013/06/25 07:04:36
Done.
| |
| 22 kMF, // Media Foundation type | |
| 23 }; | |
| 24 // Type of Device Driver (DirectShow, MediaFoundation) map and attribute. | |
| 25 typedef std::map<std::string, DeviceDriverType> DeviceDriverTypeMap; | |
| 26 DeviceDriverTypeMap device_driver_type_; | |
|
tommi (sloooow) - chröme
2013/06/24 11:09:27
sorry, no global variables that require constructi
mcasas
2013/06/25 07:04:36
All right, quote our conversation later on, it sho
| |
| 27 | |
|
tommi (sloooow) - chröme
2013/06/24 11:09:27
nit: one empty line
mcasas
2013/06/25 07:04:36
Done.
| |
| 28 | |
| 20 // Finds and creates a DirectShow Video Capture filter matching the device_name. | 29 // Finds and creates a DirectShow Video Capture filter matching the device_name. |
| 21 HRESULT GetDeviceFilter(const media::VideoCaptureDevice::Name& device_name, | 30 HRESULT GetDeviceFilter(const media::VideoCaptureDevice::Name& device_name, |
| 22 IBaseFilter** filter) { | 31 IBaseFilter** filter) { |
| 23 DCHECK(filter); | 32 DCHECK(filter); |
| 24 | 33 |
| 25 ScopedComPtr<ICreateDevEnum> dev_enum; | 34 ScopedComPtr<ICreateDevEnum> dev_enum; |
| 26 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, | 35 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, |
| 27 CLSCTX_INPROC); | 36 CLSCTX_INPROC); |
| 28 if (FAILED(hr)) | 37 if (FAILED(hr)) |
| 29 return hr; | 38 return hr; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 CoTaskMemFree(mt); | 151 CoTaskMemFree(mt); |
| 143 } | 152 } |
| 144 } | 153 } |
| 145 | 154 |
| 146 } // namespace | 155 } // namespace |
| 147 | 156 |
| 148 namespace media { | 157 namespace media { |
| 149 | 158 |
| 150 // static | 159 // static |
| 151 void VideoCaptureDevice::GetDeviceNames(Names* device_names) { | 160 void VideoCaptureDevice::GetDeviceNames(Names* device_names) { |
| 161 Names::iterator it; | |
| 162 | |
| 152 if (VideoCaptureDeviceMFWin::PlatformSupported()) { | 163 if (VideoCaptureDeviceMFWin::PlatformSupported()) { |
| 153 VideoCaptureDeviceMFWin::GetDeviceNames(device_names); | 164 VideoCaptureDeviceMFWin::GetDeviceNames(device_names); |
| 154 } else { | 165 it = device_names->begin(); |
| 155 VideoCaptureDeviceWin::GetDeviceNames(device_names); | 166 for (; it != device_names->end(); ++it) |
| 167 device_driver_type_[it->unique_id] = kMF; | |
|
tommi (sloooow) - chröme
2013/06/24 11:09:27
instead of the global map, what do you think about
mcasas
2013/06/25 07:04:36
I added the Capture Api type to VideoCaptureDevice
| |
| 168 } | |
| 169 // Retrieve the devices with DirectShow interface. They might (partially) | |
| 170 // overlap, so the list has to be consolidated. | |
| 171 Names temp_names; | |
| 172 VideoCaptureDeviceWin::GetDeviceNames(&temp_names); | |
| 173 | |
| 174 // We need to merge the DS devices into the MF device list, and next remove | |
| 175 // the duplicates, giving priority to the MF "versions". | |
| 176 device_names->merge(temp_names); | |
| 177 device_names->unique(); | |
| 178 | |
| 179 it = device_names->begin(); | |
| 180 // Walk the device_names list and mark those not found in device_driver_ | |
| 181 for (; it != device_names->end(); ++it) { | |
| 182 if (device_driver_type_.find(it->unique_id) == device_driver_type_.end()) | |
| 183 device_driver_type_[it->unique_id] = kDirectShow; | |
| 184 } | |
| 185 | |
| 186 it = device_names->begin(); | |
| 187 for (; it != device_names->end(); ++it) { | |
| 188 DLOG(WARNING) | |
| 189 << " Device " << it->unique_id << " is of type" | |
| 190 << ((device_driver_type_[it->unique_id] == kMF) ? "MediaFoundation" | |
| 191 : "DirectShow"); | |
| 156 } | 192 } |
| 157 } | 193 } |
| 158 | 194 |
| 159 // static | 195 // static |
| 160 VideoCaptureDevice* VideoCaptureDevice::Create(const Name& device_name) { | 196 VideoCaptureDevice* VideoCaptureDevice::Create(const Name& device_name) { |
| 161 VideoCaptureDevice* ret = NULL; | 197 VideoCaptureDevice* ret = NULL; |
| 162 if (VideoCaptureDeviceMFWin::PlatformSupported()) { | 198 if (device_driver_type_.find(device_name.unique_id) != |
| 199 device_driver_type_.end()) | |
| 200 return ret; | |
| 201 | |
| 202 if (device_driver_type_[device_name.unique_id] == kMF) { | |
| 163 scoped_ptr<VideoCaptureDeviceMFWin> device( | 203 scoped_ptr<VideoCaptureDeviceMFWin> device( |
| 164 new VideoCaptureDeviceMFWin(device_name)); | 204 new VideoCaptureDeviceMFWin(device_name)); |
| 165 if (device->Init()) | 205 if (device->Init()) |
| 166 ret = device.release(); | 206 ret = device.release(); |
| 167 } else { | 207 } else if (device_driver_type_[device_name.unique_id] == kDirectShow) { |
| 168 scoped_ptr<VideoCaptureDeviceWin> device( | 208 scoped_ptr<VideoCaptureDeviceWin> device( |
| 169 new VideoCaptureDeviceWin(device_name)); | 209 new VideoCaptureDeviceWin(device_name)); |
| 170 if (device->Init()) | 210 if (device->Init()) |
| 171 ret = device.release(); | 211 ret = device.release(); |
| 212 } else { | |
| 213 DLOG(ERROR) << "Couldn't recognize VideoCaptureDevice type!"; | |
| 172 } | 214 } |
| 173 | |
| 174 return ret; | 215 return ret; |
| 175 } | 216 } |
| 176 | 217 |
| 177 // static | 218 // static |
| 178 void VideoCaptureDeviceWin::GetDeviceNames(Names* device_names) { | 219 void VideoCaptureDeviceWin::GetDeviceNames(Names* device_names) { |
| 179 DCHECK(device_names); | 220 DCHECK(device_names); |
| 180 | 221 |
| 181 ScopedComPtr<ICreateDevEnum> dev_enum; | 222 ScopedComPtr<ICreateDevEnum> dev_enum; |
| 182 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, | 223 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, |
| 183 CLSCTX_INPROC); | 224 CLSCTX_INPROC); |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 568 capability.color = VideoCaptureCapability::kI420; | 609 capability.color = VideoCaptureCapability::kI420; |
| 569 } else if (media_type->subtype == MEDIASUBTYPE_IYUV) { | 610 } else if (media_type->subtype == MEDIASUBTYPE_IYUV) { |
| 570 // This is identical to kI420. | 611 // This is identical to kI420. |
| 571 capability.color = VideoCaptureCapability::kI420; | 612 capability.color = VideoCaptureCapability::kI420; |
| 572 } else if (media_type->subtype == MEDIASUBTYPE_RGB24) { | 613 } else if (media_type->subtype == MEDIASUBTYPE_RGB24) { |
| 573 capability.color = VideoCaptureCapability::kRGB24; | 614 capability.color = VideoCaptureCapability::kRGB24; |
| 574 } else if (media_type->subtype == MEDIASUBTYPE_YUY2) { | 615 } else if (media_type->subtype == MEDIASUBTYPE_YUY2) { |
| 575 capability.color = VideoCaptureCapability::kYUY2; | 616 capability.color = VideoCaptureCapability::kYUY2; |
| 576 } else if (media_type->subtype == MEDIASUBTYPE_MJPG) { | 617 } else if (media_type->subtype == MEDIASUBTYPE_MJPG) { |
| 577 capability.color = VideoCaptureCapability::kMJPEG; | 618 capability.color = VideoCaptureCapability::kMJPEG; |
| 619 } else if (media_type->subtype == MEDIASUBTYPE_UYVY) { | |
| 620 capability.color = VideoCaptureCapability::kUYVY; | |
| 621 } else if (media_type->subtype == MEDIASUBTYPE_ARGB32) { | |
| 622 capability.color = VideoCaptureCapability::kARGB; | |
| 578 } else { | 623 } else { |
| 579 WCHAR guid_str[128]; | 624 WCHAR guid_str[128]; |
| 580 StringFromGUID2(media_type->subtype, guid_str, arraysize(guid_str)); | 625 StringFromGUID2(media_type->subtype, guid_str, arraysize(guid_str)); |
| 581 DVLOG(2) << "Device support unknown media type " << guid_str; | 626 DVLOG(2) << "Device support unknown media type " << guid_str; |
| 582 continue; | 627 continue; |
| 583 } | 628 } |
| 584 capabilities_.Add(capability); | 629 capabilities_.Add(capability); |
| 585 } | 630 } |
| 586 DeleteMediaType(media_type); | 631 DeleteMediaType(media_type); |
| 587 media_type = NULL; | 632 media_type = NULL; |
| 588 } | 633 } |
| 589 | 634 |
| 590 return !capabilities_.empty(); | 635 return !capabilities_.empty(); |
| 591 } | 636 } |
| 592 | 637 |
| 593 void VideoCaptureDeviceWin::SetErrorState(const char* reason) { | 638 void VideoCaptureDeviceWin::SetErrorState(const char* reason) { |
| 594 DCHECK(CalledOnValidThread()); | 639 DCHECK(CalledOnValidThread()); |
| 595 DVLOG(1) << reason; | 640 DVLOG(1) << reason; |
| 596 state_ = kError; | 641 state_ = kError; |
| 597 observer_->OnError(); | 642 observer_->OnError(); |
| 598 } | 643 } |
| 599 | |
| 600 } // namespace media | 644 } // namespace media |
| OLD | NEW |