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

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

Issue 546803002: Win Video Capture: add support for WDM capture devices using a WDM Crossbar filter. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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/win/video_capture_device_win.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 (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 <ks.h> 7 #include <ks.h>
8 #include <ksmedia.h> 8 #include <ksmedia.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <list> 11 #include <list>
12 12
13 #include "base/strings/string_tokenizer.h"
13 #include "base/strings/sys_string_conversions.h" 14 #include "base/strings/sys_string_conversions.h"
14 #include "base/win/scoped_co_mem.h" 15 #include "base/win/scoped_co_mem.h"
15 #include "base/win/scoped_variant.h" 16 #include "base/win/scoped_variant.h"
16 #include "media/video/capture/win/video_capture_device_mf_win.h" 17 #include "media/video/capture/win/video_capture_device_mf_win.h"
17 18
18 using base::win::ScopedCoMem; 19 using base::win::ScopedCoMem;
19 using base::win::ScopedComPtr; 20 using base::win::ScopedComPtr;
20 using base::win::ScopedVariant; 21 using base::win::ScopedVariant;
21 22
22 namespace media { 23 namespace media {
23 24
24 // Finds and creates a DirectShow Video Capture filter matching the device_name. 25 // Tries to find a |device_id| of class |device_class_id|. For this, it
26 // enumerates all system devices of the given class and does a string comparison
27 // of its |property_name| tag. This comparison can be exact or substring-wise
28 // depending on |exact_name_comparison|. If such a device is found, a moniker
29 // to it is returned.
25 // static 30 // static
26 HRESULT VideoCaptureDeviceWin::GetDeviceFilter(const std::string& device_id, 31 ScopedComPtr<IMoniker> FindDeviceAndReturnMoniker(const std::string& device_id,
27 IBaseFilter** filter) { 32 const CLSID device_class_id,
28 DCHECK(filter); 33 const wchar_t* property_name,
34 bool exact_name_comparison) {
29 35
36 ScopedComPtr<IMoniker> moniker;
30 ScopedComPtr<ICreateDevEnum> dev_enum; 37 ScopedComPtr<ICreateDevEnum> dev_enum;
31 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, 38 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL,
32 CLSCTX_INPROC); 39 CLSCTX_INPROC);
40 DPLOG_IF(ERROR, FAILED(hr)) << "Create SystemDeviceEnum";
33 if (FAILED(hr)) 41 if (FAILED(hr))
34 return hr; 42 return moniker;
35 43
36 ScopedComPtr<IEnumMoniker> enum_moniker; 44 ScopedComPtr<IEnumMoniker> enum_moniker;
37 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, 45 hr = dev_enum->CreateClassEnumerator(device_class_id,
38 enum_moniker.Receive(), 0); 46 enum_moniker.Receive(), 0);
39 // CreateClassEnumerator returns S_FALSE on some Windows OS 47 // CreateClassEnumerator returns S_FALSE on some Windows OS when no camera
40 // when no camera exist. Therefore the FAILED macro can't be used. 48 // exist. Therefore the FAILED macro can't be used.
49 DPLOG_IF(ERROR, hr != S_OK) << "CreateClassEnumerator";
41 if (hr != S_OK) 50 if (hr != S_OK)
42 return NULL; 51 return moniker;
43 52
44 ScopedComPtr<IMoniker> moniker;
45 ScopedComPtr<IBaseFilter> capture_filter;
46 DWORD fetched = 0; 53 DWORD fetched = 0;
47 while (enum_moniker->Next(1, moniker.Receive(), &fetched) == S_OK) { 54 while (enum_moniker->Next(1, moniker.Receive(), &fetched) == S_OK) {
48 ScopedComPtr<IPropertyBag> prop_bag; 55 ScopedComPtr<IPropertyBag> prop_bag;
49 hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid()); 56 hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid());
50 if (FAILED(hr)) { 57 if (FAILED(hr)) {
51 moniker.Release(); 58 moniker.Release();
52 continue; 59 continue;
53 } 60 }
54 61
55 // Find the device via DevicePath, Description or FriendlyName, whichever is
56 // available first.
57 static const wchar_t* kPropertyNames[] = {
58 L"DevicePath", L"Description", L"FriendlyName"
59 };
60 ScopedVariant name; 62 ScopedVariant name;
61 for (size_t i = 0; 63 prop_bag->Read(property_name, name.Receive(), 0);
62 i < arraysize(kPropertyNames) && name.type() != VT_BSTR; ++i) { 64
63 prop_bag->Read(kPropertyNames[i], name.Receive(), 0);
64 }
65 if (name.type() == VT_BSTR) { 65 if (name.type() == VT_BSTR) {
66 std::string device_path(base::SysWideToUTF8(V_BSTR(&name))); 66 std::string device_path(base::SysWideToUTF8(V_BSTR(&name)));
67 if (device_path.compare(device_id) == 0) { 67 if ((exact_name_comparison && device_path.compare(device_id) == 0) ||
perkj_chrome 2014/09/05 15:04:21 device_path == device_id
mcasas 2014/09/08 09:16:30 Done.
68 // We have found the requested device 68 (!exact_name_comparison && (device_path.find(device_id)
perkj_chrome 2014/09/05 15:04:21 nit (!exact_name_comparison && (device_path.fi
mcasas 2014/09/08 09:16:30 Done.
69 hr = moniker->BindToObject(0, 0, IID_IBaseFilter, 69 != std::string::npos))) {
70 capture_filter.ReceiveVoid()); 70 return moniker;
71 DLOG_IF(ERROR, FAILED(hr)) << "Failed to bind camera filter: "
72 << logging::SystemErrorCodeToString(hr);
73 break;
74 } 71 }
75 } 72 }
76 moniker.Release(); 73 moniker.Release();
77 } 74 }
75 return moniker;
76 }
78 77
79 *filter = capture_filter.Detach(); 78 // Finds and creates a DirectShow Video Capture filter matching the device_name.
80 if (!*filter && SUCCEEDED(hr)) 79 // |class_id| is usually CLSID_VideoInputDeviceCategory for standard DirectShow
81 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); 80 // device but might also be AM_KSCATEGORY_CAPTURE or AM_KSCATEGORY_CROSSBAR, to
81 // enumerate WDM capture devices or WDM crossbars, respectively.
82 // static
83 HRESULT VideoCaptureDeviceWin::GetDeviceFilter(const std::string& device_id,
84 const CLSID device_class_id,
85 IBaseFilter** filter) {
86 DCHECK(filter);
87 const bool kExactNameComparison = true;
88 ScopedComPtr<IMoniker> moniker;
82 89
83 return hr; 90 static const wchar_t* kPropertyNames[] = {
91 L"DevicePath", L"Description", L"FriendlyName"
92 };
93 for (size_t i = 0; i < arraysize(kPropertyNames); ++i) {
94 moniker = FindDeviceAndReturnMoniker(device_id, device_class_id,
95 kPropertyNames[i], kExactNameComparison);
96 if (!moniker)
97 continue;
98 ScopedComPtr<IBaseFilter> capture_filter;
99 HRESULT hr = moniker->BindToObject(0, 0, IID_IBaseFilter,
100 capture_filter.ReceiveVoid());
101 *filter = capture_filter.Detach();
102 return hr && (!*filter ? E_FAIL : S_OK);
perkj_chrome 2014/09/05 15:04:21 This looks dangerous and hard to read. I don't th
mcasas 2014/09/08 09:16:31 Reverted to previous code.
103 }
104 DLOG(ERROR) << "Failed to find device " << device_id;
105 return E_FAIL;
84 } 106 }
85 107
86 // Check if a Pin matches a category. 108 // Check if a Pin matches a category.
87 // static 109 // static
88 bool VideoCaptureDeviceWin::PinMatchesCategory(IPin* pin, REFGUID category) { 110 bool VideoCaptureDeviceWin::PinMatchesCategory(IPin* pin, REFGUID category) {
89 DCHECK(pin); 111 DCHECK(pin);
90 bool found = false; 112 bool found = false;
91 ScopedComPtr<IKsPropertySet> ks_property; 113 ScopedComPtr<IKsPropertySet> ks_property;
92 HRESULT hr = ks_property.QueryFrom(pin); 114 HRESULT hr = ks_property.QueryFrom(pin);
93 if (SUCCEEDED(hr)) { 115 if (SUCCEEDED(hr)) {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 if (sink_filter_) { 233 if (sink_filter_) {
212 graph_builder_->RemoveFilter(sink_filter_); 234 graph_builder_->RemoveFilter(sink_filter_);
213 sink_filter_ = NULL; 235 sink_filter_ = NULL;
214 } 236 }
215 237
216 if (capture_filter_) 238 if (capture_filter_)
217 graph_builder_->RemoveFilter(capture_filter_); 239 graph_builder_->RemoveFilter(capture_filter_);
218 240
219 if (mjpg_filter_) 241 if (mjpg_filter_)
220 graph_builder_->RemoveFilter(mjpg_filter_); 242 graph_builder_->RemoveFilter(mjpg_filter_);
243
244 if(crossbar_filter_)
245 graph_builder_->RemoveFilter(crossbar_filter_);
221 } 246 }
222 } 247 }
223 248
224 bool VideoCaptureDeviceWin::Init() { 249 bool VideoCaptureDeviceWin::Init() {
225 DCHECK(CalledOnValidThread()); 250 DCHECK(CalledOnValidThread());
226 HRESULT hr = GetDeviceFilter(device_name_.id(), capture_filter_.Receive()); 251 HRESULT hr;
252
253 if (device_name_.capture_api_type() == Name::DIRECT_SHOW_WDM_CROSSBAR) {
254 hr = InstantiateWDMFiltersAndPins();
255 } else {
256 hr = GetDeviceFilter(device_name_.id(), CLSID_VideoInputDeviceCategory,
257 capture_filter_.Receive());
258 }
227 if (!capture_filter_) { 259 if (!capture_filter_) {
228 DLOG(ERROR) << "Failed to create capture filter: " 260 DVLOG(2) << "Failed to create capture filter.";
229 << logging::SystemErrorCodeToString(hr);
230 return false; 261 return false;
231 } 262 }
232 263
233 output_capture_pin_ = 264 output_capture_pin_ =
234 GetPin(capture_filter_, PINDIR_OUTPUT, PIN_CATEGORY_CAPTURE); 265 GetPin(capture_filter_, PINDIR_OUTPUT, PIN_CATEGORY_CAPTURE);
235 if (!output_capture_pin_) { 266 if (!output_capture_pin_) {
236 DLOG(ERROR) << "Failed to get capture output pin"; 267 DVLOG(2) << "Failed to get capture output pin";
237 return false; 268 return false;
238 } 269 }
239 270
240 // Create the sink filter used for receiving Captured frames. 271 // Create the sink filter used for receiving Captured frames.
241 sink_filter_ = new SinkFilter(this); 272 sink_filter_ = new SinkFilter(this);
242 if (sink_filter_ == NULL) { 273 if (sink_filter_ == NULL) {
243 DLOG(ERROR) << "Failed to create send filter"; 274 DVLOG(2) << "Failed to create send filter";
244 return false; 275 return false;
245 } 276 }
246 277
247 input_sink_pin_ = sink_filter_->GetPin(0); 278 input_sink_pin_ = sink_filter_->GetPin(0);
248 279
249 hr = graph_builder_.CreateInstance(CLSID_FilterGraph, NULL, 280 hr = graph_builder_.CreateInstance(CLSID_FilterGraph, NULL,
250 CLSCTX_INPROC_SERVER); 281 CLSCTX_INPROC_SERVER);
251 if (FAILED(hr)) { 282 if (FAILED(hr)) {
252 DLOG(ERROR) << "Failed to create graph builder: " 283 DVLOG(2) << "Failed to create graph builder.";
253 << logging::SystemErrorCodeToString(hr);
254 return false; 284 return false;
255 } 285 }
256 286
257 hr = graph_builder_.QueryInterface(media_control_.Receive()); 287 hr = graph_builder_.QueryInterface(media_control_.Receive());
258 if (FAILED(hr)) { 288 if (FAILED(hr)) {
259 DLOG(ERROR) << "Failed to create media control builder: " 289 DVLOG(2) << "Failed to create media control builder.";
260 << logging::SystemErrorCodeToString(hr);
261 return false; 290 return false;
262 } 291 }
263 292
264 hr = graph_builder_->AddFilter(capture_filter_, NULL); 293 hr = graph_builder_->AddFilter(capture_filter_, NULL);
265 if (FAILED(hr)) { 294 if (FAILED(hr)) {
266 DLOG(ERROR) << "Failed to add the capture device to the graph: " 295 DVLOG(2) << "Failed to add the capture device to the graph.";
267 << logging::SystemErrorCodeToString(hr); 296 return false;
297 }
298
299 if (device_name_.capture_api_type() == Name::DIRECT_SHOW_WDM_CROSSBAR &&
300 FAILED(AddWDMCrossbarFilterToGraphAndConnect())) {
301 DVLOG(2)<< "Failed to add/connect the WDM Crossbar filter to the graph.";
268 return false; 302 return false;
269 } 303 }
270 304
271 hr = graph_builder_->AddFilter(sink_filter_, NULL); 305 hr = graph_builder_->AddFilter(sink_filter_, NULL);
272 if (FAILED(hr)) { 306 if (FAILED(hr)) {
273 DLOG(ERROR) << "Failed to add the send filter to the graph: " 307 DVLOG(2)<< "Failed to add the send filter to the graph.";
274 << logging::SystemErrorCodeToString(hr);
275 return false; 308 return false;
276 } 309 }
277 310
278 return CreateCapabilityMap(); 311 return CreateCapabilityMap();
279 } 312 }
280 313
281 void VideoCaptureDeviceWin::AllocateAndStart( 314 void VideoCaptureDeviceWin::AllocateAndStart(
282 const VideoCaptureParams& params, 315 const VideoCaptureParams& params,
283 scoped_ptr<VideoCaptureDevice::Client> client) { 316 scoped_ptr<VideoCaptureDevice::Client> client) {
284 DCHECK(CalledOnValidThread()); 317 DCHECK(CalledOnValidThread());
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 } 449 }
417 450
418 graph_builder_->Disconnect(output_capture_pin_); 451 graph_builder_->Disconnect(output_capture_pin_);
419 graph_builder_->Disconnect(input_sink_pin_); 452 graph_builder_->Disconnect(input_sink_pin_);
420 453
421 // If the _mjpg filter exist disconnect it even if it has not been used. 454 // If the _mjpg filter exist disconnect it even if it has not been used.
422 if (mjpg_filter_) { 455 if (mjpg_filter_) {
423 graph_builder_->Disconnect(input_mjpg_pin_); 456 graph_builder_->Disconnect(input_mjpg_pin_);
424 graph_builder_->Disconnect(output_mjpg_pin_); 457 graph_builder_->Disconnect(output_mjpg_pin_);
425 } 458 }
459 if (crossbar_filter_) {
460 graph_builder_->Disconnect(analog_video_input_pin_);
461 graph_builder_->Disconnect(crossbar_video_output_pin_);
462 }
426 463
427 if (FAILED(hr)) { 464 if (FAILED(hr)) {
428 SetErrorState("Failed to Stop the Capture device"); 465 SetErrorState("Failed to Stop the Capture device");
429 return; 466 return;
430 } 467 }
431 client_.reset(); 468 client_.reset();
432 state_ = kIdle; 469 state_ = kIdle;
433 } 470 }
434 471
435 // Implements SinkFilterObserver::SinkFilterObserver. 472 // Implements SinkFilterObserver::SinkFilterObserver.
436 void VideoCaptureDeviceWin::FrameReceived(const uint8* buffer, 473 void VideoCaptureDeviceWin::FrameReceived(const uint8* buffer,
437 int length) { 474 int length) {
438 client_->OnIncomingCapturedData( 475 client_->OnIncomingCapturedData(
439 buffer, length, capture_format_, 0, base::TimeTicks::Now()); 476 buffer, length, capture_format_, 0, base::TimeTicks::Now());
440 } 477 }
441 478
442 bool VideoCaptureDeviceWin::CreateCapabilityMap() { 479 bool VideoCaptureDeviceWin::CreateCapabilityMap() {
443 DCHECK(CalledOnValidThread()); 480 DCHECK(CalledOnValidThread());
444 ScopedComPtr<IAMStreamConfig> stream_config; 481 ScopedComPtr<IAMStreamConfig> stream_config;
445 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); 482 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive());
446 if (FAILED(hr)) { 483 if (FAILED(hr)) {
447 DPLOG(ERROR) << "Failed to get IAMStreamConfig interface from " 484 DVLOG(2) << "Failed to get IAMStreamConfig interface from "
448 "capture device: " << logging::SystemErrorCodeToString(hr); 485 "capture device";
449 return false; 486 return false;
450 } 487 }
451 488
452 // Get interface used for getting the frame rate. 489 // Get interface used for getting the frame rate.
453 ScopedComPtr<IAMVideoControl> video_control; 490 ScopedComPtr<IAMVideoControl> video_control;
454 hr = capture_filter_.QueryInterface(video_control.Receive()); 491 hr = capture_filter_.QueryInterface(video_control.Receive());
455 DLOG_IF(WARNING, FAILED(hr)) << "IAMVideoControl Interface NOT SUPPORTED: " 492 DVLOG_IF(2, FAILED(hr)) << "IAMVideoControl Interface NOT SUPPORTED";
456 << logging::SystemErrorCodeToString(hr);
457 493
458 int count = 0, size = 0; 494 int count = 0, size = 0;
459 hr = stream_config->GetNumberOfCapabilities(&count, &size); 495 hr = stream_config->GetNumberOfCapabilities(&count, &size);
460 if (FAILED(hr)) { 496 if (FAILED(hr)) {
461 DLOG(ERROR) << "Failed to GetNumberOfCapabilities: " 497 DVLOG(2) << "Failed to GetNumberOfCapabilities";
462 << logging::SystemErrorCodeToString(hr);
463 return false; 498 return false;
464 } 499 }
465 500
466 scoped_ptr<BYTE[]> caps(new BYTE[size]); 501 scoped_ptr<BYTE[]> caps(new BYTE[size]);
467 for (int i = 0; i < count; ++i) { 502 for (int i = 0; i < count; ++i) {
468 ScopedMediaType media_type; 503 ScopedMediaType media_type;
469 hr = stream_config->GetStreamCaps(i, media_type.Receive(), caps.get()); 504 hr = stream_config->GetStreamCaps(i, media_type.Receive(), caps.get());
470 // GetStreamCaps() may return S_FALSE, so don't use FAILED() or SUCCEED() 505 // GetStreamCaps() may return S_FALSE, so don't use FAILED() or SUCCEED()
471 // macros here since they'll trigger incorrectly. 506 // macros here since they'll trigger incorrectly.
472 if (hr != S_OK) { 507 if (hr != S_OK) {
473 DLOG(ERROR) << "Failed to GetStreamCaps: " 508 DVLOG(2) << "Failed to GetStreamCaps";
474 << logging::SystemErrorCodeToString(hr);
475 return false; 509 return false;
476 } 510 }
477 511
478 if (media_type->majortype == MEDIATYPE_Video && 512 if (media_type->majortype == MEDIATYPE_Video &&
479 media_type->formattype == FORMAT_VideoInfo) { 513 media_type->formattype == FORMAT_VideoInfo) {
480 VideoCaptureCapabilityWin capability(i); 514 VideoCaptureCapabilityWin capability(i);
481 capability.supported_format.pixel_format = 515 capability.supported_format.pixel_format =
482 TranslateMediaSubtypeToPixelFormat(media_type->subtype); 516 TranslateMediaSubtypeToPixelFormat(media_type->subtype);
483 if (capability.supported_format.pixel_format == PIXEL_FORMAT_UNKNOWN) 517 if (capability.supported_format.pixel_format == PIXEL_FORMAT_UNKNOWN)
484 continue; 518 continue;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 (type_support & KSPROPERTY_SUPPORT_SET)) { 580 (type_support & KSPROPERTY_SUPPORT_SET)) {
547 KSPROPERTY_VIDEOPROCAMP_S data = {}; 581 KSPROPERTY_VIDEOPROCAMP_S data = {};
548 data.Property.Set = PROPSETID_VIDCAP_VIDEOPROCAMP; 582 data.Property.Set = PROPSETID_VIDCAP_VIDEOPROCAMP;
549 data.Property.Id = KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY; 583 data.Property.Id = KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY;
550 data.Property.Flags = KSPROPERTY_TYPE_SET; 584 data.Property.Flags = KSPROPERTY_TYPE_SET;
551 data.Value = (power_line_frequency == kPowerLine50Hz) ? 1 : 2; 585 data.Value = (power_line_frequency == kPowerLine50Hz) ? 1 : 2;
552 data.Flags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL; 586 data.Flags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
553 hr = ks_propset->Set(PROPSETID_VIDCAP_VIDEOPROCAMP, 587 hr = ks_propset->Set(PROPSETID_VIDCAP_VIDEOPROCAMP,
554 KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY, 588 KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY,
555 &data, sizeof(data), &data, sizeof(data)); 589 &data, sizeof(data), &data, sizeof(data));
556 DLOG_IF(ERROR, FAILED(hr)) << "Anti-flicker setting failed: " 590 DVLOG_IF(ERROR, FAILED(hr)) << "Anti-flicker setting failed.";
557 << logging::SystemErrorCodeToString(hr);
558 DVLOG_IF(2, SUCCEEDED(hr)) << "Anti-flicker set correctly."; 591 DVLOG_IF(2, SUCCEEDED(hr)) << "Anti-flicker set correctly.";
559 } else { 592 } else {
560 DVLOG(2) << "Anti-flicker setting not supported."; 593 DVLOG(2) << "Anti-flicker setting not supported.";
561 } 594 }
562 } 595 }
563 596
597
mcasas 2014/09/08 09:16:31 nit: remove extra line.
598 // Instantiate a WDM Crossbar Filter and the associated WDM Capture Filter,
599 // extract the correct pins from each. The necessary pins are device specific
perkj_chrome 2014/09/05 15:04:21 This is confusing sentence to read and saying that
mcasas 2014/09/08 09:16:30 Rewritten.
600 // but, experimentally, they usually are the first Crossbar output pin and the
601 // first Capture input pin.
602 HRESULT VideoCaptureDeviceWin::InstantiateWDMFiltersAndPins() {
603 ScopedComPtr<IMoniker> crossbar_moniker = FindDeviceAndReturnMoniker(
604 device_name_.name(), AM_KSCATEGORY_CROSSBAR, L"FriendlyName", false);
perkj_chrome 2014/09/05 15:04:21 Which filter uses the device_name.id() ? Ie, what
mcasas 2014/09/08 09:16:30 You're right, here I should search for the exact d
605 if (!crossbar_moniker)
606 return E_FAIL;
607
608 HRESULT hr = crossbar_moniker->BindToObject(0, 0, IID_IBaseFilter,
609 crossbar_filter_.ReceiveVoid());
610 DPLOG_IF(ERROR, FAILED(hr)) << "Failed to bind crossbar filter";
perkj_chrome 2014/09/05 15:04:21 nit: can we remove one of this log lines and only
mcasas 2014/09/08 09:16:30 Done.
611 DVLOG_IF(1, SUCCEEDED(hr)) << "Crossbar filter instantiated OK.";
612 if (FAILED(hr) || !crossbar_filter_)
613 return E_FAIL;
614
615 // Find Crossbar Video Output Pin: This is usually the first output pin.
616 crossbar_video_output_pin_ = GetPin(
617 crossbar_filter_, PINDIR_OUTPUT, GUID_NULL);
perkj_chrome 2014/09/05 15:04:21 GetPin finds the first output pin right? Isn't the
mcasas 2014/09/08 09:16:31 I'm afraid not. I printed out all Crossbar Pin typ
618 DLOG_IF(ERROR, !crossbar_video_output_pin_)
619 << "Failed to find Crossbar Video Output pin";
620 DVLOG_IF(1, crossbar_video_output_pin_)
perkj_chrome 2014/09/05 15:04:21 dito - please remove one log line.
mcasas 2014/09/08 09:16:31 Done.
621 << "Crossbar Video Output pin created OK.";
622 if (!crossbar_video_output_pin_)
623 return E_FAIL;
624
625 // Find the WDM capture filter associated to the WDM Crossbar filter. This
626 // is a fuzzy matching: they have similar names to the naked eye. Empirically,
627 // use the words of the Crossbar Filter name one by one; they are usually
628 // Vendor, Chip model etc to search in the WDM Filters list.
629 base::StringTokenizer t(device_name_.name(), " ");
630 ScopedComPtr<IMoniker> wdm_source_moniker;
631 while (!wdm_source_moniker && t.GetNext()) {
632 wdm_source_moniker = FindDeviceAndReturnMoniker(
633 t.token(), AM_KSCATEGORY_CAPTURE, L"FriendlyName", false);
634 }
635 DLOG_IF(ERROR, wdm_source_moniker) << "Couldn't find WDM device named";
636 if (!wdm_source_moniker)
637 return E_FAIL;
638
639 hr = wdm_source_moniker->BindToObject(0, 0, IID_IBaseFilter,
640 capture_filter_.ReceiveVoid());
641 DPLOG_IF(ERROR, FAILED(hr)) << "Failed to bind WDM filter";
642 DVLOG_IF(1, SUCCEEDED(hr)) << "WDM filter instantiated OK.";
perkj_chrome 2014/09/05 15:04:21 dito
mcasas 2014/09/08 09:16:30 Done. (Removed all the positive cases' logging).
643 if (FAILED(hr) || !capture_filter_)
644 return E_FAIL;
645
646 // Find the WDM Capture Filter's Analog Video input Pin: usually the first
647 // input pin.
648 analog_video_input_pin_ = GetPin(capture_filter_, PINDIR_INPUT, GUID_NULL);
649 DLOG_IF(ERROR, !analog_video_input_pin_) << "Failed to find WDM Video Input";
650 DVLOG_IF(1, analog_video_input_pin_) << "WDM Video Input pin created OK.";
651 if (!analog_video_input_pin_)
652 return E_FAIL;
653 return S_OK;
654 }
655
656 // Add the WDM Crossbar filter to the Graph and connect the pins previously
657 // found.
658 HRESULT VideoCaptureDeviceWin::AddWDMCrossbarFilterToGraphAndConnect() {
659 HRESULT hr = graph_builder_->AddFilter(crossbar_filter_, NULL);
660 DPLOG_IF(ERROR, FAILED(hr)) << "Failed to add Crossbar filter to the graph";
661 DVPLOG_IF(1, SUCCEEDED(hr)) << "Crossbar filter added OK to the graph";
662 if (FAILED(hr))
663 return E_FAIL;
664
665 hr = graph_builder_->ConnectDirect(
666 crossbar_video_output_pin_, analog_video_input_pin_, NULL);
667 DPLOG_IF(ERROR, FAILED(hr)) << "Failed to plug WDM filters to each other";
668 DVPLOG_IF(1, SUCCEEDED(hr)) << "WDM filters plugged OK";
669 if (FAILED(hr))
670 return E_FAIL;
671 return S_OK;
672 }
673
564 void VideoCaptureDeviceWin::SetErrorState(const std::string& reason) { 674 void VideoCaptureDeviceWin::SetErrorState(const std::string& reason) {
565 DCHECK(CalledOnValidThread()); 675 DCHECK(CalledOnValidThread());
676 DVLOG(1) << reason;
566 state_ = kError; 677 state_ = kError;
567 client_->OnError(reason); 678 client_->OnError(reason);
568 } 679 }
569 } // namespace media 680 } // namespace media
OLDNEW
« no previous file with comments | « media/video/capture/win/video_capture_device_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698