| 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 <ks.h> | 7 #include <ks.h> |
| 8 #include <ksmedia.h> | 8 #include <ksmedia.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 for (size_t i = 0; | 62 for (size_t i = 0; |
| 63 i < arraysize(kPropertyNames) && name.type() != VT_BSTR; ++i) { | 63 i < arraysize(kPropertyNames) && name.type() != VT_BSTR; ++i) { |
| 64 prop_bag->Read(kPropertyNames[i], name.Receive(), 0); | 64 prop_bag->Read(kPropertyNames[i], name.Receive(), 0); |
| 65 } | 65 } |
| 66 if (name.type() == VT_BSTR) { | 66 if (name.type() == VT_BSTR) { |
| 67 std::string device_path(base::SysWideToUTF8(V_BSTR(&name))); | 67 std::string device_path(base::SysWideToUTF8(V_BSTR(&name))); |
| 68 if (device_path.compare(device_name.id()) == 0) { | 68 if (device_path.compare(device_name.id()) == 0) { |
| 69 // We have found the requested device | 69 // We have found the requested device |
| 70 hr = moniker->BindToObject(0, 0, IID_IBaseFilter, | 70 hr = moniker->BindToObject(0, 0, IID_IBaseFilter, |
| 71 capture_filter.ReceiveVoid()); | 71 capture_filter.ReceiveVoid()); |
| 72 DVPLOG_IF(2, FAILED(hr)) << "Failed to bind camera filter."; | 72 DLOG_IF(ERROR, FAILED(hr)) << "Failed to bind camera filter: " |
| 73 << logging::SystemErrorCodeToString(hr); |
| 73 break; | 74 break; |
| 74 } | 75 } |
| 75 } | 76 } |
| 76 moniker.Release(); | 77 moniker.Release(); |
| 77 } | 78 } |
| 78 | 79 |
| 79 *filter = capture_filter.Detach(); | 80 *filter = capture_filter.Detach(); |
| 80 if (!*filter && SUCCEEDED(hr)) | 81 if (!*filter && SUCCEEDED(hr)) |
| 81 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); | 82 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); |
| 82 | 83 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 | 219 |
| 219 if (mjpg_filter_) | 220 if (mjpg_filter_) |
| 220 graph_builder_->RemoveFilter(mjpg_filter_); | 221 graph_builder_->RemoveFilter(mjpg_filter_); |
| 221 } | 222 } |
| 222 } | 223 } |
| 223 | 224 |
| 224 bool VideoCaptureDeviceWin::Init() { | 225 bool VideoCaptureDeviceWin::Init() { |
| 225 DCHECK(CalledOnValidThread()); | 226 DCHECK(CalledOnValidThread()); |
| 226 HRESULT hr = GetDeviceFilter(device_name_, capture_filter_.Receive()); | 227 HRESULT hr = GetDeviceFilter(device_name_, capture_filter_.Receive()); |
| 227 if (!capture_filter_) { | 228 if (!capture_filter_) { |
| 228 DVLOG(2) << "Failed to create capture filter."; | 229 DLOG(ERROR) << "Failed to create capture filter: " |
| 230 << logging::SystemErrorCodeToString(hr); |
| 229 return false; | 231 return false; |
| 230 } | 232 } |
| 231 | 233 |
| 232 output_capture_pin_ = | 234 output_capture_pin_ = |
| 233 GetPin(capture_filter_, PINDIR_OUTPUT, PIN_CATEGORY_CAPTURE); | 235 GetPin(capture_filter_, PINDIR_OUTPUT, PIN_CATEGORY_CAPTURE); |
| 234 if (!output_capture_pin_) { | 236 if (!output_capture_pin_) { |
| 235 DVLOG(2) << "Failed to get capture output pin"; | 237 DLOG(ERROR) << "Failed to get capture output pin"; |
| 236 return false; | 238 return false; |
| 237 } | 239 } |
| 238 | 240 |
| 239 // Create the sink filter used for receiving Captured frames. | 241 // Create the sink filter used for receiving Captured frames. |
| 240 sink_filter_ = new SinkFilter(this); | 242 sink_filter_ = new SinkFilter(this); |
| 241 if (sink_filter_ == NULL) { | 243 if (sink_filter_ == NULL) { |
| 242 DVLOG(2) << "Failed to create send filter"; | 244 DLOG(ERROR) << "Failed to create send filter"; |
| 243 return false; | 245 return false; |
| 244 } | 246 } |
| 245 | 247 |
| 246 input_sink_pin_ = sink_filter_->GetPin(0); | 248 input_sink_pin_ = sink_filter_->GetPin(0); |
| 247 | 249 |
| 248 hr = graph_builder_.CreateInstance(CLSID_FilterGraph, NULL, | 250 hr = graph_builder_.CreateInstance(CLSID_FilterGraph, NULL, |
| 249 CLSCTX_INPROC_SERVER); | 251 CLSCTX_INPROC_SERVER); |
| 250 if (FAILED(hr)) { | 252 if (FAILED(hr)) { |
| 251 DVLOG(2) << "Failed to create graph builder."; | 253 DLOG(ERROR) << "Failed to create graph builder: " |
| 254 << logging::SystemErrorCodeToString(hr); |
| 252 return false; | 255 return false; |
| 253 } | 256 } |
| 254 | 257 |
| 255 hr = graph_builder_.QueryInterface(media_control_.Receive()); | 258 hr = graph_builder_.QueryInterface(media_control_.Receive()); |
| 256 if (FAILED(hr)) { | 259 if (FAILED(hr)) { |
| 257 DVLOG(2) << "Failed to create media control builder."; | 260 DLOG(ERROR) << "Failed to create media control builder: " |
| 261 << logging::SystemErrorCodeToString(hr); |
| 258 return false; | 262 return false; |
| 259 } | 263 } |
| 260 | 264 |
| 261 hr = graph_builder_->AddFilter(capture_filter_, NULL); | 265 hr = graph_builder_->AddFilter(capture_filter_, NULL); |
| 262 if (FAILED(hr)) { | 266 if (FAILED(hr)) { |
| 263 DVLOG(2) << "Failed to add the capture device to the graph."; | 267 DLOG(ERROR) << "Failed to add the capture device to the graph: " |
| 268 << logging::SystemErrorCodeToString(hr); |
| 264 return false; | 269 return false; |
| 265 } | 270 } |
| 266 | 271 |
| 267 hr = graph_builder_->AddFilter(sink_filter_, NULL); | 272 hr = graph_builder_->AddFilter(sink_filter_, NULL); |
| 268 if (FAILED(hr)) { | 273 if (FAILED(hr)) { |
| 269 DVLOG(2)<< "Failed to add the send filter to the graph."; | 274 DLOG(ERROR) << "Failed to add the send filter to the graph: " |
| 275 << logging::SystemErrorCodeToString(hr); |
| 270 return false; | 276 return false; |
| 271 } | 277 } |
| 272 | 278 |
| 273 return CreateCapabilityMap(); | 279 return CreateCapabilityMap(); |
| 274 } | 280 } |
| 275 | 281 |
| 276 void VideoCaptureDeviceWin::AllocateAndStart( | 282 void VideoCaptureDeviceWin::AllocateAndStart( |
| 277 const VideoCaptureParams& params, | 283 const VideoCaptureParams& params, |
| 278 scoped_ptr<VideoCaptureDevice::Client> client) { | 284 scoped_ptr<VideoCaptureDevice::Client> client) { |
| 279 DCHECK(CalledOnValidThread()); | 285 DCHECK(CalledOnValidThread()); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 int length) { | 438 int length) { |
| 433 client_->OnIncomingCapturedData( | 439 client_->OnIncomingCapturedData( |
| 434 buffer, length, capture_format_, 0, base::TimeTicks::Now()); | 440 buffer, length, capture_format_, 0, base::TimeTicks::Now()); |
| 435 } | 441 } |
| 436 | 442 |
| 437 bool VideoCaptureDeviceWin::CreateCapabilityMap() { | 443 bool VideoCaptureDeviceWin::CreateCapabilityMap() { |
| 438 DCHECK(CalledOnValidThread()); | 444 DCHECK(CalledOnValidThread()); |
| 439 ScopedComPtr<IAMStreamConfig> stream_config; | 445 ScopedComPtr<IAMStreamConfig> stream_config; |
| 440 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); | 446 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); |
| 441 if (FAILED(hr)) { | 447 if (FAILED(hr)) { |
| 442 DVLOG(2) << "Failed to get IAMStreamConfig interface from " | 448 DPLOG(ERROR) << "Failed to get IAMStreamConfig interface from " |
| 443 "capture device"; | 449 "capture device: " << logging::SystemErrorCodeToString(hr); |
| 444 return false; | 450 return false; |
| 445 } | 451 } |
| 446 | 452 |
| 447 // Get interface used for getting the frame rate. | 453 // Get interface used for getting the frame rate. |
| 448 ScopedComPtr<IAMVideoControl> video_control; | 454 ScopedComPtr<IAMVideoControl> video_control; |
| 449 hr = capture_filter_.QueryInterface(video_control.Receive()); | 455 hr = capture_filter_.QueryInterface(video_control.Receive()); |
| 450 DVLOG_IF(2, FAILED(hr)) << "IAMVideoControl Interface NOT SUPPORTED"; | 456 DLOG_IF(WARNING, FAILED(hr)) << "IAMVideoControl Interface NOT SUPPORTED: " |
| 457 << logging::SystemErrorCodeToString(hr); |
| 451 | 458 |
| 452 int count = 0, size = 0; | 459 int count = 0, size = 0; |
| 453 hr = stream_config->GetNumberOfCapabilities(&count, &size); | 460 hr = stream_config->GetNumberOfCapabilities(&count, &size); |
| 454 if (FAILED(hr)) { | 461 if (FAILED(hr)) { |
| 455 DVLOG(2) << "Failed to GetNumberOfCapabilities"; | 462 DLOG(ERROR) << "Failed to GetNumberOfCapabilities: " |
| 463 << logging::SystemErrorCodeToString(hr); |
| 456 return false; | 464 return false; |
| 457 } | 465 } |
| 458 | 466 |
| 459 scoped_ptr<BYTE[]> caps(new BYTE[size]); | 467 scoped_ptr<BYTE[]> caps(new BYTE[size]); |
| 460 for (int i = 0; i < count; ++i) { | 468 for (int i = 0; i < count; ++i) { |
| 461 ScopedMediaType media_type; | 469 ScopedMediaType media_type; |
| 462 hr = stream_config->GetStreamCaps(i, media_type.Receive(), caps.get()); | 470 hr = stream_config->GetStreamCaps(i, media_type.Receive(), caps.get()); |
| 463 // GetStreamCaps() may return S_FALSE, so don't use FAILED() or SUCCEED() | 471 // GetStreamCaps() may return S_FALSE, so don't use FAILED() or SUCCEED() |
| 464 // macros here since they'll trigger incorrectly. | 472 // macros here since they'll trigger incorrectly. |
| 465 if (hr != S_OK) { | 473 if (hr != S_OK) { |
| 466 DVLOG(2) << "Failed to GetStreamCaps"; | 474 DLOG(ERROR) << "Failed to GetStreamCaps: " |
| 475 << logging::SystemErrorCodeToString(hr); |
| 467 return false; | 476 return false; |
| 468 } | 477 } |
| 469 | 478 |
| 470 if (media_type->majortype == MEDIATYPE_Video && | 479 if (media_type->majortype == MEDIATYPE_Video && |
| 471 media_type->formattype == FORMAT_VideoInfo) { | 480 media_type->formattype == FORMAT_VideoInfo) { |
| 472 VideoCaptureCapabilityWin capability(i); | 481 VideoCaptureCapabilityWin capability(i); |
| 473 capability.supported_format.pixel_format = | 482 capability.supported_format.pixel_format = |
| 474 TranslateMediaSubtypeToPixelFormat(media_type->subtype); | 483 TranslateMediaSubtypeToPixelFormat(media_type->subtype); |
| 475 if (capability.supported_format.pixel_format == PIXEL_FORMAT_UNKNOWN) | 484 if (capability.supported_format.pixel_format == PIXEL_FORMAT_UNKNOWN) |
| 476 continue; | 485 continue; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 (type_support & KSPROPERTY_SUPPORT_SET)) { | 547 (type_support & KSPROPERTY_SUPPORT_SET)) { |
| 539 KSPROPERTY_VIDEOPROCAMP_S data = {}; | 548 KSPROPERTY_VIDEOPROCAMP_S data = {}; |
| 540 data.Property.Set = PROPSETID_VIDCAP_VIDEOPROCAMP; | 549 data.Property.Set = PROPSETID_VIDCAP_VIDEOPROCAMP; |
| 541 data.Property.Id = KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY; | 550 data.Property.Id = KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY; |
| 542 data.Property.Flags = KSPROPERTY_TYPE_SET; | 551 data.Property.Flags = KSPROPERTY_TYPE_SET; |
| 543 data.Value = (power_line_frequency == kPowerLine50Hz) ? 1 : 2; | 552 data.Value = (power_line_frequency == kPowerLine50Hz) ? 1 : 2; |
| 544 data.Flags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL; | 553 data.Flags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL; |
| 545 hr = ks_propset->Set(PROPSETID_VIDCAP_VIDEOPROCAMP, | 554 hr = ks_propset->Set(PROPSETID_VIDCAP_VIDEOPROCAMP, |
| 546 KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY, | 555 KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY, |
| 547 &data, sizeof(data), &data, sizeof(data)); | 556 &data, sizeof(data), &data, sizeof(data)); |
| 548 DVLOG_IF(ERROR, FAILED(hr)) << "Anti-flicker setting failed."; | 557 DLOG_IF(ERROR, FAILED(hr)) << "Anti-flicker setting failed: " |
| 558 << logging::SystemErrorCodeToString(hr); |
| 549 DVLOG_IF(2, SUCCEEDED(hr)) << "Anti-flicker set correctly."; | 559 DVLOG_IF(2, SUCCEEDED(hr)) << "Anti-flicker set correctly."; |
| 550 } else { | 560 } else { |
| 551 DVLOG(2) << "Anti-flicker setting not supported."; | 561 DVLOG(2) << "Anti-flicker setting not supported."; |
| 552 } | 562 } |
| 553 } | 563 } |
| 554 | 564 |
| 555 void VideoCaptureDeviceWin::SetErrorState(const std::string& reason) { | 565 void VideoCaptureDeviceWin::SetErrorState(const std::string& reason) { |
| 556 DCHECK(CalledOnValidThread()); | 566 DCHECK(CalledOnValidThread()); |
| 557 DVLOG(1) << reason; | |
| 558 state_ = kError; | 567 state_ = kError; |
| 559 client_->OnError(reason); | 568 client_->OnError(reason); |
| 560 } | 569 } |
| 561 } // namespace media | 570 } // namespace media |
| OLD | NEW |