Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: media/video/capture/win/video_capture_device_factory_win.cc

Issue 510723003: Win Video Capture: add support for enumerating DirectShow WDM devices (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Try with a different similarity percentage Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/video/capture/video_capture_device.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « media/video/capture/video_capture_device.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698