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/capture/video/win/video_capture_device_win.h" | 5 #include "media/capture/video/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 #include <objbase.h> | 9 #include <objbase.h> |
| 10 #include <vidcap.h> | |
| 11 | 10 |
| 12 #include <algorithm> | 11 #include <algorithm> |
| 13 #include <list> | 12 #include <list> |
| 14 #include <utility> | 13 #include <utility> |
| 15 | 14 |
| 16 #include "base/macros.h" | 15 #include "base/macros.h" |
| 17 #include "base/strings/sys_string_conversions.h" | 16 #include "base/strings/sys_string_conversions.h" |
| 18 #include "base/win/scoped_co_mem.h" | 17 #include "base/win/scoped_co_mem.h" |
| 19 #include "base/win/scoped_variant.h" | 18 #include "base/win/scoped_variant.h" |
| 20 #include "media/base/timestamp_constants.h" | 19 #include "media/base/timestamp_constants.h" |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 void VideoCaptureDeviceWin::ScopedMediaType::DeleteMediaType( | 258 void VideoCaptureDeviceWin::ScopedMediaType::DeleteMediaType( |
| 260 AM_MEDIA_TYPE* mt) { | 259 AM_MEDIA_TYPE* mt) { |
| 261 if (mt != NULL) { | 260 if (mt != NULL) { |
| 262 FreeMediaType(mt); | 261 FreeMediaType(mt); |
| 263 CoTaskMemFree(mt); | 262 CoTaskMemFree(mt); |
| 264 } | 263 } |
| 265 } | 264 } |
| 266 | 265 |
| 267 VideoCaptureDeviceWin::VideoCaptureDeviceWin( | 266 VideoCaptureDeviceWin::VideoCaptureDeviceWin( |
| 268 const VideoCaptureDeviceDescriptor& device_descriptor) | 267 const VideoCaptureDeviceDescriptor& device_descriptor) |
| 269 : device_descriptor_(device_descriptor), state_(kIdle) { | 268 : device_descriptor_(device_descriptor), |
| 269 state_(kIdle), | |
| 270 white_balance_mode_manual_(false), | |
| 271 exposure_mode_manual_(false) { | |
| 270 // TODO(mcasas): Check that CoInitializeEx() has been called with the | 272 // TODO(mcasas): Check that CoInitializeEx() has been called with the |
| 271 // appropriate Apartment model, i.e., Single Threaded. | 273 // appropriate Apartment model, i.e., Single Threaded. |
| 272 } | 274 } |
| 273 | 275 |
| 274 VideoCaptureDeviceWin::~VideoCaptureDeviceWin() { | 276 VideoCaptureDeviceWin::~VideoCaptureDeviceWin() { |
| 275 DCHECK(thread_checker_.CalledOnValidThread()); | 277 DCHECK(thread_checker_.CalledOnValidThread()); |
| 276 if (media_control_.Get()) | 278 if (media_control_.Get()) |
| 277 media_control_->Stop(); | 279 media_control_->Stop(); |
| 278 | 280 |
| 279 if (graph_builder_.Get()) { | 281 if (graph_builder_.Get()) { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 456 | 458 |
| 457 // Start capturing. | 459 // Start capturing. |
| 458 hr = media_control_->Run(); | 460 hr = media_control_->Run(); |
| 459 if (FAILED(hr)) { | 461 if (FAILED(hr)) { |
| 460 SetErrorState(FROM_HERE, "Failed to start the Capture device.", hr); | 462 SetErrorState(FROM_HERE, "Failed to start the Capture device.", hr); |
| 461 return; | 463 return; |
| 462 } | 464 } |
| 463 | 465 |
| 464 client_->OnStarted(); | 466 client_->OnStarted(); |
| 465 state_ = kCapturing; | 467 state_ = kCapturing; |
| 466 } | |
| 467 | |
| 468 void VideoCaptureDeviceWin::StopAndDeAllocate() { | |
| 469 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 470 if (state_ != kCapturing) | |
| 471 return; | |
| 472 | |
| 473 HRESULT hr = media_control_->Stop(); | |
| 474 if (FAILED(hr)) { | |
| 475 SetErrorState(FROM_HERE, "Failed to stop the capture graph.", hr); | |
| 476 return; | |
| 477 } | |
| 478 | |
| 479 graph_builder_->Disconnect(output_capture_pin_.Get()); | |
| 480 graph_builder_->Disconnect(input_sink_pin_.Get()); | |
| 481 | |
| 482 client_.reset(); | |
| 483 state_ = kIdle; | |
| 484 } | |
| 485 | |
| 486 void VideoCaptureDeviceWin::TakePhoto(TakePhotoCallback callback) { | |
| 487 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 488 // DirectShow has other means of capturing still pictures, e.g. connecting a | |
| 489 // SampleGrabber filter to a PIN_CATEGORY_STILL of |capture_filter_|. This | |
| 490 // way, however, is not widespread and proves too cumbersome, so we just grab | |
| 491 // the next captured frame instead. | |
| 492 take_photo_callbacks_.push(std::move(callback)); | |
| 493 } | |
| 494 | |
| 495 void VideoCaptureDeviceWin::GetPhotoCapabilities( | |
| 496 GetPhotoCapabilitiesCallback callback) { | |
| 497 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 498 | 468 |
| 499 base::win::ScopedComPtr<IKsTopologyInfo> info; | 469 base::win::ScopedComPtr<IKsTopologyInfo> info; |
| 500 HRESULT hr = capture_filter_.CopyTo(info.Receive()); | 470 hr = capture_filter_.CopyTo(info.Receive()); |
|
robliao
2017/05/11 05:14:07
Conflict warning: Receive is being renamed to GetA
mcasas
2017/05/12 18:52:49
gotcha! Will rebase.
| |
| 501 if (FAILED(hr)) { | 471 if (FAILED(hr)) { |
| 502 SetErrorState(FROM_HERE, "Failed to obtain the topology info.", hr); | 472 SetErrorState(FROM_HERE, "Failed to obtain the topology info.", hr); |
| 503 return; | 473 return; |
| 504 } | 474 } |
| 505 | 475 |
| 506 DWORD num_nodes = 0; | 476 DWORD num_nodes = 0; |
| 507 hr = info->get_NumNodes(&num_nodes); | 477 hr = info->get_NumNodes(&num_nodes); |
| 508 if (FAILED(hr)) { | 478 if (FAILED(hr)) { |
| 509 SetErrorState(FROM_HERE, "Failed to obtain the number of nodes.", hr); | 479 SetErrorState(FROM_HERE, "Failed to obtain the number of nodes.", hr); |
| 510 return; | 480 return; |
| 511 } | 481 } |
| 512 | 482 |
| 513 // Every UVC camera is expected to have a single ICameraControl and a single | 483 // Every UVC camera is expected to have a single ICameraControl and a single |
| 514 // IVideoProcAmp nodes, and both are needed; ignore any unlikely later ones. | 484 // IVideoProcAmp nodes, and both are needed; ignore any unlikely later ones. |
| 515 GUID node_type; | 485 GUID node_type; |
| 516 base::win::ScopedComPtr<ICameraControl> camera_control; | |
| 517 for (size_t i = 0; i < num_nodes; i++) { | 486 for (size_t i = 0; i < num_nodes; i++) { |
| 518 info->get_NodeType(i, &node_type); | 487 info->get_NodeType(i, &node_type); |
| 519 if (IsEqualGUID(node_type, KSNODETYPE_VIDEO_CAMERA_TERMINAL)) { | 488 if (IsEqualGUID(node_type, KSNODETYPE_VIDEO_CAMERA_TERMINAL)) { |
| 520 hr = info->CreateNodeInstance(i, IID_PPV_ARGS(camera_control.Receive())); | 489 hr = info->CreateNodeInstance(i, IID_PPV_ARGS(camera_control_.Receive())); |
| 521 if (SUCCEEDED(hr)) | 490 if (SUCCEEDED(hr)) |
| 522 break; | 491 break; |
| 523 SetErrorState(FROM_HERE, "Failed to retrieve the ICameraControl.", hr); | 492 SetErrorState(FROM_HERE, "Failed to retrieve the ICameraControl.", hr); |
| 524 return; | 493 return; |
| 525 } | 494 } |
| 526 } | 495 } |
| 527 if (!camera_control) | |
| 528 return; | |
| 529 base::win::ScopedComPtr<IVideoProcAmp> video_control; | |
| 530 for (size_t i = 0; i < num_nodes; i++) { | 496 for (size_t i = 0; i < num_nodes; i++) { |
| 531 info->get_NodeType(i, &node_type); | 497 info->get_NodeType(i, &node_type); |
| 532 if (IsEqualGUID(node_type, KSNODETYPE_VIDEO_PROCESSING)) { | 498 if (IsEqualGUID(node_type, KSNODETYPE_VIDEO_PROCESSING)) { |
| 533 hr = info->CreateNodeInstance(i, IID_PPV_ARGS(video_control.Receive())); | 499 hr = info->CreateNodeInstance(i, IID_PPV_ARGS(video_control_.Receive())); |
| 534 if (SUCCEEDED(hr)) | 500 if (SUCCEEDED(hr)) |
| 535 break; | 501 break; |
| 536 SetErrorState(FROM_HERE, "Failed to retrieve the IVideoProcAmp.", hr); | 502 SetErrorState(FROM_HERE, "Failed to retrieve the IVideoProcAmp.", hr); |
| 537 return; | 503 return; |
| 538 } | 504 } |
| 539 } | 505 } |
| 540 if (!video_control) | 506 } |
| 507 | |
| 508 void VideoCaptureDeviceWin::StopAndDeAllocate() { | |
| 509 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 510 if (state_ != kCapturing) | |
| 511 return; | |
| 512 | |
| 513 HRESULT hr = media_control_->Stop(); | |
| 514 if (FAILED(hr)) { | |
| 515 SetErrorState(FROM_HERE, "Failed to stop the capture graph.", hr); | |
| 516 return; | |
| 517 } | |
| 518 | |
| 519 graph_builder_->Disconnect(output_capture_pin_.Get()); | |
| 520 graph_builder_->Disconnect(input_sink_pin_.Get()); | |
| 521 | |
| 522 client_.reset(); | |
| 523 state_ = kIdle; | |
| 524 } | |
| 525 | |
| 526 void VideoCaptureDeviceWin::TakePhoto(TakePhotoCallback callback) { | |
| 527 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 528 // DirectShow has other means of capturing still pictures, e.g. connecting a | |
| 529 // SampleGrabber filter to a PIN_CATEGORY_STILL of |capture_filter_|. This | |
| 530 // way, however, is not widespread and proves too cumbersome, so we just grab | |
| 531 // the next captured frame instead. | |
| 532 take_photo_callbacks_.push(std::move(callback)); | |
| 533 } | |
| 534 | |
| 535 void VideoCaptureDeviceWin::GetPhotoCapabilities( | |
| 536 GetPhotoCapabilitiesCallback callback) { | |
| 537 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 538 | |
| 539 if (!camera_control_ || !video_control_) | |
| 541 return; | 540 return; |
| 542 | 541 |
| 543 auto photo_capabilities = mojom::PhotoCapabilities::New(); | 542 auto photo_capabilities = mojom::PhotoCapabilities::New(); |
| 544 | 543 |
| 545 photo_capabilities->exposure_compensation = RetrieveControlRangeAndCurrent( | 544 photo_capabilities->exposure_compensation = RetrieveControlRangeAndCurrent( |
| 546 [camera_control](auto... args) { | 545 [this](auto... args) { |
| 547 return camera_control->getRange_Exposure(args...); | 546 return this->camera_control_->getRange_Exposure(args...); |
| 548 }, | 547 }, |
| 549 [camera_control](auto... args) { | 548 [this](auto... args) { |
| 550 return camera_control->get_Exposure(args...); | 549 return this->camera_control_->get_Exposure(args...); |
| 551 }, | 550 }, |
| 552 &photo_capabilities->supported_exposure_modes, | 551 &photo_capabilities->supported_exposure_modes, |
| 553 &photo_capabilities->current_exposure_mode); | 552 &photo_capabilities->current_exposure_mode); |
| 554 | 553 |
| 555 photo_capabilities->color_temperature = RetrieveControlRangeAndCurrent( | 554 photo_capabilities->color_temperature = RetrieveControlRangeAndCurrent( |
| 556 [video_control](auto... args) { | 555 [this](auto... args) { |
| 557 return video_control->getRange_WhiteBalance(args...); | 556 return this->video_control_->getRange_WhiteBalance(args...); |
| 558 }, | 557 }, |
| 559 [video_control](auto... args) { | 558 [this](auto... args) { |
| 560 return video_control->get_WhiteBalance(args...); | 559 return this->video_control_->get_WhiteBalance(args...); |
| 561 }, | 560 }, |
| 562 &photo_capabilities->supported_white_balance_modes, | 561 &photo_capabilities->supported_white_balance_modes, |
| 563 &photo_capabilities->current_white_balance_mode); | 562 &photo_capabilities->current_white_balance_mode); |
| 564 | 563 |
| 565 // Ignore the returned Focus control range and status. | 564 // Ignore the returned Focus control range and status. |
| 566 RetrieveControlRangeAndCurrent( | 565 RetrieveControlRangeAndCurrent( |
| 567 [camera_control](auto... args) { | 566 [this](auto... args) { |
| 568 return camera_control->getRange_Focus(args...); | 567 return this->camera_control_->getRange_Focus(args...); |
| 569 }, | 568 }, |
| 570 [camera_control](auto... args) { | 569 [this](auto... args) { |
| 571 return camera_control->get_Focus(args...); | 570 return this->camera_control_->get_Focus(args...); |
| 572 }, | 571 }, |
| 573 &photo_capabilities->supported_focus_modes, | 572 &photo_capabilities->supported_focus_modes, |
| 574 &photo_capabilities->current_focus_mode); | 573 &photo_capabilities->current_focus_mode); |
| 575 | 574 |
| 576 photo_capabilities->iso = mojom::Range::New(); | 575 photo_capabilities->iso = mojom::Range::New(); |
| 577 | 576 |
| 578 photo_capabilities->brightness = RetrieveControlRangeAndCurrent( | 577 photo_capabilities->brightness = RetrieveControlRangeAndCurrent( |
| 579 [video_control](auto... args) { | 578 [this](auto... args) { |
| 580 return video_control->getRange_Brightness(args...); | 579 return this->video_control_->getRange_Brightness(args...); |
| 581 }, | 580 }, |
| 582 [video_control](auto... args) { | 581 [this](auto... args) { |
| 583 return video_control->get_Brightness(args...); | 582 return this->video_control_->get_Brightness(args...); |
| 584 }); | 583 }); |
| 585 photo_capabilities->contrast = RetrieveControlRangeAndCurrent( | 584 photo_capabilities->contrast = RetrieveControlRangeAndCurrent( |
| 586 [video_control](auto... args) { | 585 [this](auto... args) { |
| 587 return video_control->getRange_Contrast(args...); | 586 return this->video_control_->getRange_Contrast(args...); |
| 588 }, | 587 }, |
| 589 [video_control](auto... args) { | 588 [this](auto... args) { |
| 590 return video_control->get_Contrast(args...); | 589 return this->video_control_->get_Contrast(args...); |
| 591 }); | 590 }); |
| 592 photo_capabilities->saturation = RetrieveControlRangeAndCurrent( | 591 photo_capabilities->saturation = RetrieveControlRangeAndCurrent( |
| 593 [video_control](auto... args) { | 592 [this](auto... args) { |
| 594 return video_control->getRange_Saturation(args...); | 593 return this->video_control_->getRange_Saturation(args...); |
| 595 }, | 594 }, |
| 596 [video_control](auto... args) { | 595 [this](auto... args) { |
| 597 return video_control->get_Saturation(args...); | 596 return this->video_control_->get_Saturation(args...); |
| 598 }); | 597 }); |
| 599 photo_capabilities->sharpness = RetrieveControlRangeAndCurrent( | 598 photo_capabilities->sharpness = RetrieveControlRangeAndCurrent( |
| 600 [video_control](auto... args) { | 599 [this](auto... args) { |
| 601 return video_control->getRange_Sharpness(args...); | 600 return this->video_control_->getRange_Sharpness(args...); |
| 602 }, | 601 }, |
| 603 [video_control](auto... args) { | 602 [this](auto... args) { |
| 604 return video_control->get_Sharpness(args...); | 603 return this->video_control_->get_Sharpness(args...); |
| 605 }); | 604 }); |
| 606 | 605 |
| 607 photo_capabilities->zoom = RetrieveControlRangeAndCurrent( | 606 photo_capabilities->zoom = RetrieveControlRangeAndCurrent( |
| 608 [camera_control](auto... args) { | 607 [this](auto... args) { |
| 609 return camera_control->getRange_Zoom(args...); | 608 return this->camera_control_->getRange_Zoom(args...); |
| 610 }, | 609 }, |
| 611 [camera_control](auto... args) { | 610 [this](auto... args) { |
| 612 return camera_control->get_Zoom(args...); | 611 return this->camera_control_->get_Zoom(args...); |
| 613 }); | 612 }); |
| 614 | 613 |
| 615 photo_capabilities->red_eye_reduction = mojom::RedEyeReduction::NEVER; | 614 photo_capabilities->red_eye_reduction = mojom::RedEyeReduction::NEVER; |
| 616 photo_capabilities->height = mojom::Range::New(); | 615 photo_capabilities->height = mojom::Range::New(); |
| 617 photo_capabilities->width = mojom::Range::New(); | 616 photo_capabilities->width = mojom::Range::New(); |
| 618 photo_capabilities->torch = false; | 617 photo_capabilities->torch = false; |
| 619 | 618 |
| 620 callback.Run(std::move(photo_capabilities)); | 619 callback.Run(std::move(photo_capabilities)); |
| 621 } | 620 } |
| 622 | 621 |
| 622 void VideoCaptureDeviceWin::SetPhotoOptions( | |
| 623 mojom::PhotoSettingsPtr settings, | |
| 624 VideoCaptureDevice::SetPhotoOptionsCallback callback) { | |
| 625 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 626 | |
| 627 if (!camera_control_ || !video_control_) | |
| 628 return; | |
| 629 | |
| 630 if (settings->has_zoom) { | |
| 631 HRESULT hr = | |
| 632 camera_control_->put_Zoom(settings->zoom, CameraControl_Flags_Manual); | |
| 633 DLOG_IF_FAILED_WITH_HRESULT("Zoom config failed", hr); | |
| 634 } | |
| 635 | |
| 636 if (settings->has_white_balance_mode) { | |
| 637 if (settings->white_balance_mode == mojom::MeteringMode::CONTINUOUS) { | |
| 638 HRESULT hr = | |
| 639 video_control_->put_WhiteBalance(0L, VideoProcAmp_Flags_Auto); | |
| 640 DLOG_IF_FAILED_WITH_HRESULT("Auto white balance config failed", hr); | |
| 641 | |
| 642 white_balance_mode_manual_ = false; | |
| 643 } else { | |
| 644 white_balance_mode_manual_ = true; | |
| 645 } | |
| 646 } | |
| 647 if (white_balance_mode_manual_ && settings->has_color_temperature) { | |
| 648 HRESULT hr = video_control_->put_WhiteBalance(settings->color_temperature, | |
| 649 CameraControl_Flags_Manual); | |
| 650 DLOG_IF_FAILED_WITH_HRESULT("Color temperature config failed", hr); | |
| 651 } | |
| 652 | |
| 653 if (settings->has_exposure_mode) { | |
| 654 if (settings->exposure_mode == mojom::MeteringMode::CONTINUOUS) { | |
| 655 HRESULT hr = camera_control_->put_Exposure(0L, VideoProcAmp_Flags_Auto); | |
| 656 DLOG_IF_FAILED_WITH_HRESULT("Auto exposure config failed", hr); | |
| 657 | |
| 658 exposure_mode_manual_ = false; | |
| 659 } else { | |
| 660 exposure_mode_manual_ = true; | |
| 661 } | |
| 662 } | |
| 663 if (exposure_mode_manual_ && settings->has_exposure_compensation) { | |
| 664 HRESULT hr = camera_control_->put_Exposure(settings->exposure_compensation, | |
| 665 CameraControl_Flags_Manual); | |
| 666 DLOG_IF_FAILED_WITH_HRESULT("Exposure Compensation config failed", hr); | |
| 667 } | |
| 668 | |
| 669 if (settings->has_brightness) { | |
| 670 HRESULT hr = video_control_->put_Brightness(settings->brightness, | |
| 671 CameraControl_Flags_Manual); | |
| 672 DLOG_IF_FAILED_WITH_HRESULT("Brightness config failed", hr); | |
| 673 } | |
| 674 if (settings->has_contrast) { | |
| 675 HRESULT hr = video_control_->put_Contrast(settings->contrast, | |
| 676 CameraControl_Flags_Manual); | |
| 677 DLOG_IF_FAILED_WITH_HRESULT("Contrast config failed", hr); | |
| 678 } | |
| 679 if (settings->has_saturation) { | |
| 680 HRESULT hr = video_control_->put_Saturation(settings->saturation, | |
| 681 CameraControl_Flags_Manual); | |
| 682 DLOG_IF_FAILED_WITH_HRESULT("Saturation config failed", hr); | |
| 683 } | |
| 684 if (settings->has_sharpness) { | |
| 685 HRESULT hr = video_control_->put_Sharpness(settings->sharpness, | |
| 686 CameraControl_Flags_Manual); | |
| 687 DLOG_IF_FAILED_WITH_HRESULT("Sharpness config failed", hr); | |
| 688 } | |
| 689 | |
| 690 callback.Run(true); | |
| 691 } | |
| 623 // Implements SinkFilterObserver::SinkFilterObserver. | 692 // Implements SinkFilterObserver::SinkFilterObserver. |
| 624 void VideoCaptureDeviceWin::FrameReceived(const uint8_t* buffer, | 693 void VideoCaptureDeviceWin::FrameReceived(const uint8_t* buffer, |
| 625 int length, | 694 int length, |
| 626 const VideoCaptureFormat& format, | 695 const VideoCaptureFormat& format, |
| 627 base::TimeDelta timestamp) { | 696 base::TimeDelta timestamp) { |
| 628 if (first_ref_time_.is_null()) | 697 if (first_ref_time_.is_null()) |
| 629 first_ref_time_ = base::TimeTicks::Now(); | 698 first_ref_time_ = base::TimeTicks::Now(); |
| 630 | 699 |
| 631 // There is a chance that the platform does not provide us with the timestamp, | 700 // There is a chance that the platform does not provide us with the timestamp, |
| 632 // in which case, we use reference time to calculate a timestamp. | 701 // in which case, we use reference time to calculate a timestamp. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 649 bool VideoCaptureDeviceWin::CreateCapabilityMap() { | 718 bool VideoCaptureDeviceWin::CreateCapabilityMap() { |
| 650 DCHECK(thread_checker_.CalledOnValidThread()); | 719 DCHECK(thread_checker_.CalledOnValidThread()); |
| 651 ScopedComPtr<IAMStreamConfig> stream_config; | 720 ScopedComPtr<IAMStreamConfig> stream_config; |
| 652 HRESULT hr = output_capture_pin_.CopyTo(stream_config.Receive()); | 721 HRESULT hr = output_capture_pin_.CopyTo(stream_config.Receive()); |
| 653 DLOG_IF_FAILED_WITH_HRESULT( | 722 DLOG_IF_FAILED_WITH_HRESULT( |
| 654 "Failed to get IAMStreamConfig from capture device", hr); | 723 "Failed to get IAMStreamConfig from capture device", hr); |
| 655 if (FAILED(hr)) | 724 if (FAILED(hr)) |
| 656 return false; | 725 return false; |
| 657 | 726 |
| 658 // Get interface used for getting the frame rate. | 727 // Get interface used for getting the frame rate. |
| 659 ScopedComPtr<IAMVideoControl> video_control; | 728 ScopedComPtr<IAMVideoControl> video_control_; |
|
robliao
2017/05/11 05:14:07
This declaration shadows the instance variable vid
mcasas
2017/05/12 18:52:49
Oops, unintended change.
| |
| 660 hr = capture_filter_.CopyTo(video_control.Receive()); | 729 hr = capture_filter_.CopyTo(video_control_.Receive()); |
| 661 | 730 |
| 662 int count = 0, size = 0; | 731 int count = 0, size = 0; |
| 663 hr = stream_config->GetNumberOfCapabilities(&count, &size); | 732 hr = stream_config->GetNumberOfCapabilities(&count, &size); |
| 664 DLOG_IF_FAILED_WITH_HRESULT("Failed to GetNumberOfCapabilities", hr); | 733 DLOG_IF_FAILED_WITH_HRESULT("Failed to GetNumberOfCapabilities", hr); |
| 665 if (FAILED(hr)) | 734 if (FAILED(hr)) |
| 666 return false; | 735 return false; |
| 667 | 736 |
| 668 std::unique_ptr<BYTE[]> caps(new BYTE[size]); | 737 std::unique_ptr<BYTE[]> caps(new BYTE[size]); |
| 669 for (int stream_index = 0; stream_index < count; ++stream_index) { | 738 for (int stream_index = 0; stream_index < count; ++stream_index) { |
| 670 ScopedMediaType media_type; | 739 ScopedMediaType media_type; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 685 if (format.pixel_format == PIXEL_FORMAT_UNKNOWN) | 754 if (format.pixel_format == PIXEL_FORMAT_UNKNOWN) |
| 686 continue; | 755 continue; |
| 687 | 756 |
| 688 VIDEOINFOHEADER* h = | 757 VIDEOINFOHEADER* h = |
| 689 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); | 758 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); |
| 690 format.frame_size.SetSize(h->bmiHeader.biWidth, h->bmiHeader.biHeight); | 759 format.frame_size.SetSize(h->bmiHeader.biWidth, h->bmiHeader.biHeight); |
| 691 | 760 |
| 692 // Try to get a better |time_per_frame| from IAMVideoControl. If not, use | 761 // Try to get a better |time_per_frame| from IAMVideoControl. If not, use |
| 693 // the value from VIDEOINFOHEADER. | 762 // the value from VIDEOINFOHEADER. |
| 694 REFERENCE_TIME time_per_frame = h->AvgTimePerFrame; | 763 REFERENCE_TIME time_per_frame = h->AvgTimePerFrame; |
| 695 if (video_control.Get()) { | 764 if (video_control_.Get()) { |
| 696 ScopedCoMem<LONGLONG> max_fps; | 765 ScopedCoMem<LONGLONG> max_fps; |
| 697 LONG list_size = 0; | 766 LONG list_size = 0; |
| 698 const SIZE size = {format.frame_size.width(), | 767 const SIZE size = {format.frame_size.width(), |
| 699 format.frame_size.height()}; | 768 format.frame_size.height()}; |
| 700 hr = video_control->GetFrameRateList(output_capture_pin_.Get(), | 769 hr = video_control_->GetFrameRateList(output_capture_pin_.Get(), |
| 701 stream_index, size, &list_size, | 770 stream_index, size, &list_size, |
| 702 &max_fps); | 771 &max_fps); |
| 703 // Can't assume the first value will return the max fps. | 772 // Can't assume the first value will return the max fps. |
| 704 // Sometimes |list_size| will be > 0, but max_fps will be NULL. Some | 773 // Sometimes |list_size| will be > 0, but max_fps will be NULL. Some |
| 705 // drivers may return an HRESULT of S_FALSE which SUCCEEDED() translates | 774 // drivers may return an HRESULT of S_FALSE which SUCCEEDED() translates |
| 706 // into success, so explicitly check S_OK. See http://crbug.com/306237. | 775 // into success, so explicitly check S_OK. See http://crbug.com/306237. |
| 707 if (hr == S_OK && list_size > 0 && max_fps) { | 776 if (hr == S_OK && list_size > 0 && max_fps) { |
| 708 time_per_frame = | 777 time_per_frame = |
| 709 *std::min_element(max_fps.get(), max_fps.get() + list_size); | 778 *std::min_element(max_fps.get(), max_fps.get() + list_size); |
| 710 } | 779 } |
| 711 } | 780 } |
| 712 | 781 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 757 void VideoCaptureDeviceWin::SetErrorState( | 826 void VideoCaptureDeviceWin::SetErrorState( |
| 758 const tracked_objects::Location& from_here, | 827 const tracked_objects::Location& from_here, |
| 759 const std::string& reason, | 828 const std::string& reason, |
| 760 HRESULT hr) { | 829 HRESULT hr) { |
| 761 DCHECK(thread_checker_.CalledOnValidThread()); | 830 DCHECK(thread_checker_.CalledOnValidThread()); |
| 762 DLOG_IF_FAILED_WITH_HRESULT(reason, hr); | 831 DLOG_IF_FAILED_WITH_HRESULT(reason, hr); |
| 763 state_ = kError; | 832 state_ = kError; |
| 764 client_->OnError(from_here, reason); | 833 client_->OnError(from_here, reason); |
| 765 } | 834 } |
| 766 } // namespace media | 835 } // namespace media |
| OLD | NEW |