| 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 media { |
| 18 namespace { | 19 namespace { |
| 19 | 20 |
| 20 // Finds and creates a DirectShow Video Capture filter matching the device_name. | 21 // Finds and creates a DirectShow Video Capture filter matching the device_name. |
| 21 HRESULT GetDeviceFilter(const media::VideoCaptureDevice::Name& device_name, | 22 HRESULT GetDeviceFilter(const VideoCaptureDevice::Name& device_name, |
| 22 IBaseFilter** filter) { | 23 IBaseFilter** filter) { |
| 23 DCHECK(filter); | 24 DCHECK(filter); |
| 24 | 25 |
| 25 ScopedComPtr<ICreateDevEnum> dev_enum; | 26 ScopedComPtr<ICreateDevEnum> dev_enum; |
| 26 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, | 27 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, |
| 27 CLSCTX_INPROC); | 28 CLSCTX_INPROC); |
| 28 if (FAILED(hr)) | 29 if (FAILED(hr)) |
| 29 return hr; | 30 return hr; |
| 30 | 31 |
| 31 ScopedComPtr<IEnumMoniker> enum_moniker; | 32 ScopedComPtr<IEnumMoniker> enum_moniker; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 51 static const wchar_t* kPropertyNames[] = { | 52 static const wchar_t* kPropertyNames[] = { |
| 52 L"DevicePath", L"Description", L"FriendlyName" | 53 L"DevicePath", L"Description", L"FriendlyName" |
| 53 }; | 54 }; |
| 54 ScopedVariant name; | 55 ScopedVariant name; |
| 55 for (size_t i = 0; | 56 for (size_t i = 0; |
| 56 i < arraysize(kPropertyNames) && name.type() != VT_BSTR; ++i) { | 57 i < arraysize(kPropertyNames) && name.type() != VT_BSTR; ++i) { |
| 57 prop_bag->Read(kPropertyNames[i], name.Receive(), 0); | 58 prop_bag->Read(kPropertyNames[i], name.Receive(), 0); |
| 58 } | 59 } |
| 59 if (name.type() == VT_BSTR) { | 60 if (name.type() == VT_BSTR) { |
| 60 std::string device_path(base::SysWideToUTF8(V_BSTR(&name))); | 61 std::string device_path(base::SysWideToUTF8(V_BSTR(&name))); |
| 61 if (device_path.compare(device_name.unique_id) == 0) { | 62 if (device_path.compare(device_name.id()) == 0) { |
| 62 // We have found the requested device | 63 // We have found the requested device |
| 63 hr = moniker->BindToObject(0, 0, IID_IBaseFilter, | 64 hr = moniker->BindToObject(0, 0, IID_IBaseFilter, |
| 64 capture_filter.ReceiveVoid()); | 65 capture_filter.ReceiveVoid()); |
| 65 DVPLOG_IF(2, FAILED(hr)) << "Failed to bind camera filter."; | 66 DVPLOG_IF(2, FAILED(hr)) << "Failed to bind camera filter."; |
| 66 break; | 67 break; |
| 67 } | 68 } |
| 68 } | 69 } |
| 69 moniker.Release(); | 70 moniker.Release(); |
| 70 } | 71 } |
| 71 | 72 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 // http://msdn.microsoft.com/en-us/library/dd375432(VS.85).aspx | 139 // http://msdn.microsoft.com/en-us/library/dd375432(VS.85).aspx |
| 139 void DeleteMediaType(AM_MEDIA_TYPE* mt) { | 140 void DeleteMediaType(AM_MEDIA_TYPE* mt) { |
| 140 if (mt != NULL) { | 141 if (mt != NULL) { |
| 141 FreeMediaType(mt); | 142 FreeMediaType(mt); |
| 142 CoTaskMemFree(mt); | 143 CoTaskMemFree(mt); |
| 143 } | 144 } |
| 144 } | 145 } |
| 145 | 146 |
| 146 } // namespace | 147 } // namespace |
| 147 | 148 |
| 148 namespace media { | |
| 149 | |
| 150 // static | 149 // static |
| 151 void VideoCaptureDevice::GetDeviceNames(Names* device_names) { | 150 void VideoCaptureDevice::GetDeviceNames(Names* device_names) { |
| 152 if (VideoCaptureDeviceMFWin::PlatformSupported()) { | 151 if (VideoCaptureDeviceMFWin::PlatformSupported()) { |
| 153 VideoCaptureDeviceMFWin::GetDeviceNames(device_names); | 152 VideoCaptureDeviceMFWin::GetDeviceNames(device_names); |
| 154 } else { | 153 } else { |
| 155 VideoCaptureDeviceWin::GetDeviceNames(device_names); | 154 VideoCaptureDeviceWin::GetDeviceNames(device_names); |
| 156 } | 155 } |
| 157 } | 156 } |
| 158 | 157 |
| 159 // static | 158 // static |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 device_names->clear(); | 194 device_names->clear(); |
| 196 | 195 |
| 197 // Name of a fake DirectShow filter that exist on computers with | 196 // Name of a fake DirectShow filter that exist on computers with |
| 198 // GTalk installed. | 197 // GTalk installed. |
| 199 static const char kGoogleCameraAdapter[] = "google camera adapter"; | 198 static const char kGoogleCameraAdapter[] = "google camera adapter"; |
| 200 | 199 |
| 201 // Enumerate all video capture devices. | 200 // Enumerate all video capture devices. |
| 202 ScopedComPtr<IMoniker> moniker; | 201 ScopedComPtr<IMoniker> moniker; |
| 203 int index = 0; | 202 int index = 0; |
| 204 while (enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK) { | 203 while (enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK) { |
| 205 Name device; | |
| 206 ScopedComPtr<IPropertyBag> prop_bag; | 204 ScopedComPtr<IPropertyBag> prop_bag; |
| 207 hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid()); | 205 hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid()); |
| 208 if (FAILED(hr)) { | 206 if (FAILED(hr)) { |
| 209 moniker.Release(); | 207 moniker.Release(); |
| 210 continue; | 208 continue; |
| 211 } | 209 } |
| 212 | 210 |
| 213 // Find the description or friendly name. | 211 // Find the description or friendly name. |
| 214 ScopedVariant name; | 212 ScopedVariant name; |
| 215 hr = prop_bag->Read(L"Description", name.Receive(), 0); | 213 hr = prop_bag->Read(L"Description", name.Receive(), 0); |
| 216 if (FAILED(hr)) | 214 if (FAILED(hr)) |
| 217 hr = prop_bag->Read(L"FriendlyName", name.Receive(), 0); | 215 hr = prop_bag->Read(L"FriendlyName", name.Receive(), 0); |
| 218 | 216 |
| 219 if (SUCCEEDED(hr) && name.type() == VT_BSTR) { | 217 if (SUCCEEDED(hr) && name.type() == VT_BSTR) { |
| 220 // Ignore all VFW drivers and the special Google Camera Adapter. | 218 // Ignore all VFW drivers and the special Google Camera Adapter. |
| 221 // Google Camera Adapter is not a real DirectShow camera device. | 219 // Google Camera Adapter is not a real DirectShow camera device. |
| 222 // VFW is very old Video for Windows drivers that can not be used. | 220 // VFW is very old Video for Windows drivers that can not be used. |
| 223 const wchar_t* str_ptr = V_BSTR(&name); | 221 const wchar_t* str_ptr = V_BSTR(&name); |
| 224 const int name_length = arraysize(kGoogleCameraAdapter) - 1; | 222 const int name_length = arraysize(kGoogleCameraAdapter) - 1; |
| 225 | 223 |
| 226 if ((wcsstr(str_ptr, L"(VFW)") == NULL) && | 224 if ((wcsstr(str_ptr, L"(VFW)") == NULL) && |
| 227 lstrlenW(str_ptr) < name_length || | 225 lstrlenW(str_ptr) < name_length || |
| 228 (!(LowerCaseEqualsASCII(str_ptr, str_ptr + name_length, | 226 (!(LowerCaseEqualsASCII(str_ptr, str_ptr + name_length, |
| 229 kGoogleCameraAdapter)))) { | 227 kGoogleCameraAdapter)))) { |
| 230 device.device_name = base::SysWideToUTF8(str_ptr); | 228 std::string id; |
| 229 std::string device_name(base::SysWideToUTF8(str_ptr)); |
| 231 name.Reset(); | 230 name.Reset(); |
| 232 hr = prop_bag->Read(L"DevicePath", name.Receive(), 0); | 231 hr = prop_bag->Read(L"DevicePath", name.Receive(), 0); |
| 233 if (FAILED(hr)) { | 232 if (FAILED(hr) || name.type() != VT_BSTR) { |
| 234 device.unique_id = device.device_name; | 233 id = device_name; |
| 235 } else if (name.type() == VT_BSTR) { | 234 } else { |
| 236 device.unique_id = base::SysWideToUTF8(V_BSTR(&name)); | 235 DCHECK_EQ(name.type(), VT_BSTR); |
| 236 id = base::SysWideToUTF8(V_BSTR(&name)); |
| 237 } | 237 } |
| 238 | 238 |
| 239 device_names->push_back(device); | 239 device_names->push_back(Name(device_name, id)); |
| 240 } | 240 } |
| 241 } | 241 } |
| 242 moniker.Release(); | 242 moniker.Release(); |
| 243 } | 243 } |
| 244 } | 244 } |
| 245 | 245 |
| 246 VideoCaptureDeviceWin::VideoCaptureDeviceWin(const Name& device_name) | 246 VideoCaptureDeviceWin::VideoCaptureDeviceWin(const Name& device_name) |
| 247 : device_name_(device_name), | 247 : device_name_(device_name), |
| 248 state_(kIdle), | 248 state_(kIdle), |
| 249 observer_(NULL) { | 249 observer_(NULL) { |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 } | 591 } |
| 592 | 592 |
| 593 void VideoCaptureDeviceWin::SetErrorState(const char* reason) { | 593 void VideoCaptureDeviceWin::SetErrorState(const char* reason) { |
| 594 DCHECK(CalledOnValidThread()); | 594 DCHECK(CalledOnValidThread()); |
| 595 DVLOG(1) << reason; | 595 DVLOG(1) << reason; |
| 596 state_ = kError; | 596 state_ = kError; |
| 597 observer_->OnError(); | 597 observer_->OnError(); |
| 598 } | 598 } |
| 599 | 599 |
| 600 } // namespace media | 600 } // namespace media |
| OLD | NEW |